@@ -18,6 +18,7 @@ use infer::region_inference::RegionResolutionError;
18
18
use hir:: map as hir_map;
19
19
use middle:: resolve_lifetime as rl;
20
20
use hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
21
+ use infer:: error_reporting:: util:: AnonymousArgInfo ;
21
22
22
23
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
23
24
// This method prints the error message for lifetime errors when both the concerned regions
@@ -57,6 +58,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
57
58
let ty_sup = or_false ! ( self . find_anon_type( sup, & bregion_sup) ) ;
58
59
59
60
let ty_sub = or_false ! ( self . find_anon_type( sub, & bregion_sub) ) ;
61
+
60
62
debug ! ( "try_report_anon_anon_conflict: found_arg1={:?} sup={:?} br1={:?}" ,
61
63
ty_sub,
62
64
sup,
@@ -66,56 +68,70 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
66
68
sub,
67
69
bregion_sub) ;
68
70
69
- let ( main_label , label1 , label2 ) = if let ( Some ( sup_arg ) , Some ( sub_arg ) ) =
70
- ( self . find_arg_with_region ( sup , sup ) , self . find_arg_with_region ( sub , sub ) ) {
71
+ let ( ty_sup , ty_fndecl_sup ) = ty_sup ;
72
+ let ( ty_sub , ty_fndecl_sub ) = ty_sub ;
71
73
72
- let ( anon_arg_sup, is_first_sup, anon_arg_sub, is_first_sub) =
73
- ( sup_arg. arg , sup_arg. is_first , sub_arg. arg , sub_arg. is_first ) ;
74
- if self . is_self_anon ( is_first_sup, scope_def_id_sup) ||
75
- self . is_self_anon ( is_first_sub, scope_def_id_sub) {
76
- return false ;
77
- }
74
+ let AnonymousArgInfo { arg : anon_arg_sup, .. } =
75
+ or_false ! ( self . find_arg_with_region( sup, sup) ) ;
76
+ let AnonymousArgInfo { arg : anon_arg_sub, .. } =
77
+ or_false ! ( self . find_arg_with_region( sub, sub) ) ;
78
78
79
- if self . is_return_type_anon ( scope_def_id_sup , bregion_sup ) ||
80
- self . is_return_type_anon ( scope_def_id_sub , bregion_sub ) {
81
- return false ;
82
- }
79
+ let sup_is_ret_type =
80
+ self . is_return_type_anon ( scope_def_id_sup , bregion_sup , ty_fndecl_sup ) ;
81
+ let sub_is_ret_type =
82
+ self . is_return_type_anon ( scope_def_id_sub , bregion_sub , ty_fndecl_sub ) ;
83
83
84
- if anon_arg_sup == anon_arg_sub {
85
- ( format ! ( "this type was declared with multiple lifetimes..." ) ,
86
- format ! ( " with one lifetime" ) ,
87
- format ! ( " into the other" ) )
88
- } else {
89
- let span_label_var1 = if let Some ( simple_name) = anon_arg_sup. pat . simple_name ( ) {
90
- format ! ( " from `{}`" , simple_name)
91
- } else {
92
- format ! ( "" )
93
- } ;
84
+ let span_label_var1 = if let Some ( simple_name) = anon_arg_sup. pat . simple_name ( ) {
85
+ format ! ( " from `{}`" , simple_name)
86
+ } else {
87
+ format ! ( "" )
88
+ } ;
89
+
90
+ let span_label_var2 = if let Some ( simple_name) = anon_arg_sub. pat . simple_name ( ) {
91
+ format ! ( " into `{}`" , simple_name)
92
+ } else {
93
+ format ! ( "" )
94
+ } ;
95
+
96
+
97
+ let ( span_1, span_2, main_label, span_label) = match ( sup_is_ret_type, sub_is_ret_type) {
98
+ ( None , None ) => {
99
+ let ( main_label_1, span_label_1) = if ty_sup == ty_sub {
94
100
95
- let span_label_var2 = if let Some ( simple_name) = anon_arg_sub. pat . simple_name ( ) {
96
- format ! ( " into `{}`" , simple_name)
101
+ ( format ! ( "this type is declared with multiple lifetimes..." ) ,
102
+ format ! ( "...but data{} flows{} here" ,
103
+ format!( " with one lifetime" ) ,
104
+ format!( " into the other" ) ) )
97
105
} else {
98
- format ! ( "" )
106
+ ( format ! ( "these two types are declared with different lifetimes..." ) ,
107
+ format ! ( "...but data{} flows{} here" ,
108
+ span_label_var1,
109
+ span_label_var2) )
99
110
} ;
111
+ ( ty_sup. span , ty_sub. span , main_label_1, span_label_1)
112
+ }
100
113
101
- let span_label =
102
- format ! ( "these two types are declared with different lifetimes..." , ) ;
103
-
104
- ( span_label, span_label_var1, span_label_var2)
114
+ ( Some ( ret_span) , _) => {
115
+ ( ty_sub. span ,
116
+ ret_span,
117
+ format ! ( "this parameter and the return type are declared \
118
+ with different lifetimes...", ) ,
119
+ format ! ( "...but data{} is returned here" , span_label_var1) )
120
+ }
121
+ ( _, Some ( ret_span) ) => {
122
+ ( ty_sup. span ,
123
+ ret_span,
124
+ format ! ( "this parameter and the return type are declared \
125
+ with different lifetimes...", ) ,
126
+ format ! ( "...but data{} is returned here" , span_label_var1) )
105
127
}
106
- } else {
107
- debug ! ( "no arg with anon region found" ) ;
108
- debug ! ( "try_report_anon_anon_conflict: is_suitable(sub) = {:?}" ,
109
- self . is_suitable_region( sub) ) ;
110
- debug ! ( "try_report_anon_anon_conflict: is_suitable(sup) = {:?}" ,
111
- self . is_suitable_region( sup) ) ;
112
- return false ;
113
128
} ;
114
129
130
+
115
131
struct_span_err ! ( self . tcx. sess, span, E0623 , "lifetime mismatch" )
116
- . span_label ( ty_sup . span , main_label)
117
- . span_label ( ty_sub . span , format ! ( "" ) )
118
- . span_label ( span, format ! ( "...but data{} flows{} here" , label1 , label2 ) )
132
+ . span_label ( span_1 , main_label)
133
+ . span_label ( span_2 , format ! ( "" ) )
134
+ . span_label ( span, span_label )
119
135
. emit ( ) ;
120
136
return true ;
121
137
}
@@ -135,28 +151,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
135
151
/// ```
136
152
/// The function returns the nested type corresponding to the anonymous region
137
153
/// for e.g. `&u8` and Vec<`&u8`.
138
- pub fn find_anon_type ( & self , region : Region < ' tcx > , br : & ty:: BoundRegion ) -> Option < & hir:: Ty > {
154
+ pub fn find_anon_type ( & self ,
155
+ region : Region < ' tcx > ,
156
+ br : & ty:: BoundRegion )
157
+ -> Option < ( & hir:: Ty , & hir:: FnDecl ) > {
139
158
if let Some ( anon_reg) = self . is_suitable_region ( region) {
140
159
let def_id = anon_reg. def_id ;
141
160
if let Some ( node_id) = self . tcx . hir . as_local_node_id ( def_id) {
142
- let inputs : & [ _ ] = match self . tcx . hir . get ( node_id) {
161
+ let fndecl = match self . tcx . hir . get ( node_id) {
143
162
hir_map:: NodeItem ( & hir:: Item { node : hir:: ItemFn ( ref fndecl, ..) , .. } ) => {
144
- & fndecl. inputs
163
+ & fndecl
145
164
}
146
165
hir_map:: NodeTraitItem ( & hir:: TraitItem {
147
- node : hir:: TraitItemKind :: Method ( ref fndecl , ..) , ..
148
- } ) => & fndecl . decl . inputs ,
166
+ node : hir:: TraitItemKind :: Method ( ref m , ..) , ..
167
+ } ) |
149
168
hir_map:: NodeImplItem ( & hir:: ImplItem {
150
- node : hir:: ImplItemKind :: Method ( ref fndecl, ..) , ..
151
- } ) => & fndecl. decl . inputs ,
152
-
153
- _ => & [ ] ,
169
+ node : hir:: ImplItemKind :: Method ( ref m, ..) , ..
170
+ } ) => & m. decl ,
171
+ _ => return None ,
154
172
} ;
155
173
156
- return inputs
174
+ return fndecl
175
+ . inputs
157
176
. iter ( )
158
- . filter_map ( |arg| self . find_component_for_bound_region ( & * * arg, br) )
159
- . next ( ) ;
177
+ . filter_map ( |arg| self . find_component_for_bound_region ( arg, br) )
178
+ . next ( )
179
+ . map ( |ty| ( ty, & * * fndecl) ) ;
160
180
}
161
181
}
162
182
None
0 commit comments