@@ -11,6 +11,8 @@ use rustc_span::symbol::sym;
1111use rustc_span:: Span ;
1212use rustc_target:: spec:: abi;
1313
14+ use crate :: errors:: ForbiddenLifetimeBound ;
15+
1416macro_rules! gate_feature_fn {
1517 ( $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => { {
1618 let ( visitor, has_feature, span, name, explain, help) =
@@ -136,6 +138,34 @@ impl<'a> PostExpansionVisitor<'a> {
136138 }
137139 ImplTraitVisitor { vis : self } . visit_ty ( ty) ;
138140 }
141+
142+ fn check_late_bound_lifetime_defs ( & self , params : & [ ast:: GenericParam ] ) {
143+ // Check only lifetime parameters are present and that the lifetime
144+ // parameters that are present have no bounds.
145+ let non_lt_param_spans: Vec < _ > = params
146+ . iter ( )
147+ . filter_map ( |param| match param. kind {
148+ ast:: GenericParamKind :: Lifetime { .. } => None ,
149+ _ => Some ( param. ident . span ) ,
150+ } )
151+ . collect ( ) ;
152+ // FIXME: gate_feature_post doesn't really handle multispans...
153+ if !non_lt_param_spans. is_empty ( ) && !self . features . non_lifetime_binders {
154+ feature_err (
155+ & self . sess . parse_sess ,
156+ sym:: non_lifetime_binders,
157+ non_lt_param_spans,
158+ rustc_errors:: fluent:: ast_passes_forbidden_non_lifetime_param,
159+ )
160+ . emit ( ) ;
161+ }
162+ for param in params {
163+ if !param. bounds . is_empty ( ) {
164+ let spans: Vec < _ > = param. bounds . iter ( ) . map ( |b| b. span ( ) ) . collect ( ) ;
165+ self . sess . emit_err ( ForbiddenLifetimeBound { spans } ) ;
166+ }
167+ }
168+ }
139169}
140170
141171impl < ' a > Visitor < ' a > for PostExpansionVisitor < ' a > {
@@ -147,7 +177,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
147177 ..
148178 } ) = attr_info
149179 {
150- gate_feature_fn ! ( self , has_feature, attr. span, * name, descr) ;
180+ gate_feature_fn ! ( self , has_feature, attr. span, * name, * descr) ;
151181 }
152182 // Check unstable flavors of the `#[doc]` attribute.
153183 if attr. has_name ( sym:: doc) {
@@ -306,6 +336,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
306336 ast:: TyKind :: BareFn ( bare_fn_ty) => {
307337 // Function pointers cannot be `const`
308338 self . check_extern ( bare_fn_ty. ext , ast:: Const :: No ) ;
339+ self . check_late_bound_lifetime_defs ( & bare_fn_ty. generic_params ) ;
309340 }
310341 ast:: TyKind :: Never => {
311342 gate_feature_post ! ( & self , never_type, ty. span, "the `!` type is experimental" ) ;
@@ -318,6 +349,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
318349 visit:: walk_ty ( self , ty)
319350 }
320351
352+ fn visit_generics ( & mut self , g : & ' a ast:: Generics ) {
353+ for predicate in & g. where_clause . predicates {
354+ match predicate {
355+ ast:: WherePredicate :: BoundPredicate ( bound_pred) => {
356+ // A type binding, eg `for<'c> Foo: Send+Clone+'c`
357+ self . check_late_bound_lifetime_defs ( & bound_pred. bound_generic_params ) ;
358+ }
359+ _ => { }
360+ }
361+ }
362+ visit:: walk_generics ( self , g) ;
363+ }
364+
321365 fn visit_fn_ret_ty ( & mut self , ret_ty : & ' a ast:: FnRetTy ) {
322366 if let ast:: FnRetTy :: Ty ( output_ty) = ret_ty {
323367 if let ast:: TyKind :: Never = output_ty. kind {
@@ -437,12 +481,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
437481 visit:: walk_pat ( self , pattern)
438482 }
439483
484+ fn visit_poly_trait_ref ( & mut self , t : & ' a ast:: PolyTraitRef ) {
485+ self . check_late_bound_lifetime_defs ( & t. bound_generic_params ) ;
486+ visit:: walk_poly_trait_ref ( self , t) ;
487+ }
488+
440489 fn visit_fn ( & mut self , fn_kind : FnKind < ' a > , span : Span , _: NodeId ) {
441490 if let Some ( header) = fn_kind. header ( ) {
442491 // Stability of const fn methods are covered in `visit_assoc_item` below.
443492 self . check_extern ( header. ext , header. constness ) ;
444493 }
445494
495+ if let FnKind :: Closure ( ast:: ClosureBinder :: For { generic_params, .. } , ..) = fn_kind {
496+ self . check_late_bound_lifetime_defs ( generic_params) ;
497+ }
498+
446499 if fn_kind. ctxt ( ) != Some ( FnCtxt :: Foreign ) && fn_kind. decl ( ) . c_variadic ( ) {
447500 gate_feature_post ! ( & self , c_variadic, span, "C-variadic functions are unstable" ) ;
448501 }
0 commit comments