]> git.lizzy.rs Git - rust.git/commitdiff
make bounds on higher-kinded lifetimes a hard error in ast_validation
authorRalf Jung <post@ralfj.de>
Tue, 6 Mar 2018 10:22:24 +0000 (11:22 +0100)
committerRalf Jung <post@ralfj.de>
Tue, 6 Mar 2018 10:29:48 +0000 (11:29 +0100)
Also move the check for not having type parameters into ast_validation.

I was not sure what to do with compile-fail/issue-23046.rs: The issue looks like
maybe the bounds actually played a role in triggering the ICE, but that seems
unlikely given that the compiler seems to entirely ignore them.  However, I
couldn't find a testcase without the bounds, so I figured the best I could do is
to just remove the bounds and make sure at least that keeps working.

src/librustc_lint/builtin.rs
src/librustc_passes/ast_validation.rs
src/libsyntax/parse/parser.rs
src/test/compile-fail/bounds-lifetime.rs [new file with mode: 0644]
src/test/compile-fail/issue-23046.rs
src/test/compile-fail/private-in-public-warn.rs
src/test/parse-fail/bounds-lifetime.rs
src/test/parse-fail/bounds-type.rs
src/test/run-pass/impl-trait/lifetimes.rs
src/test/ui/param-bounds-ignored.rs
src/test/ui/param-bounds-ignored.stderr

index 2452bda8d43723dc62508221445b7c0fd0d09dc0..b653cfecf949686ee753b4c7308f259773730a62 100644 (file)
@@ -1404,79 +1404,32 @@ fn get_lints(&self) -> LintArray {
     }
 }
 
-impl IgnoredGenericBounds {
-    fn ensure_no_param_bounds(
-        cx: &EarlyContext,
-        generics: &Vec<ast::GenericParam>,
-        thing: &'static str,
-    ) {
-        for param in generics.iter() {
-            match param {
-                &ast::GenericParam::Lifetime(ref lifetime) => {
-                    if !lifetime.bounds.is_empty() {
-                        let spans : Vec<_> = lifetime.bounds.iter().map(|b| b.span).collect();
-                        cx.span_lint(
-                            IGNORED_GENERIC_BOUNDS,
-                            spans,
-                            format!("bounds on generic lifetime parameters are ignored in {}",
-                                thing).as_ref()
-                        );
-                    }
-                }
-                &ast::GenericParam::Type(ref ty) => {
-                    if !ty.bounds.is_empty() {
-                        let spans : Vec<_> = ty.bounds.iter().map(|b| b.span()).collect();
-                        cx.span_lint(
-                            IGNORED_GENERIC_BOUNDS,
-                            spans,
-                            format!("bounds on generic type parameters are ignored in {}", thing)
-                                .as_ref()
-                        );
-                    }
-                }
-            }
-        }
-    }
-}
-
 impl EarlyLintPass for IgnoredGenericBounds {
     fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
-        match item.node {
-            ast::ItemKind::Ty(_, ref generics) => {
-                if !generics.where_clause.predicates.is_empty() {
-                    let spans : Vec<_> = generics.where_clause.predicates.iter()
-                        .map(|pred| pred.span()).collect();
-                    cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
-                        "where clauses are ignored in type aliases");
-                }
-                IgnoredGenericBounds::ensure_no_param_bounds(cx, &generics.params,
-                    "type aliases");
-            }
-            _ => {}
-        }
-    }
-
-    fn check_where_predicate(&mut self, cx: &EarlyContext, p: &ast::WherePredicate) {
-        if let &ast::WherePredicate::BoundPredicate(ref bound_predicate) = p {
-            // A type binding, eg `for<'c> Foo: Send+Clone+'c`
-            IgnoredGenericBounds::ensure_no_param_bounds(cx,
-                &bound_predicate.bound_generic_params, "higher-ranked trait bounds (i.e., `for`)");
+        let type_alias_generics = match item.node {
+            ast::ItemKind::Ty(_, ref generics) => generics,
+            _ => return,
+        };
+        // There must not be a where clause
+        if !type_alias_generics.where_clause.predicates.is_empty() {
+            let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter()
+                .map(|pred| pred.span()).collect();
+            cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
+                "where clauses are ignored in type aliases");
         }
-    }
-
-    fn check_poly_trait_ref(&mut self, cx: &EarlyContext, t: &ast::PolyTraitRef,
-                            _: &ast::TraitBoundModifier) {
-        IgnoredGenericBounds::ensure_no_param_bounds(cx, &t.bound_generic_params,
-            "higher-ranked trait bounds (i.e., `for`)");
-    }
-
-    fn check_ty(&mut self, cx: &EarlyContext, ty: &ast::Ty) {
-        match ty.node {
-            ast::TyKind::BareFn(ref fn_ty) => {
-                IgnoredGenericBounds::ensure_no_param_bounds(cx, &fn_ty.generic_params,
-                    "higher-ranked function types (i.e., `for`)");
+        // The parameters must not have bounds
+        for param in type_alias_generics.params.iter() {
+            let spans : Vec<_> = match param {
+                &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
+                &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
+            };
+            if !spans.is_empty() {
+                cx.span_lint(
+                    IGNORED_GENERIC_BOUNDS,
+                    spans,
+                    "bounds on generic parameters are ignored in type aliases",
+                );
             }
-            _ => {}
         }
     }
 }
index a5dd8f1558e4392b8e59c5d9a045bbc44803fe79..55d00f92e4dac0b1d235fa3bb9f72b6996e5a927 100644 (file)
@@ -136,6 +136,33 @@ fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) {
                                                          in patterns")
         }
     }
+
+    fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParam>) {
+        // Check: Only lifetime parameters
+        let non_lifetime_param_spans : Vec<_> = params.iter()
+            .filter_map(|param| match *param {
+                GenericParam::Lifetime(_) => None,
+                GenericParam::Type(ref t) => Some(t.span),
+            }).collect();
+        if !non_lifetime_param_spans.is_empty() {
+            self.err_handler().span_err(non_lifetime_param_spans,
+                "only lifetime parameters can be used in this context");
+        }
+
+        // Check: No bounds on lifetime parameters
+        for param in params.iter() {
+            match *param {
+                GenericParam::Lifetime(ref l) => {
+                    if !l.bounds.is_empty() {
+                        let spans : Vec<_> = l.bounds.iter().map(|b| b.span).collect();
+                        self.err_handler().span_err(spans,
+                            "lifetime bounds cannot be used in this context");
+                    }
+                }
+                GenericParam::Type(_) => {}
+            }
+        }
+    }
 }
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
@@ -157,6 +184,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
                     struct_span_err!(self.session, span, E0561,
                                      "patterns aren't allowed in function pointer types").emit();
                 });
+                self.check_late_bound_lifetime_defs(&bfty.generic_params);
             }
             TyKind::TraitObject(ref bounds, ..) => {
                 let mut any_lifetime_bounds = false;
@@ -417,6 +445,19 @@ fn visit_pat(&mut self, pat: &'a Pat) {
 
         visit::walk_pat(self, pat)
     }
+
+    fn visit_where_predicate(&mut self, p: &'a WherePredicate) {
+        if let &WherePredicate::BoundPredicate(ref bound_predicate) = p {
+            // A type binding, eg `for<'c> Foo: Send+Clone+'c`
+            self.check_late_bound_lifetime_defs(&bound_predicate.bound_generic_params);
+        }
+        visit::walk_where_predicate(self, p);
+    }
+
+    fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
+        self.check_late_bound_lifetime_defs(&t.bound_generic_params);
+        visit::walk_poly_trait_ref(self, t, m);
+    }
 }
 
 // Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.
index 09dd00fa5fa3a2953b54bd8a7af1994e3579439b..ba8ccc2256f20038c9fd00f5ee8708d61dbae7fc 100644 (file)
@@ -5484,18 +5484,8 @@ fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
             self.expect_lt()?;
             let params = self.parse_generic_params()?;
             self.expect_gt()?;
-
-            let first_non_lifetime_param_span = params.iter()
-                .filter_map(|param| match *param {
-                    ast::GenericParam::Lifetime(_) => None,
-                    ast::GenericParam::Type(ref t) => Some(t.span),
-                })
-                .next();
-
-            if let Some(span) = first_non_lifetime_param_span {
-                self.span_err(span, "only lifetime parameters can be used in this context");
-            }
-
+            // We rely on AST validation to rule out invalid cases: There must not be type
+            // parameters, and the lifetime parameters must not have bounds.
             Ok(params)
         } else {
             Ok(Vec::new())
diff --git a/src/test/compile-fail/bounds-lifetime.rs b/src/test/compile-fail/bounds-lifetime.rs
new file mode 100644 (file)
index 0000000..5bfaa6c
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2017 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.
+
+type A = for<'b, 'a: 'b> fn(); //~ ERROR lifetime bounds cannot be used in this context
+type B = for<'b, 'a: 'b,> fn(); //~ ERROR lifetime bounds cannot be used in this context
+type C = for<'b, 'a: 'b +> fn(); //~ ERROR lifetime bounds cannot be used in this context
+type D = for<'a, T> fn(); //~ ERROR only lifetime parameters can be used in this context
+type E = for<T> Fn(); //~ ERROR only lifetime parameters can be used in this context
+
+fn main() {}
index 6ce088786933560367edfa8301888a96dd1fa98b..670706b7a9adf8af4ec82139d1a24a31a899e450 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(ignored_generic_bounds)]
-
 pub enum Expr<'var, VAR> {
     Let(Box<Expr<'var, VAR>>,
-        Box<for<'v: 'var> Fn(Expr<'v, VAR>) -> Expr<'v, VAR> + 'var>)
+        Box<for<'v> Fn(Expr<'v, VAR>) -> Expr<'v, VAR> + 'var>)
 }
 
 pub fn add<'var, VAR>
@@ -20,7 +18,7 @@ pub fn add<'var, VAR>
     loop {}
 }
 
-pub fn let_<'var, VAR, F: for<'v: 'var> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>>
+pub fn let_<'var, VAR, F: for<'v> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>>
                        (a: Expr<'var, VAR>, b: F) -> Expr<'var, VAR> {
     loop {}
 }
index 4be01dbd677f0b905761c5aa2c837db962785d7d..cc9eed7e65426238667185a8a693556d2183b4e4 100644 (file)
@@ -58,7 +58,7 @@ trait PrivTr {}
     pub trait PubTr {}
 
     pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
-    //~^ WARNING bounds on generic type parameters are ignored
+    //~^ WARNING bounds on generic parameters are ignored
     //~| WARNING hard error
     pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
     //~^ WARNING hard error
index 5113a6b4803fc058bd492dde93594b74146fe926..88db205310ce156027f2f7de63456197f14450d2 100644 (file)
@@ -8,17 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z parse-only -Z continue-parse-after-error
+// compile-flags: -Z parse-only
 
-type A = for<'a: 'b + 'c> fn(); // OK
-type A = for<'a: 'b,> fn(); // OK
 type A = for<'a:> fn(); // OK
 type A = for<'a:,> fn(); // OK
 type A = for<'a> fn(); // OK
 type A = for<> fn(); // OK
-type A = for<'a: 'b +> fn(); // OK
-
-type A = for<'a, T> fn(); //~ ERROR only lifetime parameters can be used in this context
+type A = for<'a: 'b + 'c> fn(); // OK (rejected later by ast_validation)
+type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation)
+type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation)
+type A = for<'a, T> fn(); // OK (rejected later by ast_validation)
 type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,`
 
 fn main() {}
index c224b44a14bf1fb7a94812a048fd08cff6dd660a..0ebe7fde0a63f36f16e730ec2228e01941dc02b2 100644 (file)
@@ -15,7 +15,7 @@ struct S<
     T: Tr + 'a, // OK
     T: 'a, // OK
     T:, // OK
-    T: ?for<'a: 'b + 'c> Trait, // OK
+    T: ?for<'a> Trait, // OK
     T: Tr +, // OK
     T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
 >;
index 2d5dfb045dbac32ca8e2dec32432135b514dc5c9..fcad23926fc0caf45b2a085f3e3194ac2129badf 100644 (file)
@@ -69,8 +69,8 @@ fn foo(x: &impl Debug) -> &impl Debug { x }
 fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x }
 fn foo_explicit_arg<T: Debug>(x: &T) -> &impl Debug { x }
 
-fn mixed_lifetimes<'a>() -> impl for<'b: 'a> Fn(&'b u32) { |_| () }
-fn mixed_as_static() -> impl Fn(&'static u32) { mixed_lifetimes() }
+fn mixed_lifetimes<'a>() -> impl for<'b> Fn(&'b &'a u32) { |_| () }
+fn mixed_as_static() -> impl Fn(&'static &'static u32) { mixed_lifetimes() }
 
 trait MultiRegionTrait<'a, 'b>: Debug {}
 
index a136ec60252b4a6860c184e05b2cabe5de6dc6dc..94bcdec945035033d8ca36a9ca977bc02c504b95 100644 (file)
@@ -8,17 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// must-compile-successfully
 #![allow(dead_code, non_camel_case_types)]
 
 use std::rc::Rc;
 
 type SVec<T: Send+Send> = Vec<T>;
-//~^ WARN bounds on generic type parameters are ignored in type aliases
+//~^ WARN bounds on generic parameters are ignored in type aliases
 type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
-//~^ WARN bounds on generic lifetime parameters are ignored in type aliases
+//~^ WARN bounds on generic parameters are ignored in type aliases
 type WVec<'b, T: 'b+'b> = Vec<T>;
-//~^ WARN bounds on generic type parameters are ignored in type aliases
+//~^ WARN bounds on generic parameters are ignored in type aliases
 type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
 //~^ WARN where clauses are ignored in type aliases
 
@@ -40,8 +39,8 @@ fn foo<'a>(y: &'a i32) {
 fn bar1<'a, 'b>(
     x: &'a i32,
     y: &'b i32,
-    f: for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked function types
+    f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
+    //~^ ERROR lifetime bounds cannot be used in this context
 {
     // If the bound in f's type would matter, the call below would (have to)
     // be rejected.
@@ -49,7 +48,7 @@ fn bar1<'a, 'b>(
 }
 
 fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+    //~^ ERROR lifetime bounds cannot be used in this context
     x: &'a i32,
     y: &'b i32,
     f: F)
@@ -64,7 +63,7 @@ fn bar3<'a, 'b, F>(
     y: &'b i32,
     f: F)
     where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+    //~^ ERROR lifetime bounds cannot be used in this context
 {
     // If the bound in f's type would matter, the call below would (have to)
     // be rejected.
@@ -76,7 +75,7 @@ fn bar4<'a, 'b, F>(
     y: &'b i32,
     f: F)
     where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+    //~^ ERROR lifetime bounds cannot be used in this context
 {
     // If the bound in f's type would matter, the call below would (have to)
     // be rejected.
@@ -84,21 +83,21 @@ fn bar4<'a, 'b, F>(
 }
 
 struct S1<F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(F);
-//~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+//~^ ERROR lifetime bounds cannot be used in this context
 struct S2<F>(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32;
-//~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+//~^ ERROR lifetime bounds cannot be used in this context
 struct S3<F>(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32;
-//~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+//~^ ERROR lifetime bounds cannot be used in this context
 
 struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32);
-//~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked function types
+//~^ ERROR lifetime bounds cannot be used in this context
 
 type T1 = Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>;
-//~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+//~^ ERROR lifetime bounds cannot be used in this context
 
 fn main() {
     let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None;
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked function types
+    //~^ ERROR lifetime bounds cannot be used in this context
     let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
-    //~^ WARN bounds on generic lifetime parameters are ignored in higher-ranked trait bounds
+    //~^ ERROR lifetime bounds cannot be used in this context
 }
index 55df5d1c939410e1b6eee8dd510f3f9064c99567..657fec54f9608ac415c0ccf8bbf58eac196d5eae 100644 (file)
@@ -1,92 +1,94 @@
-warning: bounds on generic type parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:16:14
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:42:22
    |
-LL | type SVec<T: Send+Send> = Vec<T>;
-   |              ^^^^ ^^^^
-   |
-   = note: #[warn(ignored_generic_bounds)] on by default
-
-warning: bounds on generic lifetime parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:18:19
-   |
-LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
-   |                   ^^ ^^
-
-warning: bounds on generic type parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:20:18
-   |
-LL | type WVec<'b, T: 'b+'b> = Vec<T>;
-   |                  ^^ ^^
-
-warning: where clauses are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:22:25
-   |
-LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
-   |                         ^^^^^  ^^^^^
+LL |     f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
+   |                      ^^^ ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked function types (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:43:22
-   |
-LL |     f: for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
-   |                      ^^^
-
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:51:34
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:50:34
    |
 LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(
    |                                  ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:66:28
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:65:28
    |
 LL |     where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32
    |                            ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:78:25
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:77:25
    |
 LL |     where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32
    |                         ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:86:28
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:85:28
    |
 LL | struct S1<F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(F);
    |                            ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:88:40
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:87:40
    |
 LL | struct S2<F>(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32;
    |                                        ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:90:37
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:89:37
    |
 LL | struct S3<F>(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32;
    |                                     ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked function types (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:93:29
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:92:29
    |
 LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32);
    |                             ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:96:29
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:95:29
    |
 LL | type T1 = Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>;
    |                             ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked function types (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:100:34
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:99:34
    |
 LL |     let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None;
    |                                  ^^^
 
-warning: bounds on generic lifetime parameters are ignored in higher-ranked trait bounds (i.e., `for`)
-  --> $DIR/param-bounds-ignored.rs:102:38
+error: lifetime bounds cannot be used in this context
+  --> $DIR/param-bounds-ignored.rs:101:38
    |
 LL |     let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
    |                                      ^^^
 
+warning: bounds on generic parameters are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:15:14
+   |
+LL | type SVec<T: Send+Send> = Vec<T>;
+   |              ^^^^ ^^^^
+   |
+   = note: #[warn(ignored_generic_bounds)] on by default
+
+warning: bounds on generic parameters are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:17:19
+   |
+LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
+   |                   ^^ ^^
+
+warning: bounds on generic parameters are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:19:18
+   |
+LL | type WVec<'b, T: 'b+'b> = Vec<T>;
+   |                  ^^ ^^
+
+warning: where clauses are ignored in type aliases
+  --> $DIR/param-bounds-ignored.rs:21:25
+   |
+LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
+   |                         ^^^^^  ^^^^^
+
+error: aborting due to 11 previous errors
+