From 86821f7fb6afbbfebd2d7b0a681d14c4cf6a578e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 18 Feb 2018 19:40:35 +0100 Subject: add lint to detect ignored generic bounds; this subsumes the previous 'generic bounds in type aliases are ignored' warning --- src/libsyntax/ast.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 6609b77b132..245025d3e4f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -294,6 +294,15 @@ pub enum TyParamBound { RegionTyParamBound(Lifetime) } +impl TyParamBound { + pub fn span(&self) -> Span { + match self { + &TraitTyParamBound(ref t, ..) => t.span, + &RegionTyParamBound(ref l) => l.span, + } + } +} + /// A modifier on a bound, currently this is only used for `?Sized`, where the /// modifier is `Maybe`. Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -404,6 +413,16 @@ pub enum WherePredicate { EqPredicate(WhereEqPredicate), } +impl WherePredicate { + pub fn span(&self) -> Span { + match self { + &WherePredicate::BoundPredicate(ref p) => p.span, + &WherePredicate::RegionPredicate(ref p) => p.span, + &WherePredicate::EqPredicate(ref p) => p.span, + } + } +} + /// A type bound. /// /// E.g. `for<'c> Foo: Send+Clone+'c` -- cgit 1.4.1-3-g733a5 From 49abd8748357012e5db10bf11077384f727e2177 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Mar 2018 11:22:24 +0100 Subject: 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. --- src/librustc_lint/builtin.rs | 91 +++++---------------- src/librustc_passes/ast_validation.rs | 41 ++++++++++ src/libsyntax/parse/parser.rs | 14 +--- src/test/compile-fail/bounds-lifetime.rs | 17 ++++ src/test/compile-fail/issue-23046.rs | 6 +- src/test/compile-fail/private-in-public-warn.rs | 2 +- src/test/parse-fail/bounds-lifetime.rs | 11 ++- src/test/parse-fail/bounds-type.rs | 2 +- src/test/run-pass/impl-trait/lifetimes.rs | 4 +- src/test/ui/param-bounds-ignored.rs | 31 ++++--- src/test/ui/param-bounds-ignored.stderr | 102 ++++++++++++------------ 11 files changed, 160 insertions(+), 161 deletions(-) create mode 100644 src/test/compile-fail/bounds-lifetime.rs (limited to 'src/libsyntax') diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2452bda8d43..b653cfecf94 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1404,79 +1404,32 @@ impl LintPass for IgnoredGenericBounds { } } -impl IgnoredGenericBounds { - fn ensure_no_param_bounds( - cx: &EarlyContext, - generics: &Vec, - 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", + ); } - _ => {} } } } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index a5dd8f1558e..55d00f92e4d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -136,6 +136,33 @@ impl<'a> AstValidator<'a> { in patterns") } } + + fn check_late_bound_lifetime_defs(&self, params: &Vec) { + // 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 @@ impl<'a> Visitor<'a> for AstValidator<'a> { 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 @@ impl<'a> Visitor<'a> for AstValidator<'a> { 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`. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 09dd00fa5fa..ba8ccc2256f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5484,18 +5484,8 @@ impl<'a> Parser<'a> { 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 index 00000000000..5bfaa6c54fa --- /dev/null +++ b/src/test/compile-fail/bounds-lifetime.rs @@ -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 or the MIT license +// , 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 Fn(); //~ ERROR only lifetime parameters can be used in this context + +fn main() {} diff --git a/src/test/compile-fail/issue-23046.rs b/src/test/compile-fail/issue-23046.rs index 6ce08878693..670706b7a9a 100644 --- a/src/test/compile-fail/issue-23046.rs +++ b/src/test/compile-fail/issue-23046.rs @@ -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>, - Box Fn(Expr<'v, VAR>) -> Expr<'v, VAR> + 'var>) + Box 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 {} } diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 4be01dbd677..cc9eed7e654 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,7 @@ mod traits { pub trait PubTr {} pub type Alias = 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 diff --git a/src/test/parse-fail/bounds-lifetime.rs b/src/test/parse-fail/bounds-lifetime.rs index 5113a6b4803..88db205310c 100644 --- a/src/test/parse-fail/bounds-lifetime.rs +++ b/src/test/parse-fail/bounds-lifetime.rs @@ -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() {} diff --git a/src/test/parse-fail/bounds-type.rs b/src/test/parse-fail/bounds-type.rs index c224b44a14b..0ebe7fde0a6 100644 --- a/src/test/parse-fail/bounds-type.rs +++ b/src/test/parse-fail/bounds-type.rs @@ -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 >; diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index 2d5dfb045db..fcad23926fc 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -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(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 {} diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/param-bounds-ignored.rs index a136ec60252..94bcdec9450 100644 --- a/src/test/ui/param-bounds-ignored.rs +++ b/src/test/ui/param-bounds-ignored.rs @@ -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 = Vec; -//~^ 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; -//~^ 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; //~^ 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 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) 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) 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 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 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 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 } diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/param-bounds-ignored.stderr index 55df5d1c939..657fec54f96 100644 --- a/src/test/ui/param-bounds-ignored.stderr +++ b/src/test/ui/param-bounds-ignored.stderr @@ -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 = Vec; - | ^^^^ ^^^^ - | - = 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; - | ^^ ^^ - -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; - | ^^^^^ ^^^^^ +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 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) 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) 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 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 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 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 = Vec; + | ^^^^ ^^^^ + | + = 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; + | ^^ ^^ + +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; + | ^^^^^ ^^^^^ + +error: aborting due to 11 previous errors + -- cgit 1.4.1-3-g733a5 From 780b544a391fb2dc42d814ce8cb7e6ad3633fa39 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Mar 2018 11:33:26 +0100 Subject: note a FIXME --- src/libsyntax/parse/parser.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ba8ccc2256f..b60a6b32fab 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4827,6 +4827,7 @@ impl<'a> Parser<'a> { } )); // FIXME: Decide what should be used here, `=` or `==`. + // FIXME: We are just dropping the binders in lifetime_defs on the floor here. } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { let rhs_ty = self.parse_ty()?; where_clause.predicates.push(ast::WherePredicate::EqPredicate( -- cgit 1.4.1-3-g733a5