1
1
//! Error Reporting for static impl Traits.
2
2
3
3
use rustc_data_structures:: fx:: FxIndexSet ;
4
- use rustc_errors:: { Applicability , Diag , ErrorGuaranteed , MultiSpan , Subdiagnostic } ;
4
+ use rustc_errors:: { Applicability , Diag , ErrorGuaranteed } ;
5
5
use rustc_hir:: def_id:: DefId ;
6
6
use rustc_hir:: intravisit:: { Visitor , VisitorExt , walk_ty} ;
7
7
use rustc_hir:: {
8
8
self as hir, AmbigArg , GenericBound , GenericParam , GenericParamKind , Item , ItemKind , Lifetime ,
9
9
LifetimeName , LifetimeParamKind , MissingLifetimeKind , Node , TyKind ,
10
10
} ;
11
- use rustc_middle:: ty:: {
12
- self , AssocItemContainer , StaticLifetimeVisitor , Ty , TyCtxt , TypeSuperVisitable , TypeVisitor ,
13
- } ;
11
+ use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitor } ;
14
12
use rustc_span:: def_id:: LocalDefId ;
15
13
use rustc_span:: { Ident , Span } ;
16
14
use tracing:: debug;
17
15
18
16
use crate :: error_reporting:: infer:: nice_region_error:: NiceRegionError ;
19
- use crate :: errors:: {
20
- ButCallingIntroduces , ButNeedsToSatisfy , DynTraitConstraintSuggestion , MoreTargeted ,
21
- ReqIntroducedLocations ,
22
- } ;
23
- use crate :: infer:: { RegionResolutionError , SubregionOrigin , TypeTrace } ;
24
- use crate :: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
17
+ use crate :: errors:: ButNeedsToSatisfy ;
18
+ use crate :: infer:: { RegionResolutionError , SubregionOrigin } ;
25
19
26
20
impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
27
21
/// Print the error message for lifetime errors when the return type is a static `impl Trait`,
@@ -39,52 +33,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
39
33
sup_r,
40
34
spans,
41
35
) if sub_r. is_static ( ) => ( var_origin, sub_origin, sub_r, sup_origin, sup_r, spans) ,
42
- RegionResolutionError :: ConcreteFailure (
43
- SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) ,
44
- sub_r,
45
- sup_r,
46
- ) if sub_r. is_static ( ) => {
47
- // This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
48
- if let ObligationCauseCode :: UnifyReceiver ( ctxt) = cause. code ( ) {
49
- // This may have a closure and it would cause ICE
50
- // through `find_param_with_region` (#78262).
51
- let anon_reg_sup = tcx. is_suitable_region ( self . generic_param_scope , * sup_r) ?;
52
- let fn_returns = tcx. return_type_impl_or_dyn_traits ( anon_reg_sup. scope ) ;
53
- if fn_returns. is_empty ( ) {
54
- return None ;
55
- }
56
-
57
- let param = self . find_param_with_region ( * sup_r, * sub_r) ?;
58
- let simple_ident = param. param . pat . simple_ident ( ) ;
59
-
60
- let ( has_impl_path, impl_path) = match ctxt. assoc_item . container {
61
- AssocItemContainer :: Trait => {
62
- let id = ctxt. assoc_item . container_id ( tcx) ;
63
- ( true , tcx. def_path_str ( id) )
64
- }
65
- AssocItemContainer :: Impl => ( false , String :: new ( ) ) ,
66
- } ;
67
-
68
- let mut err = self . tcx ( ) . dcx ( ) . create_err ( ButCallingIntroduces {
69
- param_ty_span : param. param_ty_span ,
70
- cause_span : cause. span ,
71
- has_param_name : simple_ident. is_some ( ) ,
72
- param_name : simple_ident. map ( |x| x. to_string ( ) ) . unwrap_or_default ( ) ,
73
- has_lifetime : sup_r. has_name ( ) ,
74
- lifetime : sup_r. to_string ( ) ,
75
- assoc_item : ctxt. assoc_item . name ,
76
- has_impl_path,
77
- impl_path,
78
- } ) ;
79
- if self . find_impl_on_dyn_trait ( & mut err, param. param_ty , ctxt) {
80
- let reported = err. emit ( ) ;
81
- return Some ( reported) ;
82
- } else {
83
- err. cancel ( )
84
- }
85
- }
86
- return None ;
87
- }
88
36
_ => return None ,
89
37
} ;
90
38
debug ! (
@@ -140,39 +88,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
140
88
None
141
89
} ;
142
90
143
- let mut subdiag = None ;
144
-
145
- if let SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) = sub_origin {
146
- if let ObligationCauseCode :: ReturnValue ( hir_id)
147
- | ObligationCauseCode :: BlockTailExpression ( hir_id, ..) = cause. code ( )
148
- {
149
- let parent_id = tcx. hir_get_parent_item ( * hir_id) ;
150
- if let Some ( fn_decl) = tcx. hir_fn_decl_by_hir_id ( parent_id. into ( ) ) {
151
- let mut span: MultiSpan = fn_decl. output . span ( ) . into ( ) ;
152
- let mut spans = Vec :: new ( ) ;
153
- let mut add_label = true ;
154
- if let hir:: FnRetTy :: Return ( ty) = fn_decl. output {
155
- let mut v = StaticLifetimeVisitor ( vec ! [ ] , tcx. hir ( ) ) ;
156
- v. visit_ty_unambig ( ty) ;
157
- if !v. 0 . is_empty ( ) {
158
- span = v. 0 . clone ( ) . into ( ) ;
159
- spans = v. 0 ;
160
- add_label = false ;
161
- }
162
- }
163
- let fn_decl_span = fn_decl. output . span ( ) ;
164
-
165
- subdiag = Some ( ReqIntroducedLocations {
166
- span,
167
- spans,
168
- fn_decl_span,
169
- cause_span : cause. span ,
170
- add_label,
171
- } ) ;
172
- }
173
- }
174
- }
175
-
176
91
let diag = ButNeedsToSatisfy {
177
92
sp,
178
93
influencer_point,
@@ -183,7 +98,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
183
98
require_span_as_note : require_as_note. then_some ( require_span) ,
184
99
// We don't need a note, it's already at the end, it can be shown as a `span_label`.
185
100
require_span_as_label : ( !require_as_note) . then_some ( require_span) ,
186
- req_introduces_loc : subdiag,
187
101
188
102
has_lifetime : sup_r. has_name ( ) ,
189
103
lifetime : lifetime_name. clone ( ) ,
@@ -197,45 +111,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
197
111
198
112
let fn_returns = tcx. return_type_impl_or_dyn_traits ( anon_reg_sup. scope ) ;
199
113
200
- let mut override_error_code = None ;
201
- if let SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) = & sup_origin
202
- && let ObligationCauseCode :: UnifyReceiver ( ctxt) = cause. code ( )
203
- // Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a
204
- // `'static` lifetime when called as a method on a binding: `bar.qux()`.
205
- && self . find_impl_on_dyn_trait ( & mut err, param. param_ty , ctxt)
206
- {
207
- override_error_code = Some ( ctxt. assoc_item . name ) ;
208
- }
209
-
210
- if let SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) = & sub_origin
211
- && let code = match cause. code ( ) {
212
- ObligationCauseCode :: MatchImpl ( parent, ..) => parent. code ( ) ,
213
- _ => cause. code ( ) ,
214
- }
215
- && let (
216
- & ObligationCauseCode :: WhereClause ( item_def_id, _)
217
- | & ObligationCauseCode :: WhereClauseInExpr ( item_def_id, ..) ,
218
- None ,
219
- ) = ( code, override_error_code)
220
- {
221
- // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
222
- // lifetime as above, but called using a fully-qualified path to the method:
223
- // `Foo::qux(bar)`.
224
- let mut v = TraitObjectVisitor ( FxIndexSet :: default ( ) ) ;
225
- v. visit_ty ( param. param_ty ) ;
226
- if let Some ( ( ident, self_ty) ) =
227
- NiceRegionError :: get_impl_ident_and_self_ty_from_trait ( tcx, item_def_id, & v. 0 )
228
- && self . suggest_constrain_dyn_trait_in_impl ( & mut err, & v. 0 , ident, self_ty)
229
- {
230
- override_error_code = Some ( ident. name ) ;
231
- }
232
- }
233
- if let ( Some ( ident) , true ) = ( override_error_code, fn_returns. is_empty ( ) ) {
234
- // Provide a more targeted error code and description.
235
- let retarget_subdiag = MoreTargeted { ident } ;
236
- retarget_subdiag. add_to_diag ( & mut err) ;
237
- }
238
-
239
114
let arg = match param. param . pat . simple_ident ( ) {
240
115
Some ( simple_ident) => format ! ( "argument `{simple_ident}`" ) ,
241
116
None => "the argument" . to_string ( ) ,
@@ -495,8 +370,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
495
370
kind : ItemKind :: Impl ( hir:: Impl { self_ty, .. } ) , ..
496
371
} ) = tcx. hir_node_by_def_id ( impl_did)
497
372
&& trait_objects. iter ( ) . all ( |did| {
498
- // FIXME: we should check `self_ty` against the receiver
499
- // type in the `UnifyReceiver` context, but for now, use
373
+ // FIXME: we should check `self_ty`, but for now, use
500
374
// this imperfect proxy. This will fail if there are
501
375
// multiple `impl`s for the same trait like
502
376
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
@@ -516,62 +390,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
516
390
_ => None ,
517
391
}
518
392
}
519
-
520
- /// When we call a method coming from an `impl Foo for dyn Bar`, `dyn Bar` introduces a default
521
- /// `'static` obligation. Suggest relaxing that implicit bound.
522
- fn find_impl_on_dyn_trait (
523
- & self ,
524
- err : & mut Diag < ' _ > ,
525
- ty : Ty < ' _ > ,
526
- ctxt : & UnifyReceiverContext < ' tcx > ,
527
- ) -> bool {
528
- let tcx = self . tcx ( ) ;
529
-
530
- // Find the method being called.
531
- let Ok ( Some ( instance) ) = ty:: Instance :: try_resolve (
532
- tcx,
533
- self . cx . typing_env ( ctxt. param_env ) ,
534
- ctxt. assoc_item . def_id ,
535
- self . cx . resolve_vars_if_possible ( ctxt. args ) ,
536
- ) else {
537
- return false ;
538
- } ;
539
-
540
- let mut v = TraitObjectVisitor ( FxIndexSet :: default ( ) ) ;
541
- v. visit_ty ( ty) ;
542
-
543
- // Get the `Ident` of the method being called and the corresponding `impl` (to point at
544
- // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
545
- let Some ( ( ident, self_ty) ) =
546
- NiceRegionError :: get_impl_ident_and_self_ty_from_trait ( tcx, instance. def_id ( ) , & v. 0 )
547
- else {
548
- return false ;
549
- } ;
550
-
551
- // Find the trait object types in the argument, so we point at *only* the trait object.
552
- self . suggest_constrain_dyn_trait_in_impl ( err, & v. 0 , ident, self_ty)
553
- }
554
-
555
- fn suggest_constrain_dyn_trait_in_impl (
556
- & self ,
557
- err : & mut Diag < ' _ > ,
558
- found_dids : & FxIndexSet < DefId > ,
559
- ident : Ident ,
560
- self_ty : & hir:: Ty < ' _ > ,
561
- ) -> bool {
562
- let mut suggested = false ;
563
- for found_did in found_dids {
564
- let mut traits = vec ! [ ] ;
565
- let mut hir_v = HirTraitObjectVisitor ( & mut traits, * found_did) ;
566
- hir_v. visit_ty_unambig ( self_ty) ;
567
- for & span in & traits {
568
- let subdiag = DynTraitConstraintSuggestion { span, ident } ;
569
- subdiag. add_to_diag ( err) ;
570
- suggested = true ;
571
- }
572
- }
573
- suggested
574
- }
575
393
}
576
394
577
395
/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
0 commit comments