99use std:: mem;
1010use syntax:: print:: pprust;
1111use rustc:: lint;
12- use rustc:: lint:: builtin:: { BuiltinLintDiagnostics , NESTED_IMPL_TRAIT } ;
1312use rustc:: session:: Session ;
1413use rustc_data_structures:: fx:: FxHashMap ;
1514use syntax:: ast:: * ;
@@ -23,39 +22,14 @@ use syntax::{span_err, struct_span_err, walk_list};
2322use syntax_pos:: { Span , MultiSpan } ;
2423use errors:: { Applicability , FatalError } ;
2524
26- #[ derive( Copy , Clone , Debug ) ]
27- struct OuterImplTrait {
28- span : Span ,
29-
30- /// rust-lang/rust#57979: a bug in original implementation caused
31- /// us to fail sometimes to record an outer `impl Trait`.
32- /// Therefore, in order to reliably issue a warning (rather than
33- /// an error) in the *precise* places where we are newly injecting
34- /// the diagnostic, we have to distinguish between the places
35- /// where the outer `impl Trait` has always been recorded, versus
36- /// the places where it has only recently started being recorded.
37- only_recorded_since_pull_request_57730 : bool ,
38- }
39-
40- impl OuterImplTrait {
41- /// This controls whether we should downgrade the nested impl
42- /// trait diagnostic to a warning rather than an error, based on
43- /// whether the outer impl trait had been improperly skipped in
44- /// earlier implementations of the analysis on the stable
45- /// compiler.
46- fn should_warn_instead_of_error ( & self ) -> bool {
47- self . only_recorded_since_pull_request_57730
48- }
49- }
50-
5125struct AstValidator < ' a > {
5226 session : & ' a Session ,
5327 has_proc_macro_decls : bool ,
5428
5529 /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
5630 /// Nested `impl Trait` _is_ allowed in associated type position,
5731 /// e.g., `impl Iterator<Item = impl Debug>`.
58- outer_impl_trait : Option < OuterImplTrait > ,
32+ outer_impl_trait : Option < Span > ,
5933
6034 /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
6135 /// or `Foo::Bar<impl Trait>`
@@ -65,26 +39,10 @@ struct AstValidator<'a> {
6539 /// certain positions.
6640 is_assoc_ty_bound_banned : bool ,
6741
68- /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
69- /// until PRs #57730 and #57981 landed: it would jump directly to
70- /// walk_ty rather than visit_ty (or skip recurring entirely for
71- /// impl trait in projections), and thus miss some cases. We track
72- /// whether we should downgrade to a warning for short-term via
73- /// these booleans.
74- warning_period_57979_didnt_record_next_impl_trait : bool ,
75- warning_period_57979_impl_trait_in_proj : bool ,
76-
7742 lint_buffer : & ' a mut lint:: LintBuffer ,
7843}
7944
8045impl < ' a > AstValidator < ' a > {
81- fn with_impl_trait_in_proj_warning < T > ( & mut self , v : bool , f : impl FnOnce ( & mut Self ) -> T ) -> T {
82- let old = mem:: replace ( & mut self . warning_period_57979_impl_trait_in_proj , v) ;
83- let ret = f ( self ) ;
84- self . warning_period_57979_impl_trait_in_proj = old;
85- ret
86- }
87-
8846 fn with_banned_impl_trait ( & mut self , f : impl FnOnce ( & mut Self ) ) {
8947 let old = mem:: replace ( & mut self . is_impl_trait_banned , true ) ;
9048 f ( self ) ;
@@ -97,22 +55,15 @@ impl<'a> AstValidator<'a> {
9755 self . is_assoc_ty_bound_banned = old;
9856 }
9957
100- fn with_impl_trait ( & mut self , outer : Option < OuterImplTrait > , f : impl FnOnce ( & mut Self ) ) {
58+ fn with_impl_trait ( & mut self , outer : Option < Span > , f : impl FnOnce ( & mut Self ) ) {
10159 let old = mem:: replace ( & mut self . outer_impl_trait , outer) ;
10260 f ( self ) ;
10361 self . outer_impl_trait = old;
10462 }
10563
10664 fn visit_assoc_ty_constraint_from_generic_args ( & mut self , constraint : & ' a AssocTyConstraint ) {
10765 match constraint. kind {
108- AssocTyConstraintKind :: Equality { ref ty } => {
109- // rust-lang/rust#57979: bug in old `visit_generic_args` called
110- // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait`
111- // if it happened to occur at `ty`.
112- if let TyKind :: ImplTrait ( ..) = ty. kind {
113- self . warning_period_57979_didnt_record_next_impl_trait = true ;
114- }
115- }
66+ AssocTyConstraintKind :: Equality { .. } => { }
11667 AssocTyConstraintKind :: Bound { .. } => {
11768 if self . is_assoc_ty_bound_banned {
11869 self . err_handler ( ) . span_err ( constraint. span ,
@@ -124,37 +75,11 @@ impl<'a> AstValidator<'a> {
12475 self . visit_assoc_ty_constraint ( constraint) ;
12576 }
12677
127- fn visit_ty_from_generic_args ( & mut self , ty : & ' a Ty ) {
128- // rust-lang/rust#57979: bug in old `visit_generic_args` called
129- // `walk_ty` rather than `visit_ty`, skippping outer `impl Trait`
130- // if it happened to occur at `ty`.
131- if let TyKind :: ImplTrait ( ..) = ty. kind {
132- self . warning_period_57979_didnt_record_next_impl_trait = true ;
133- }
134- self . visit_ty ( ty) ;
135- }
136-
137- fn outer_impl_trait ( & mut self , span : Span ) -> OuterImplTrait {
138- let only_recorded_since_pull_request_57730 =
139- self . warning_period_57979_didnt_record_next_impl_trait ;
140-
141- // (This flag is designed to be set to `true`, and then only
142- // reach the construction point for the outer impl trait once,
143- // so its safe and easiest to unconditionally reset it to
144- // false.)
145- self . warning_period_57979_didnt_record_next_impl_trait = false ;
146-
147- OuterImplTrait {
148- span, only_recorded_since_pull_request_57730,
149- }
150- }
151-
15278 // Mirrors `visit::walk_ty`, but tracks relevant state.
15379 fn walk_ty ( & mut self , t : & ' a Ty ) {
15480 match t. kind {
15581 TyKind :: ImplTrait ( ..) => {
156- let outer_impl_trait = self . outer_impl_trait ( t. span ) ;
157- self . with_impl_trait ( Some ( outer_impl_trait) , |this| visit:: walk_ty ( this, t) )
82+ self . with_impl_trait ( Some ( t. span ) , |this| visit:: walk_ty ( this, t) )
15883 }
15984 TyKind :: Path ( ref qself, ref path) => {
16085 // We allow these:
@@ -484,40 +409,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
484409 }
485410 TyKind :: ImplTrait ( _, ref bounds) => {
486411 if self . is_impl_trait_banned {
487- if self . warning_period_57979_impl_trait_in_proj {
488- self . lint_buffer . buffer_lint (
489- NESTED_IMPL_TRAIT , ty. id , ty. span ,
490- "`impl Trait` is not allowed in path parameters" ) ;
491- } else {
492- struct_span_err ! ( self . session, ty. span, E0667 ,
493- "`impl Trait` is not allowed in path parameters" ) . emit ( ) ;
494- }
412+ struct_span_err ! (
413+ self . session, ty. span, E0667 ,
414+ "`impl Trait` is not allowed in path parameters"
415+ )
416+ . emit ( ) ;
495417 }
496418
497- if let Some ( outer_impl_trait) = self . outer_impl_trait {
498- if outer_impl_trait. should_warn_instead_of_error ( ) {
499- self . lint_buffer . buffer_lint_with_diagnostic (
500- NESTED_IMPL_TRAIT , ty. id , ty. span ,
501- "nested `impl Trait` is not allowed" ,
502- BuiltinLintDiagnostics :: NestedImplTrait {
503- outer_impl_trait_span : outer_impl_trait. span ,
504- inner_impl_trait_span : ty. span ,
505- } ) ;
506- } else {
507- struct_span_err ! ( self . session, ty. span, E0666 ,
508- "nested `impl Trait` is not allowed" )
509- . span_label ( outer_impl_trait. span , "outer `impl Trait`" )
510- . span_label ( ty. span , "nested `impl Trait` here" )
511- . emit ( ) ;
512- }
419+ if let Some ( outer_impl_trait_sp) = self . outer_impl_trait {
420+ struct_span_err ! (
421+ self . session, ty. span, E0666 ,
422+ "nested `impl Trait` is not allowed"
423+ )
424+ . span_label ( outer_impl_trait_sp, "outer `impl Trait`" )
425+ . span_label ( ty. span , "nested `impl Trait` here" )
426+ . emit ( ) ;
513427 }
514428
515429 if !bounds. iter ( )
516430 . any ( |b| if let GenericBound :: Trait ( ..) = * b { true } else { false } ) {
517431 self . err_handler ( ) . span_err ( ty. span , "at least one trait must be specified" ) ;
518432 }
519433
520- self . with_impl_trait_in_proj_warning ( true , |this| this . walk_ty ( ty) ) ;
434+ self . walk_ty ( ty) ;
521435 return ;
522436 }
523437 _ => { }
@@ -726,7 +640,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
726640 if let Some ( ref type_) = data. output {
727641 // `-> Foo` syntax is essentially an associated type binding,
728642 // so it is also allowed to contain nested `impl Trait`.
729- self . with_impl_trait ( None , |this| this. visit_ty_from_generic_args ( type_) ) ;
643+ self . with_impl_trait ( None , |this| this. visit_ty ( type_) ) ;
730644 }
731645 }
732646 }
@@ -844,8 +758,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe
844758 outer_impl_trait : None ,
845759 is_impl_trait_banned : false ,
846760 is_assoc_ty_bound_banned : false ,
847- warning_period_57979_didnt_record_next_impl_trait : false ,
848- warning_period_57979_impl_trait_in_proj : false ,
849761 lint_buffer : lints,
850762 } ;
851763 visit:: walk_crate ( & mut validator, krate) ;
0 commit comments