11//! Error Reporting for static impl Traits.
22
33use rustc_data_structures:: fx:: FxIndexSet ;
4- use rustc_errors:: { Applicability , Diag , ErrorGuaranteed , MultiSpan , Subdiagnostic } ;
4+ use rustc_errors:: { Applicability , Diag , ErrorGuaranteed } ;
55use rustc_hir:: def_id:: DefId ;
66use rustc_hir:: intravisit:: { Visitor , VisitorExt , walk_ty} ;
77use rustc_hir:: {
88 self as hir, AmbigArg , GenericBound , GenericParam , GenericParamKind , Item , ItemKind , Lifetime ,
99 LifetimeName , LifetimeParamKind , MissingLifetimeKind , Node , TyKind ,
1010} ;
11- use rustc_middle:: ty:: {
12- self , AssocItemContainer , StaticLifetimeVisitor , Ty , TyCtxt , TypeSuperVisitable , TypeVisitor ,
13- } ;
11+ use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitor } ;
1412use rustc_span:: def_id:: LocalDefId ;
1513use rustc_span:: { Ident , Span } ;
1614use tracing:: debug;
1715
1816use 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 } ;
2519
2620impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
2721 /// 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> {
3933 sup_r,
4034 spans,
4135 ) 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- }
8836 _ => return None ,
8937 } ;
9038 debug ! (
@@ -140,39 +88,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
14088 None
14189 } ;
14290
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-
17691 let diag = ButNeedsToSatisfy {
17792 sp,
17893 influencer_point,
@@ -183,7 +98,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
18398 require_span_as_note : require_as_note. then_some ( require_span) ,
18499 // We don't need a note, it's already at the end, it can be shown as a `span_label`.
185100 require_span_as_label : ( !require_as_note) . then_some ( require_span) ,
186- req_introduces_loc : subdiag,
187101
188102 has_lifetime : sup_r. has_name ( ) ,
189103 lifetime : lifetime_name. clone ( ) ,
@@ -197,45 +111,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
197111
198112 let fn_returns = tcx. return_type_impl_or_dyn_traits ( anon_reg_sup. scope ) ;
199113
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-
239114 let arg = match param. param . pat . simple_ident ( ) {
240115 Some ( simple_ident) => format ! ( "argument `{simple_ident}`" ) ,
241116 None => "the argument" . to_string ( ) ,
@@ -495,8 +370,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
495370 kind : ItemKind :: Impl ( hir:: Impl { self_ty, .. } ) , ..
496371 } ) = tcx. hir_node_by_def_id ( impl_did)
497372 && 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
500374 // this imperfect proxy. This will fail if there are
501375 // multiple `impl`s for the same trait like
502376 // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
@@ -516,62 +390,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
516390 _ => None ,
517391 }
518392 }
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- }
575393}
576394
577395/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
0 commit comments