@@ -4,16 +4,13 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
4
4
use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
5
5
use crate :: infer:: { Subtype , TyCtxtInferExt , ValuePairs } ;
6
6
use crate :: traits:: ObligationCauseCode :: CompareImplMethodObligation ;
7
- use rustc_data_structures:: fx:: FxIndexSet ;
8
7
use rustc_errors:: ErrorReported ;
9
8
use rustc_hir as hir;
10
9
use rustc_hir:: def_id:: DefId ;
11
10
use rustc_hir:: intravisit:: Visitor ;
12
- use rustc_hir:: ItemKind ;
13
11
use rustc_middle:: ty:: error:: ExpectedFound ;
14
- use rustc_middle:: ty:: fold:: TypeFoldable ;
15
12
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
16
- use rustc_span:: Span ;
13
+ use rustc_span:: { MultiSpan , Span } ;
17
14
18
15
impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
19
16
/// 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> {
63
60
. struct_span_err ( sp, "`impl` item signature doesn't match `trait` item signature" ) ;
64
61
err. span_label ( sp, & format ! ( "found `{:?}`" , found) ) ;
65
62
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
- }
101
63
102
64
// Get the span of all the used type parameters in the method.
103
65
let assoc_item = self . tcx ( ) . associated_item ( trait_def_id) ;
@@ -114,11 +76,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
114
76
}
115
77
_ => { }
116
78
}
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 (
119
83
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 ( ) ,
122
85
) ;
123
86
}
124
87
@@ -132,11 +95,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
132
95
// This fallback shouldn't be necessary, but let's keep it in just in case.
133
96
err. note ( & format ! ( "expected `{:?}`\n found `{:?}`" , expected, found) ) ;
134
97
}
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` ",
139
102
) ;
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
+ }
140
109
err. emit ( ) ;
141
110
}
142
111
}
0 commit comments