make bounds on higher-kinded lifetimes a hard error in ast_validation

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.
This commit is contained in:
Ralf Jung 2018-03-06 11:22:24 +01:00
parent 30b5be0e95
commit 49abd87483
11 changed files with 182 additions and 183 deletions

View File

@ -1404,79 +1404,32 @@ impl LintPass for IgnoredGenericBounds {
} }
} }
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 { impl EarlyLintPass for IgnoredGenericBounds {
fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
match item.node { let type_alias_generics = match item.node {
ast::ItemKind::Ty(_, ref generics) => { ast::ItemKind::Ty(_, ref generics) => generics,
if !generics.where_clause.predicates.is_empty() { _ => return,
let spans : Vec<_> = generics.where_clause.predicates.iter() };
.map(|pred| pred.span()).collect(); // There must not be a where clause
cx.span_lint(IGNORED_GENERIC_BOUNDS, spans, if !type_alias_generics.where_clause.predicates.is_empty() {
"where clauses are ignored in type aliases"); let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter()
} .map(|pred| pred.span()).collect();
IgnoredGenericBounds::ensure_no_param_bounds(cx, &generics.params, cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
"type aliases"); "where clauses are ignored in type aliases");
}
_ => {}
} }
} // The parameters must not have bounds
for param in type_alias_generics.params.iter() {
fn check_where_predicate(&mut self, cx: &EarlyContext, p: &ast::WherePredicate) { let spans : Vec<_> = match param {
if let &ast::WherePredicate::BoundPredicate(ref bound_predicate) = p { &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
// A type binding, eg `for<'c> Foo: Send+Clone+'c` &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
IgnoredGenericBounds::ensure_no_param_bounds(cx, };
&bound_predicate.bound_generic_params, "higher-ranked trait bounds (i.e., `for`)"); if !spans.is_empty() {
} cx.span_lint(
} IGNORED_GENERIC_BOUNDS,
spans,
fn check_poly_trait_ref(&mut self, cx: &EarlyContext, t: &ast::PolyTraitRef, "bounds on generic parameters are ignored in type aliases",
_: &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`)");
} }
_ => {}
} }
} }
} }

View File

@ -136,6 +136,33 @@ impl<'a> AstValidator<'a> {
in patterns") 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> { impl<'a> Visitor<'a> for AstValidator<'a> {
@ -157,6 +184,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
struct_span_err!(self.session, span, E0561, struct_span_err!(self.session, span, E0561,
"patterns aren't allowed in function pointer types").emit(); "patterns aren't allowed in function pointer types").emit();
}); });
self.check_late_bound_lifetime_defs(&bfty.generic_params);
} }
TyKind::TraitObject(ref bounds, ..) => { TyKind::TraitObject(ref bounds, ..) => {
let mut any_lifetime_bounds = false; let mut any_lifetime_bounds = false;
@ -417,6 +445,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
visit::walk_pat(self, 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>`. // Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.

View File

@ -5484,18 +5484,8 @@ impl<'a> Parser<'a> {
self.expect_lt()?; self.expect_lt()?;
let params = self.parse_generic_params()?; let params = self.parse_generic_params()?;
self.expect_gt()?; self.expect_gt()?;
// We rely on AST validation to rule out invalid cases: There must not be type
let first_non_lifetime_param_span = params.iter() // parameters, and the lifetime parameters must not have bounds.
.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");
}
Ok(params) Ok(params)
} else { } else {
Ok(Vec::new()) Ok(Vec::new())

View File

@ -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() {}

View File

@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(ignored_generic_bounds)]
pub enum Expr<'var, VAR> { pub enum Expr<'var, VAR> {
Let(Box<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> pub fn add<'var, VAR>
@ -20,7 +18,7 @@ pub fn add<'var, VAR>
loop {} 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> { (a: Expr<'var, VAR>, b: F) -> Expr<'var, VAR> {
loop {} loop {}
} }

View File

@ -58,7 +58,7 @@ mod traits {
pub trait PubTr {} pub trait PubTr {}
pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface 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 //~| WARNING hard error
pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
//~^ WARNING hard error //~^ WARNING hard error

View File

@ -8,17 +8,16 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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<'a:,> fn(); // OK
type A = for<'a> fn(); // OK type A = for<'a> fn(); // OK
type A = for<> fn(); // OK type A = for<> fn(); // OK
type A = for<'a: 'b +> fn(); // OK 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, T> fn(); //~ ERROR only lifetime parameters can be used in this context 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 `,` type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,`
fn main() {} fn main() {}

View File

@ -15,7 +15,7 @@ struct S<
T: Tr + 'a, // OK T: Tr + 'a, // OK
T: 'a, // OK T: 'a, // OK
T:, // OK T:, // OK
T: ?for<'a: 'b + 'c> Trait, // OK T: ?for<'a> Trait, // OK
T: Tr +, // OK T: Tr +, // OK
T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
>; >;

View 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_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x }
fn foo_explicit_arg<T: Debug>(x: &T) -> &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_lifetimes<'a>() -> impl for<'b> Fn(&'b &'a u32) { |_| () }
fn mixed_as_static() -> impl Fn(&'static u32) { mixed_lifetimes() } fn mixed_as_static() -> impl Fn(&'static &'static u32) { mixed_lifetimes() }
trait MultiRegionTrait<'a, 'b>: Debug {} trait MultiRegionTrait<'a, 'b>: Debug {}

View File

@ -8,17 +8,16 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// must-compile-successfully
#![allow(dead_code, non_camel_case_types)] #![allow(dead_code, non_camel_case_types)]
use std::rc::Rc; use std::rc::Rc;
type SVec<T: Send+Send> = Vec<T>; 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>; 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>; 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>; type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
//~^ WARN where clauses are ignored in type aliases //~^ WARN where clauses are ignored in type aliases
@ -40,8 +39,8 @@ fn foo<'a>(y: &'a i32) {
fn bar1<'a, 'b>( fn bar1<'a, 'b>(
x: &'a i32, x: &'a i32,
y: &'b i32, y: &'b i32,
f: for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) f: for<'xa, 'xb: 'xa+'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
{ {
// If the bound in f's type would matter, the call below would (have to) // If the bound in f's type would matter, the call below would (have to)
// be rejected. // 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>( 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, x: &'a i32,
y: &'b i32, y: &'b i32,
f: F) f: F)
@ -64,7 +63,7 @@ fn bar3<'a, 'b, F>(
y: &'b i32, y: &'b i32,
f: F) f: F)
where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 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) // If the bound in f's type would matter, the call below would (have to)
// be rejected. // be rejected.
@ -76,7 +75,7 @@ fn bar4<'a, 'b, F>(
y: &'b i32, y: &'b i32,
f: F) f: F)
where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 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) // If the bound in f's type would matter, the call below would (have to)
// be rejected. // 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); 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; 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; 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); 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>; 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() { fn main() {
let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None; 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; 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
} }

View File

@ -1,92 +1,94 @@
warning: bounds on generic type parameters are ignored in type aliases error: lifetime bounds cannot be used in this context
--> $DIR/param-bounds-ignored.rs:16:14 --> $DIR/param-bounds-ignored.rs:42:22
|
LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
| ^^^ ^^^
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>(
| ^^^
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
| ^^^
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
| ^^^
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);
| ^^^
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;
| ^^^
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;
| ^^^
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);
| ^^^
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>;
| ^^^
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;
| ^^^
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>; LL | type SVec<T: Send+Send> = Vec<T>;
| ^^^^ ^^^^ | ^^^^ ^^^^
| |
= note: #[warn(ignored_generic_bounds)] on by default = note: #[warn(ignored_generic_bounds)] on by default
warning: bounds on generic lifetime parameters are ignored in type aliases warning: bounds on generic parameters are ignored in type aliases
--> $DIR/param-bounds-ignored.rs:18:19 --> $DIR/param-bounds-ignored.rs:17:19
| |
LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>; LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
| ^^ ^^ | ^^ ^^
warning: bounds on generic type parameters are ignored in type aliases warning: bounds on generic parameters are ignored in type aliases
--> $DIR/param-bounds-ignored.rs:20:18 --> $DIR/param-bounds-ignored.rs:19:18
| |
LL | type WVec<'b, T: 'b+'b> = Vec<T>; LL | type WVec<'b, T: 'b+'b> = Vec<T>;
| ^^ ^^ | ^^ ^^
warning: where clauses are ignored in type aliases warning: where clauses are ignored in type aliases
--> $DIR/param-bounds-ignored.rs:22:25 --> $DIR/param-bounds-ignored.rs:21:25
| |
LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>; LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
| ^^^^^ ^^^^^ | ^^^^^ ^^^^^
warning: bounds on generic lifetime parameters are ignored in higher-ranked function types (i.e., `for`) error: aborting due to 11 previous errors
--> $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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
LL | let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
| ^^^