@@ -87,6 +87,15 @@ pub mod nice_region_error;
87
87
pub mod region;
88
88
pub mod sub_relations;
89
89
90
+ /// A hint about where a type error occurred, for better diagnostics.
91
+ #[ derive( Debug , PartialEq ) ]
92
+ pub enum TypeErrorRole {
93
+ /// This type error occurred while resolving the "self" type of a method
94
+ SelfType ,
95
+ /// This type error occurred in any other context.
96
+ Elsewhere ,
97
+ }
98
+
90
99
/// Makes a valid string literal from a string by escaping special characters (" and \),
91
100
/// unless they are already escaped.
92
101
fn escape_literal ( s : & str ) -> String {
@@ -149,7 +158,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
149
158
actual : Ty < ' tcx > ,
150
159
err : TypeError < ' tcx > ,
151
160
) -> Diag < ' a > {
152
- self . report_and_explain_type_error ( TypeTrace :: types ( cause, true , expected, actual) , err)
161
+ self . report_and_explain_type_error (
162
+ TypeTrace :: types ( cause, true , expected, actual) ,
163
+ err,
164
+ TypeErrorRole :: Elsewhere ,
165
+ )
166
+ }
167
+
168
+ pub fn report_mismatched_self_types (
169
+ & self ,
170
+ cause : & ObligationCause < ' tcx > ,
171
+ expected : Ty < ' tcx > ,
172
+ actual : Ty < ' tcx > ,
173
+ err : TypeError < ' tcx > ,
174
+ ) -> Diag < ' a > {
175
+ self . report_and_explain_type_error (
176
+ TypeTrace :: types ( cause, true , expected, actual) ,
177
+ err,
178
+ TypeErrorRole :: SelfType ,
179
+ )
153
180
}
154
181
155
182
pub fn report_mismatched_consts (
@@ -159,7 +186,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
159
186
actual : ty:: Const < ' tcx > ,
160
187
err : TypeError < ' tcx > ,
161
188
) -> Diag < ' a > {
162
- self . report_and_explain_type_error ( TypeTrace :: consts ( cause, true , expected, actual) , err)
189
+ self . report_and_explain_type_error (
190
+ TypeTrace :: consts ( cause, true , expected, actual) ,
191
+ err,
192
+ TypeErrorRole :: Elsewhere ,
193
+ )
163
194
}
164
195
165
196
pub fn get_impl_future_output_ty ( & self , ty : Ty < ' tcx > ) -> Option < Ty < ' tcx > > {
@@ -1140,6 +1171,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1140
1171
terr : TypeError < ' tcx > ,
1141
1172
swap_secondary_and_primary : bool ,
1142
1173
prefer_label : bool ,
1174
+ role : TypeErrorRole ,
1143
1175
) {
1144
1176
let span = cause. span ( ) ;
1145
1177
@@ -1601,6 +1633,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1601
1633
1602
1634
self . check_and_note_conflicting_crates ( diag, terr) ;
1603
1635
1636
+ if role == TypeErrorRole :: SelfType {
1637
+ diag. note ( "this error occurred while resolving the `self` type of this method call" ) ;
1638
+ }
1639
+
1604
1640
self . note_and_explain_type_err ( diag, terr, cause, span, cause. body_id . to_def_id ( ) ) ;
1605
1641
if let Some ( exp_found) = exp_found
1606
1642
&& let exp_found = TypeError :: Sorts ( exp_found)
@@ -1783,8 +1819,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1783
1819
& self ,
1784
1820
trace : TypeTrace < ' tcx > ,
1785
1821
terr : TypeError < ' tcx > ,
1822
+ role : TypeErrorRole ,
1786
1823
) -> Diag < ' a > {
1787
- debug ! ( "report_and_explain_type_error(trace={:?}, terr={:?})" , trace, terr) ;
1824
+ debug ! (
1825
+ "report_and_explain_type_error(trace={:?}, terr={:?}, role={:?})" ,
1826
+ trace, terr, role
1827
+ ) ;
1788
1828
1789
1829
let span = trace. cause . span ( ) ;
1790
1830
let failure_code = trace. cause . as_failure_code_diag (
@@ -1793,7 +1833,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1793
1833
self . type_error_additional_suggestions ( & trace, terr) ,
1794
1834
) ;
1795
1835
let mut diag = self . dcx ( ) . create_err ( failure_code) ;
1796
- self . note_type_err ( & mut diag, & trace. cause , None , Some ( trace. values ) , terr, false , false ) ;
1836
+ self . note_type_err (
1837
+ & mut diag,
1838
+ & trace. cause ,
1839
+ None ,
1840
+ Some ( trace. values ) ,
1841
+ terr,
1842
+ false ,
1843
+ false ,
1844
+ role,
1845
+ ) ;
1797
1846
diag
1798
1847
}
1799
1848
0 commit comments