diff options
| author | bors <bors@rust-lang.org> | 2018-03-09 10:45:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-03-09 10:45:29 +0000 |
| commit | fedce67cd21dc08ece5a484fe1a060346acac98a (patch) | |
| tree | 2cc26079f1d4ee58c1bc38e326585013e52f7e6b /src/libsyntax | |
| parent | 2079a084df08c38eb4dbfc5c8de5c0245170c3d9 (diff) | |
| parent | 780b544a391fb2dc42d814ce8cb7e6ad3633fa39 (diff) | |
| download | rust-fedce67cd21dc08ece5a484fe1a060346acac98a.tar.gz rust-fedce67cd21dc08ece5a484fe1a060346acac98a.zip | |
Auto merge of #48326 - RalfJung:generic-bounds, r=petrochenkov
Warn about ignored generic bounds in `for` This adds a new lint to fix #42181. For consistency and to avoid code duplication, I also moved the existing "bounds in type aliases are ignored" here. Questions to the reviewer: * Is it okay to just remove a diagnostic error code like this? Should I instead keep the warning about type aliases where it is? The old code provided a detailed explanation of what's going on when asked, that information is now lost. On the other hand, `span_warn!` seems deprecated (after this patch, it has exactly one user left!). * Did I miss any syntactic construct that can appear as `for` in the surface syntax? I covered function types (`for<'a> fn(...)`), generic traits (`for <'a> Fn(...)`, can appear both as bounds as as trait objects) and bounds (`for<'a> F: ...`). * For the sake of backwards compatibility, this adds a warning, not an error. @nikomatsakis suggested an error in https://github.com/rust-lang/rust/issues/42181#issuecomment-306924389, but I feel that can only happen in a new epoch -- right? Cc @eddyb
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 15 |
2 files changed, 22 insertions, 12 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 10b8e121f83..8b3a7164ccc 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` diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 847733e1e37..f5aa01fb034 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4951,6 +4951,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( @@ -5608,18 +5609,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()) |
