@@ -86,6 +86,15 @@ pub mod nice_region_error;
86
86
pub mod region;
87
87
pub mod sub_relations;
88
88
89
+ /// A hint about where a type error occurred, for better diagnostics.
90
+ #[ derive( Debug , PartialEq ) ]
91
+ pub enum TypeErrorRole {
92
+ /// This type error occurred while resolving the "self" type of a method
93
+ SelfType ,
94
+ /// This type error occurred in any other context.
95
+ Elsewhere ,
96
+ }
97
+
89
98
/// Makes a valid string literal from a string by escaping special characters (" and \),
90
99
/// unless they are already escaped.
91
100
fn escape_literal ( s : & str ) -> String {
@@ -148,7 +157,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
148
157
actual : Ty < ' tcx > ,
149
158
err : TypeError < ' tcx > ,
150
159
) -> Diag < ' a > {
151
- self . report_and_explain_type_error ( TypeTrace :: types ( cause, true , expected, actual) , err)
160
+ self . report_and_explain_type_error (
161
+ TypeTrace :: types ( cause, true , expected, actual) ,
162
+ err,
163
+ TypeErrorRole :: Elsewhere ,
164
+ )
165
+ }
166
+
167
+ pub fn report_mismatched_self_types (
168
+ & self ,
169
+ cause : & ObligationCause < ' tcx > ,
170
+ expected : Ty < ' tcx > ,
171
+ actual : Ty < ' tcx > ,
172
+ err : TypeError < ' tcx > ,
173
+ ) -> Diag < ' a > {
174
+ self . report_and_explain_type_error (
175
+ TypeTrace :: types ( cause, true , expected, actual) ,
176
+ err,
177
+ TypeErrorRole :: SelfType ,
178
+ )
152
179
}
153
180
154
181
pub fn report_mismatched_consts (
@@ -158,7 +185,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
158
185
actual : ty:: Const < ' tcx > ,
159
186
err : TypeError < ' tcx > ,
160
187
) -> Diag < ' a > {
161
- self . report_and_explain_type_error ( TypeTrace :: consts ( cause, true , expected, actual) , err)
188
+ self . report_and_explain_type_error (
189
+ TypeTrace :: consts ( cause, true , expected, actual) ,
190
+ err,
191
+ TypeErrorRole :: Elsewhere ,
192
+ )
162
193
}
163
194
164
195
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