about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-08-19 14:39:00 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-08-21 19:33:29 -0700
commit24a213726940836e5d57b51fdc0dcd4b1bffeba9 (patch)
treedd11173c4f65baf935014fe80c0780ce6498a276
parentb43596b43ed7084aff5954e5c4bdd0b2d52665e4 (diff)
downloadrust-24a213726940836e5d57b51fdc0dcd4b1bffeba9.tar.gz
rust-24a213726940836e5d57b51fdc0dcd4b1bffeba9.zip
librustc: Consider where clauses when traversing free regions in
signatures.

Closes #16549.
Closes #16564.
-rw-r--r--src/librustc/middle/resolve_lifetime.rs13
-rw-r--r--src/test/run-pass/where-clauses-lifetimes.rs15
-rw-r--r--src/test/run-pass/where-clauses-unboxed-closures.rs26
3 files changed, 51 insertions, 3 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 5001e7a88bd..abb67a6503e 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -206,7 +206,8 @@ impl<'a> LifetimeContext<'a> {
 
         self.check_lifetime_names(&generics.lifetimes);
 
-        let referenced_idents = free_lifetimes(&generics.ty_params);
+        let referenced_idents = free_lifetimes(&generics.ty_params,
+                                               &generics.where_clause);
         debug!("pushing fn scope id={} due to fn item/method\
                referenced_idents={:?}",
                n,
@@ -403,7 +404,8 @@ fn search_lifetimes(lifetimes: &Vec<ast::LifetimeDef>,
 ///////////////////////////////////////////////////////////////////////////
 
 pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::LifetimeDef> {
-    let referenced_idents = free_lifetimes(&generics.ty_params);
+    let referenced_idents = free_lifetimes(&generics.ty_params,
+                                           &generics.where_clause);
     if referenced_idents.is_empty() {
         return Vec::new();
     }
@@ -414,7 +416,9 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
         .collect()
 }
 
-pub fn free_lifetimes(ty_params: &OwnedSlice<ast::TyParam>) -> Vec<ast::Name> {
+pub fn free_lifetimes(ty_params: &OwnedSlice<ast::TyParam>,
+                      where_clause: &ast::WhereClause)
+                      -> Vec<ast::Name> {
     /*!
      * Gathers up and returns the names of any lifetimes that appear
      * free in `ty_params`. Of course, right now, all lifetimes appear
@@ -426,6 +430,9 @@ pub fn free_lifetimes(ty_params: &OwnedSlice<ast::TyParam>) -> Vec<ast::Name> {
     for ty_param in ty_params.iter() {
         visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds, ());
     }
+    for predicate in where_clause.predicates.iter() {
+        visit::walk_ty_param_bounds(&mut collector, &predicate.bounds, ());
+    }
     return collector.names;
 
     struct FreeLifetimeCollector {
diff --git a/src/test/run-pass/where-clauses-lifetimes.rs b/src/test/run-pass/where-clauses-lifetimes.rs
new file mode 100644
index 00000000000..4adaf7a11e3
--- /dev/null
+++ b/src/test/run-pass/where-clauses-lifetimes.rs
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<'a, I>(mut it: I) where I: Iterator<&'a int> {}
+
+fn main() {
+    foo([1i, 2].iter());
+}
diff --git a/src/test/run-pass/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses-unboxed-closures.rs
new file mode 100644
index 00000000000..ae005b4ae53
--- /dev/null
+++ b/src/test/run-pass/where-clauses-unboxed-closures.rs
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+
+struct Bencher;
+
+// ICE
+fn warm_up<'a, F>(f: F) where F: |&: &'a mut Bencher| {
+}
+
+fn main() {
+    // ICE trigger
+    warm_up(|&: b: &mut Bencher| () );
+
+    // OK
+    warm_up(|&: b| () );
+}
+