Skip to content

Commit 0c993f8

Browse files
committed
Add diagnostics while resolving self types.
1 parent 7f4b270 commit 0c993f8

File tree

10 files changed

+94
-19
lines changed

10 files changed

+94
-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;
@@ -482,12 +483,11 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
482483
.try_report_from_nll()
483484
.or_else(|| {
484485
if let SubregionOrigin::Subtype(trace) = cause {
485-
Some(
486-
infcx.err_ctxt().report_and_explain_type_error(
487-
*trace,
488-
TypeError::RegionsPlaceholderMismatch,
489-
),
490-
)
486+
Some(infcx.err_ctxt().report_and_explain_type_error(
487+
*trace,
488+
TypeError::RegionsPlaceholderMismatch,
489+
TypeErrorRole::Elsewhere,
490+
))
491491
} else {
492492
None
493493
}

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;
@@ -612,6 +613,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
612613
terr,
613614
false,
614615
false,
616+
TypeErrorRole::Elsewhere,
615617
);
616618
return Err(diag.emit());
617619
}
@@ -1036,6 +1038,7 @@ fn report_trait_method_mismatch<'tcx>(
10361038
terr,
10371039
false,
10381040
false,
1041+
TypeErrorRole::Elsewhere,
10391042
);
10401043

10411044
return diag.emit();
@@ -1843,6 +1846,7 @@ fn compare_const_predicate_entailment<'tcx>(
18431846
terr,
18441847
false,
18451848
false,
1849+
TypeErrorRole::Elsewhere,
18461850
);
18471851
return Err(diag.emit());
18481852
};

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;
@@ -656,6 +656,7 @@ pub fn check_function_signature<'tcx>(
656656
err,
657657
false,
658658
false,
659+
TypeErrorRole::Elsewhere,
659660
);
660661
return Err(diag.emit());
661662
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ use rustc_middle::{bug, span_bug};
2424
use rustc_session::Session;
2525
use rustc_span::symbol::{kw, Ident};
2626
use rustc_span::{sym, Span, DUMMY_SP};
27-
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
27+
use rustc_trait_selection::error_reporting::infer::{
28+
FailureCode, ObligationCauseExt, TypeErrorRole,
29+
};
2830
use rustc_trait_selection::infer::InferCtxtExt;
2931
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
3032
use tracing::debug;
@@ -826,6 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
826828
provided_arg_tys[mismatch_idx.into()].0,
827829
),
828830
terr,
831+
TypeErrorRole::Elsewhere,
829832
);
830833
err.span_label(
831834
full_call_span,
@@ -909,7 +912,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
909912
let trace =
910913
mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
911914
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) {
912-
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *e);
915+
let mut err = self.err_ctxt().report_and_explain_type_error(
916+
trace,
917+
*e,
918+
TypeErrorRole::Elsewhere,
919+
);
913920
suggest_confusable(&mut err);
914921
reported = Some(err.emit());
915922
return false;
@@ -937,7 +944,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
937944
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
938945
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
939946
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
940-
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
947+
let mut err = self.err_ctxt().report_and_explain_type_error(
948+
trace,
949+
*err,
950+
TypeErrorRole::Elsewhere,
951+
);
941952
self.emit_coerce_suggestions(
942953
&mut err,
943954
provided_args[*provided_idx],
@@ -1113,6 +1124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11131124
e,
11141125
false,
11151126
true,
1127+
TypeErrorRole::Elsewhere,
11161128
);
11171129
}
11181130
}

compiler/rustc_hir_typeck/src/method/confirm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
521521
// to the feature, like the self type can't reference method args.
522522
if self.tcx.features().arbitrary_self_types {
523523
self.err_ctxt()
524-
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
524+
.report_mismatched_self_types(&cause, method_self_ty, self_ty, terr)
525525
.emit();
526526
} else {
527527
// 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;
@@ -2336,6 +2337,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23362337
terr,
23372338
false,
23382339
false,
2340+
TypeErrorRole::Elsewhere,
23392341
);
23402342
diag.emit();
23412343
self.abort.set(true);

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

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

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

155182
pub fn report_mismatched_consts(
@@ -159,7 +186,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
159186
actual: ty::Const<'tcx>,
160187
err: TypeError<'tcx>,
161188
) -> 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+
)
163194
}
164195

165196
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
@@ -18,7 +18,7 @@ use rustc_type_ir::Upcast as _;
1818
use tracing::{debug, instrument};
1919

2020
use super::nice_region_error::find_anon_type;
21-
use super::ObligationCauseAsDiagArg;
21+
use super::{ObligationCauseAsDiagArg, TypeErrorRole};
2222
use crate::error_reporting::infer::ObligationCauseExt;
2323
use crate::error_reporting::TypeErrCtxt;
2424
use crate::errors::{
@@ -295,7 +295,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
295295
let mut err = match origin {
296296
infer::Subtype(box trace) => {
297297
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
298-
let mut err = self.report_and_explain_type_error(trace, terr);
298+
let mut err =
299+
self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
299300
match (*sub, *sup) {
300301
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
301302
(ty::RePlaceholder(_), _) => {
@@ -638,7 +639,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
638639
}
639640
infer::Subtype(box trace) => {
640641
let terr = TypeError::RegionsPlaceholderMismatch;
641-
return self.report_and_explain_type_error(trace, terr);
642+
return self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
642643
}
643644
_ => {
644645
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
@@ -35,7 +35,7 @@ use super::suggestions::get_explanation_based_on_obligation;
3535
use super::{
3636
ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst,
3737
};
38-
use crate::error_reporting::infer::TyCategory;
38+
use crate::error_reporting::infer::{TyCategory, TypeErrorRole};
3939
use crate::error_reporting::traits::report_object_safety_error;
4040
use crate::error_reporting::TypeErrCtxt;
4141
use crate::errors::{
@@ -667,6 +667,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
667667
TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
668668
false,
669669
false,
670+
TypeErrorRole::Elsewhere
670671
);
671672
diag
672673
}
@@ -1410,6 +1411,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
14101411
err,
14111412
true,
14121413
false,
1414+
TypeErrorRole::Elsewhere,
14131415
);
14141416
self.note_obligation_cause(&mut diag, obligation);
14151417
diag.emit()
@@ -2556,6 +2558,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
25562558
self.report_and_explain_type_error(
25572559
TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
25582560
terr,
2561+
TypeErrorRole::Elsewhere,
25592562
)
25602563
}
25612564

@@ -2653,6 +2656,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
26532656
found_trait_ref,
26542657
),
26552658
ty::error::TypeError::Mismatch,
2659+
TypeErrorRole::Elsewhere,
26562660
)
26572661
} else if found.len() == expected.len() {
26582662
self.report_closure_arg_mismatch(

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)