Skip to content

Commit 23db43a

Browse files
committed
Add diagnostics while resolving self types.
1 parent f13ebc7 commit 23db43a

File tree

12 files changed

+97
-19
lines changed

12 files changed

+97
-19
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::ty::{
1515
};
1616
use rustc_span::Span;
1717
use rustc_trait_selection::error_reporting::infer::nice_region_error::NiceRegionError;
18+
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
1819
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
1920
use rustc_trait_selection::traits::query::type_op;
2021
use rustc_trait_selection::traits::ObligationCtxt;
@@ -481,12 +482,11 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
481482
.try_report_from_nll()
482483
.or_else(|| {
483484
if let SubregionOrigin::Subtype(trace) = cause {
484-
Some(
485-
infcx.err_ctxt().report_and_explain_type_error(
486-
*trace,
487-
TypeError::RegionsPlaceholderMismatch,
488-
),
489-
)
485+
Some(infcx.err_ctxt().report_and_explain_type_error(
486+
*trace,
487+
TypeError::RegionsPlaceholderMismatch,
488+
TypeErrorRole::Elsewhere,
489+
))
490490
} else {
491491
None
492492
}

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_middle::ty::{
2121
};
2222
use rustc_middle::{bug, span_bug};
2323
use rustc_span::Span;
24+
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
2425
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2526
use rustc_trait_selection::infer::InferCtxtExt;
2627
use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -611,6 +612,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
611612
terr,
612613
false,
613614
false,
615+
TypeErrorRole::Elsewhere,
614616
);
615617
return Err(diag.emit());
616618
}
@@ -1035,6 +1037,7 @@ fn report_trait_method_mismatch<'tcx>(
10351037
terr,
10361038
false,
10371039
false,
1040+
TypeErrorRole::Elsewhere,
10381041
);
10391042

10401043
return diag.emit();
@@ -1842,6 +1845,7 @@ fn compare_const_predicate_entailment<'tcx>(
18421845
terr,
18431846
false,
18441847
false,
1848+
TypeErrorRole::Elsewhere,
18451849
);
18461850
return Err(diag.emit());
18471851
};

compiler/rustc_hir_analysis/src/check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ use rustc_span::symbol::{kw, sym, Ident};
9393
use rustc_span::{BytePos, Span, Symbol, DUMMY_SP};
9494
use rustc_target::abi::VariantIdx;
9595
use rustc_target::spec::abi::Abi;
96-
use rustc_trait_selection::error_reporting::infer::ObligationCauseExt as _;
96+
use rustc_trait_selection::error_reporting::infer::{ObligationCauseExt as _, TypeErrorRole};
9797
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
9898
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
9999
use rustc_trait_selection::traits::ObligationCtxt;
@@ -655,6 +655,7 @@ pub fn check_function_signature<'tcx>(
655655
err,
656656
false,
657657
false,
658+
TypeErrorRole::Elsewhere,
658659
);
659660
return Err(diag.emit());
660661
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ use rustc_middle::{bug, span_bug};
2323
use rustc_session::Session;
2424
use rustc_span::symbol::{kw, Ident};
2525
use rustc_span::{sym, Span, DUMMY_SP};
26-
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
26+
use rustc_trait_selection::error_reporting::infer::{
27+
FailureCode, ObligationCauseExt, TypeErrorRole,
28+
};
2729
use rustc_trait_selection::infer::InferCtxtExt;
2830
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
2931
use {rustc_ast as ast, rustc_hir as hir};
@@ -794,6 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
794796
provided_arg_tys[mismatch_idx.into()].0,
795797
),
796798
terr,
799+
TypeErrorRole::Elsewhere,
797800
);
798801
err.span_label(
799802
full_call_span,
@@ -877,7 +880,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
877880
let trace =
878881
mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
879882
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) {
880-
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *e);
883+
let mut err = self.err_ctxt().report_and_explain_type_error(
884+
trace,
885+
*e,
886+
TypeErrorRole::Elsewhere,
887+
);
881888
suggest_confusable(&mut err);
882889
reported = Some(err.emit());
883890
return false;
@@ -905,7 +912,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
905912
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
906913
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
907914
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
908-
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
915+
let mut err = self.err_ctxt().report_and_explain_type_error(
916+
trace,
917+
*err,
918+
TypeErrorRole::Elsewhere,
919+
);
909920
self.emit_coerce_suggestions(
910921
&mut err,
911922
provided_args[*provided_idx],
@@ -1081,6 +1092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10811092
e,
10821093
false,
10831094
true,
1095+
TypeErrorRole::Elsewhere,
10841096
);
10851097
}
10861098
}

compiler/rustc_hir_typeck/src/method/confirm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
520520
// to the feature, like the self type can't reference method args.
521521
if self.tcx.features().arbitrary_self_types {
522522
self.err_ctxt()
523-
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
523+
.report_mismatched_self_types(&cause, method_self_ty, self_ty, terr)
524524
.emit();
525525
} else {
526526
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions

compiler/rustc_passes/src/check_attr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_session::parse::feature_err;
3535
use rustc_span::symbol::{kw, sym, Symbol};
3636
use rustc_span::{BytePos, Span, DUMMY_SP};
3737
use rustc_target::spec::abi::Abi;
38+
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
3839
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
3940
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
4041
use rustc_trait_selection::traits::ObligationCtxt;
@@ -2359,6 +2360,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23592360
terr,
23602361
false,
23612362
false,
2363+
TypeErrorRole::Elsewhere,
23622364
);
23632365
diag.emit();
23642366
self.abort.set(true);

compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

+53-4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ pub mod nice_region_error;
8686
pub mod region;
8787
pub mod sub_relations;
8888

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+
8998
/// Makes a valid string literal from a string by escaping special characters (" and \),
9099
/// unless they are already escaped.
91100
fn escape_literal(s: &str) -> String {
@@ -148,7 +157,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
148157
actual: Ty<'tcx>,
149158
err: TypeError<'tcx>,
150159
) -> 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+
)
152179
}
153180

154181
pub fn report_mismatched_consts(
@@ -158,7 +185,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
158185
actual: ty::Const<'tcx>,
159186
err: TypeError<'tcx>,
160187
) -> 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+
)
162193
}
163194

164195
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
@@ -1140,6 +1171,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
11401171
terr: TypeError<'tcx>,
11411172
swap_secondary_and_primary: bool,
11421173
prefer_label: bool,
1174+
role: TypeErrorRole,
11431175
) {
11441176
let span = cause.span();
11451177

@@ -1601,6 +1633,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16011633

16021634
self.check_and_note_conflicting_crates(diag, terr);
16031635

1636+
if role == TypeErrorRole::SelfType {
1637+
diag.note("this error occurred while resolving the `self` type of this method call");
1638+
}
1639+
16041640
self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
16051641
if let Some(exp_found) = exp_found
16061642
&& let exp_found = TypeError::Sorts(exp_found)
@@ -1783,8 +1819,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17831819
&self,
17841820
trace: TypeTrace<'tcx>,
17851821
terr: TypeError<'tcx>,
1822+
role: TypeErrorRole,
17861823
) -> 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+
);
17881828

17891829
let span = trace.cause.span();
17901830
let failure_code = trace.cause.as_failure_code_diag(
@@ -1793,7 +1833,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17931833
self.type_error_additional_suggestions(&trace, terr),
17941834
);
17951835
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+
);
17971846
diag
17981847
}
17991848

compiler/rustc_trait_selection/src/error_reporting/infer/region.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol};
1717
use rustc_type_ir::Upcast as _;
1818

1919
use super::nice_region_error::find_anon_type;
20-
use super::ObligationCauseAsDiagArg;
20+
use super::{ObligationCauseAsDiagArg, TypeErrorRole};
2121
use crate::error_reporting::infer::ObligationCauseExt;
2222
use crate::error_reporting::TypeErrCtxt;
2323
use crate::errors::{
@@ -294,7 +294,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
294294
let mut err = match origin {
295295
infer::Subtype(box trace) => {
296296
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
297-
let mut err = self.report_and_explain_type_error(trace, terr);
297+
let mut err =
298+
self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
298299
match (*sub, *sup) {
299300
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
300301
(ty::RePlaceholder(_), _) => {
@@ -637,7 +638,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
637638
}
638639
infer::Subtype(box trace) => {
639640
let terr = TypeError::RegionsPlaceholderMismatch;
640-
return self.report_and_explain_type_error(trace, terr);
641+
return self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
641642
}
642643
_ => {
643644
return self.report_concrete_failure(

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use super::suggestions::get_explanation_based_on_obligation;
3434
use super::{
3535
ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst,
3636
};
37-
use crate::error_reporting::infer::TyCategory;
37+
use crate::error_reporting::infer::{TyCategory, TypeErrorRole};
3838
use crate::error_reporting::traits::report_object_safety_error;
3939
use crate::error_reporting::TypeErrCtxt;
4040
use crate::errors::{
@@ -666,6 +666,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
666666
TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
667667
false,
668668
false,
669+
TypeErrorRole::Elsewhere
669670
);
670671
diag
671672
}
@@ -1409,6 +1410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
14091410
err,
14101411
true,
14111412
false,
1413+
TypeErrorRole::Elsewhere,
14121414
);
14131415
self.note_obligation_cause(&mut diag, obligation);
14141416
diag.emit()
@@ -2555,6 +2557,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
25552557
self.report_and_explain_type_error(
25562558
TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
25572559
terr,
2560+
TypeErrorRole::Elsewhere,
25582561
)
25592562
}
25602563

@@ -2652,6 +2655,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
26522655
found_trait_ref,
26532656
),
26542657
ty::error::TypeError::Mismatch,
2658+
TypeErrorRole::Elsewhere,
26552659
)
26562660
} else if found.len() == expected.len() {
26572661
self.report_closure_arg_mismatch(

tests/ui/self/arbitrary-self-from-method-substs-mismatches.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | smart_ptr.a::<SmartPtr2<Foo>>();
66
|
77
= note: expected struct `SmartPtr2<'_, Foo>`
88
found struct `SmartPtr<'_, Foo>`
9+
= note: this error occurred while resolving the `self` type of this method call
910

1011
error[E0308]: mismatched types
1112
--> $DIR/arbitrary-self-from-method-substs-mismatches.rs:36:5
@@ -15,6 +16,7 @@ LL | smart_ptr.a::<&Foo>();
1516
|
1617
= note: expected reference `&Foo`
1718
found struct `SmartPtr<'_, Foo, >`
19+
= note: this error occurred while resolving the `self` type of this method call
1820

1921
error: aborting due to 2 previous errors
2022

tests/ui/self/arbitrary-self-from-method-substs-rc.feature.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | foo.get::<std::rc::Rc<Foo>>();
66
|
77
= note: expected struct `Rc<Foo>`
88
found struct `Foo`
9+
= note: this error occurred while resolving the `self` type of this method call
910

1011
error: aborting due to 1 previous error
1112

tests/ui/self/arbitrary-self-from-method-substs.feature.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0308]: mismatched types
33
|
44
LL | foo.get::<&Foo>();
55
| ^^^ expected `&Foo`, found `Foo`
6+
|
7+
= note: this error occurred while resolving the `self` type of this method call
68

79
error: aborting due to 1 previous error
810

0 commit comments

Comments
 (0)