@@ -4,16 +4,13 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
55use crate :: infer:: { Subtype , TyCtxtInferExt , ValuePairs } ;
66use crate :: traits:: ObligationCauseCode :: CompareImplMethodObligation ;
7- use rustc_data_structures:: fx:: FxIndexSet ;
87use rustc_errors:: ErrorReported ;
98use rustc_hir as hir;
109use rustc_hir:: def_id:: DefId ;
1110use rustc_hir:: intravisit:: Visitor ;
12- use rustc_hir:: ItemKind ;
1311use rustc_middle:: ty:: error:: ExpectedFound ;
14- use rustc_middle:: ty:: fold:: TypeFoldable ;
1512use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
16- use rustc_span:: Span ;
13+ use rustc_span:: { MultiSpan , Span } ;
1714
1815impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
1916 /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
@@ -63,41 +60,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6360 . struct_span_err ( sp, "`impl` item signature doesn't match `trait` item signature" ) ;
6461 err. span_label ( sp, & format ! ( "found `{:?}`" , found) ) ;
6562 err. span_label ( trait_sp, & format ! ( "expected `{:?}`" , expected) ) ;
66- let trait_fn_sig = tcx. fn_sig ( trait_def_id) ;
67-
68- // Check the `trait`'s method's output to look for type parameters that might have
69- // unconstrained lifetimes. If the method returns a type parameter and the `impl` has a
70- // borrow as the type parameter being implemented, the lifetimes will not match because
71- // a new lifetime is being introduced in the `impl` that is not present in the `trait`.
72- // Because this is confusing as hell the first time you see it, we give a short message
73- // explaining the situation and proposing constraining the type param with a named lifetime
74- // so that the `impl` will have one to tie them together.
75- struct AssocTypeFinder ( FxIndexSet < ty:: ParamTy > ) ;
76- impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for AssocTypeFinder {
77- fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> bool {
78- if let ty:: Param ( param) = ty. kind {
79- self . 0 . insert ( param) ;
80- }
81- ty. super_visit_with ( self )
82- }
83- }
84- let mut visitor = AssocTypeFinder ( FxIndexSet :: default ( ) ) ;
85- trait_fn_sig. output ( ) . visit_with ( & mut visitor) ;
86- if let Some ( id) = trait_def_id. as_local ( ) . map ( |id| tcx. hir ( ) . as_local_hir_id ( id) ) {
87- let parent_id = tcx. hir ( ) . get_parent_item ( id) ;
88- let trait_item = tcx. hir ( ) . expect_item ( parent_id) ;
89- if let ItemKind :: Trait ( _, _, generics, _, _) = & trait_item. kind {
90- for param_ty in & visitor. 0 {
91- if let Some ( generic) = generics. get_named ( param_ty. name ) {
92- err. span_label (
93- generic. span ,
94- "this type parameter might not have a lifetime compatible with the \
95- `impl`",
96- ) ;
97- }
98- }
99- }
100- }
10163
10264 // Get the span of all the used type parameters in the method.
10365 let assoc_item = self . tcx ( ) . associated_item ( trait_def_id) ;
@@ -114,11 +76,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
11476 }
11577 _ => { }
11678 }
117- for span in visitor. types {
118- err. span_label (
79+ let mut type_param_span: MultiSpan =
80+ visitor. types . iter ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) . into ( ) ;
81+ for & span in & visitor. types {
82+ type_param_span. push_span_label (
11983 span,
120- "you might want to borrow this type parameter in the trait to make it match the \
121- `impl`",
84+ "consider borrowing this type parameter in the trait" . to_string ( ) ,
12285 ) ;
12386 }
12487
@@ -132,11 +95,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
13295 // This fallback shouldn't be necessary, but let's keep it in just in case.
13396 err. note ( & format ! ( "expected `{:?}`\n found `{:?}`" , expected, found) ) ;
13497 }
135- err. note ( "the lifetime requirements from the `trait` could not be satisfied by the `impl`" ) ;
136- err . help (
137- "verify the lifetime relationships in the `trait` and `impl` between the `self` \
138- argument, the other inputs and its output ",
98+ err. span_help (
99+ type_param_span ,
100+ "the lifetime requirements from the `impl` do not correspond to the requirements in \
101+ the `trait` ",
139102 ) ;
103+ if visitor. types . is_empty ( ) {
104+ err. help (
105+ "verify the lifetime relationships in the `trait` and `impl` between the `self` \
106+ argument, the other inputs and its output",
107+ ) ;
108+ }
140109 err. emit ( ) ;
141110 }
142111}
0 commit comments