9
9
use std:: mem;
10
10
use syntax:: print:: pprust;
11
11
use rustc:: lint;
12
- use rustc:: lint:: builtin:: { BuiltinLintDiagnostics , NESTED_IMPL_TRAIT } ;
13
12
use rustc:: session:: Session ;
14
13
use rustc_data_structures:: fx:: FxHashMap ;
15
14
use syntax:: ast:: * ;
@@ -23,39 +22,14 @@ use syntax::{span_err, struct_span_err, walk_list};
23
22
use syntax_pos:: { Span , MultiSpan } ;
24
23
use errors:: { Applicability , FatalError } ;
25
24
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
-
51
25
struct AstValidator < ' a > {
52
26
session : & ' a Session ,
53
27
has_proc_macro_decls : bool ,
54
28
55
29
/// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
56
30
/// Nested `impl Trait` _is_ allowed in associated type position,
57
31
/// e.g., `impl Iterator<Item = impl Debug>`.
58
- outer_impl_trait : Option < OuterImplTrait > ,
32
+ outer_impl_trait : Option < Span > ,
59
33
60
34
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
61
35
/// or `Foo::Bar<impl Trait>`
@@ -65,26 +39,10 @@ struct AstValidator<'a> {
65
39
/// certain positions.
66
40
is_assoc_ty_bound_banned : bool ,
67
41
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
-
77
42
lint_buffer : & ' a mut lint:: LintBuffer ,
78
43
}
79
44
80
45
impl < ' 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
-
88
46
fn with_banned_impl_trait ( & mut self , f : impl FnOnce ( & mut Self ) ) {
89
47
let old = mem:: replace ( & mut self . is_impl_trait_banned , true ) ;
90
48
f ( self ) ;
@@ -97,22 +55,15 @@ impl<'a> AstValidator<'a> {
97
55
self . is_assoc_ty_bound_banned = old;
98
56
}
99
57
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 ) ) {
101
59
let old = mem:: replace ( & mut self . outer_impl_trait , outer) ;
102
60
f ( self ) ;
103
61
self . outer_impl_trait = old;
104
62
}
105
63
106
64
fn visit_assoc_ty_constraint_from_generic_args ( & mut self , constraint : & ' a AssocTyConstraint ) {
107
65
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 { .. } => { }
116
67
AssocTyConstraintKind :: Bound { .. } => {
117
68
if self . is_assoc_ty_bound_banned {
118
69
self . err_handler ( ) . span_err ( constraint. span ,
@@ -124,37 +75,11 @@ impl<'a> AstValidator<'a> {
124
75
self . visit_assoc_ty_constraint ( constraint) ;
125
76
}
126
77
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
-
152
78
// Mirrors `visit::walk_ty`, but tracks relevant state.
153
79
fn walk_ty ( & mut self , t : & ' a Ty ) {
154
80
match t. kind {
155
81
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) )
158
83
}
159
84
TyKind :: Path ( ref qself, ref path) => {
160
85
// We allow these:
@@ -484,40 +409,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
484
409
}
485
410
TyKind :: ImplTrait ( _, ref bounds) => {
486
411
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 ( ) ;
495
417
}
496
418
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 ( ) ;
513
427
}
514
428
515
429
if !bounds. iter ( )
516
430
. any ( |b| if let GenericBound :: Trait ( ..) = * b { true } else { false } ) {
517
431
self . err_handler ( ) . span_err ( ty. span , "at least one trait must be specified" ) ;
518
432
}
519
433
520
- self . with_impl_trait_in_proj_warning ( true , |this| this . walk_ty ( ty) ) ;
434
+ self . walk_ty ( ty) ;
521
435
return ;
522
436
}
523
437
_ => { }
@@ -726,7 +640,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
726
640
if let Some ( ref type_) = data. output {
727
641
// `-> Foo` syntax is essentially an associated type binding,
728
642
// 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_) ) ;
730
644
}
731
645
}
732
646
}
@@ -844,8 +758,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe
844
758
outer_impl_trait : None ,
845
759
is_impl_trait_banned : false ,
846
760
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 ,
849
761
lint_buffer : lints,
850
762
} ;
851
763
visit:: walk_crate ( & mut validator, krate) ;
0 commit comments