Skip to content

Commit

Permalink
Add diagnostics while resolving self types.
Browse files Browse the repository at this point in the history
  • Loading branch information
adetaylor committed Sep 5, 2024
1 parent f13ebc7 commit 23db43a
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 19 deletions.
12 changes: 6 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_middle::ty::{
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::nice_region_error::NiceRegionError;
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::traits::query::type_op;
use rustc_trait_selection::traits::ObligationCtxt;
Expand Down Expand Up @@ -481,12 +482,11 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
.try_report_from_nll()
.or_else(|| {
if let SubregionOrigin::Subtype(trace) = cause {
Some(
infcx.err_ctxt().report_and_explain_type_error(
*trace,
TypeError::RegionsPlaceholderMismatch,
),
)
Some(infcx.err_ctxt().report_and_explain_type_error(
*trace,
TypeError::RegionsPlaceholderMismatch,
TypeErrorRole::Elsewhere,
))
} else {
None
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_middle::ty::{
};
use rustc_middle::{bug, span_bug};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::regions::InferCtxtRegionExt;
Expand Down Expand Up @@ -611,6 +612,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
terr,
false,
false,
TypeErrorRole::Elsewhere,
);
return Err(diag.emit());
}
Expand Down Expand Up @@ -1035,6 +1037,7 @@ fn report_trait_method_mismatch<'tcx>(
terr,
false,
false,
TypeErrorRole::Elsewhere,
);

return diag.emit();
Expand Down Expand Up @@ -1842,6 +1845,7 @@ fn compare_const_predicate_entailment<'tcx>(
terr,
false,
false,
TypeErrorRole::Elsewhere,
);
return Err(diag.emit());
};
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::error_reporting::infer::ObligationCauseExt as _;
use rustc_trait_selection::error_reporting::infer::{ObligationCauseExt as _, TypeErrorRole};
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::traits::ObligationCtxt;
Expand Down Expand Up @@ -655,6 +655,7 @@ pub fn check_function_signature<'tcx>(
err,
false,
false,
TypeErrorRole::Elsewhere,
);
return Err(diag.emit());
}
Expand Down
18 changes: 15 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{sym, Span, DUMMY_SP};
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
use rustc_trait_selection::error_reporting::infer::{
FailureCode, ObligationCauseExt, TypeErrorRole,
};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
use {rustc_ast as ast, rustc_hir as hir};
Expand Down Expand Up @@ -794,6 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
provided_arg_tys[mismatch_idx.into()].0,
),
terr,
TypeErrorRole::Elsewhere,
);
err.span_label(
full_call_span,
Expand Down Expand Up @@ -877,7 +880,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let trace =
mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) {
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *e);
let mut err = self.err_ctxt().report_and_explain_type_error(
trace,
*e,
TypeErrorRole::Elsewhere,
);
suggest_confusable(&mut err);
reported = Some(err.emit());
return false;
Expand Down Expand Up @@ -905,7 +912,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
let mut err = self.err_ctxt().report_and_explain_type_error(
trace,
*err,
TypeErrorRole::Elsewhere,
);
self.emit_coerce_suggestions(
&mut err,
provided_args[*provided_idx],
Expand Down Expand Up @@ -1081,6 +1092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
e,
false,
true,
TypeErrorRole::Elsewhere,
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// to the feature, like the self type can't reference method args.
if self.tcx.features().arbitrary_self_types {
self.err_ctxt()
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
.report_mismatched_self_types(&cause, method_self_ty, self_ty, terr)
.emit();
} else {
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{BytePos, Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::error_reporting::infer::TypeErrorRole;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
use rustc_trait_selection::traits::ObligationCtxt;
Expand Down Expand Up @@ -2359,6 +2360,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
terr,
false,
false,
TypeErrorRole::Elsewhere,
);
diag.emit();
self.abort.set(true);
Expand Down
57 changes: 53 additions & 4 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ pub mod nice_region_error;
pub mod region;
pub mod sub_relations;

/// A hint about where a type error occurred, for better diagnostics.
#[derive(Debug, PartialEq)]
pub enum TypeErrorRole {
/// This type error occurred while resolving the "self" type of a method
SelfType,
/// This type error occurred in any other context.
Elsewhere,
}

/// Makes a valid string literal from a string by escaping special characters (" and \),
/// unless they are already escaped.
fn escape_literal(s: &str) -> String {
Expand Down Expand Up @@ -148,7 +157,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'a> {
self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
self.report_and_explain_type_error(
TypeTrace::types(cause, true, expected, actual),
err,
TypeErrorRole::Elsewhere,
)
}

pub fn report_mismatched_self_types(
&self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'a> {
self.report_and_explain_type_error(
TypeTrace::types(cause, true, expected, actual),
err,
TypeErrorRole::SelfType,
)
}

pub fn report_mismatched_consts(
Expand All @@ -158,7 +185,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'a> {
self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
self.report_and_explain_type_error(
TypeTrace::consts(cause, true, expected, actual),
err,
TypeErrorRole::Elsewhere,
)
}

pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
Expand Down Expand Up @@ -1140,6 +1171,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
terr: TypeError<'tcx>,
swap_secondary_and_primary: bool,
prefer_label: bool,
role: TypeErrorRole,
) {
let span = cause.span();

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

self.check_and_note_conflicting_crates(diag, terr);

if role == TypeErrorRole::SelfType {
diag.note("this error occurred while resolving the `self` type of this method call");
}

self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
if let Some(exp_found) = exp_found
&& let exp_found = TypeError::Sorts(exp_found)
Expand Down Expand Up @@ -1783,8 +1819,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&self,
trace: TypeTrace<'tcx>,
terr: TypeError<'tcx>,
role: TypeErrorRole,
) -> Diag<'a> {
debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
debug!(
"report_and_explain_type_error(trace={:?}, terr={:?}, role={:?})",
trace, terr, role
);

let span = trace.cause.span();
let failure_code = trace.cause.as_failure_code_diag(
Expand All @@ -1793,7 +1833,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
self.type_error_additional_suggestions(&trace, terr),
);
let mut diag = self.dcx().create_err(failure_code);
self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false);
self.note_type_err(
&mut diag,
&trace.cause,
None,
Some(trace.values),
terr,
false,
false,
role,
);
diag
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol};
use rustc_type_ir::Upcast as _;

use super::nice_region_error::find_anon_type;
use super::ObligationCauseAsDiagArg;
use super::{ObligationCauseAsDiagArg, TypeErrorRole};
use crate::error_reporting::infer::ObligationCauseExt;
use crate::error_reporting::TypeErrCtxt;
use crate::errors::{
Expand Down Expand Up @@ -294,7 +294,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let mut err = match origin {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, terr);
let mut err =
self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
match (*sub, *sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
Expand Down Expand Up @@ -637,7 +638,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
infer::Subtype(box trace) => {
let terr = TypeError::RegionsPlaceholderMismatch;
return self.report_and_explain_type_error(trace, terr);
return self.report_and_explain_type_error(trace, terr, TypeErrorRole::Elsewhere);
}
_ => {
return self.report_concrete_failure(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use super::suggestions::get_explanation_based_on_obligation;
use super::{
ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst,
};
use crate::error_reporting::infer::TyCategory;
use crate::error_reporting::infer::{TyCategory, TypeErrorRole};
use crate::error_reporting::traits::report_object_safety_error;
use crate::error_reporting::TypeErrCtxt;
use crate::errors::{
Expand Down Expand Up @@ -666,6 +666,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
false,
false,
TypeErrorRole::Elsewhere
);
diag
}
Expand Down Expand Up @@ -1409,6 +1410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err,
true,
false,
TypeErrorRole::Elsewhere,
);
self.note_obligation_cause(&mut diag, obligation);
diag.emit()
Expand Down Expand Up @@ -2555,6 +2557,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
self.report_and_explain_type_error(
TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
terr,
TypeErrorRole::Elsewhere,
)
}

Expand Down Expand Up @@ -2652,6 +2655,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
found_trait_ref,
),
ty::error::TypeError::Mismatch,
TypeErrorRole::Elsewhere,
)
} else if found.len() == expected.len() {
self.report_closure_arg_mismatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | smart_ptr.a::<SmartPtr2<Foo>>();
|
= note: expected struct `SmartPtr2<'_, Foo>`
found struct `SmartPtr<'_, Foo>`
= note: this error occurred while resolving the `self` type of this method call

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

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | foo.get::<std::rc::Rc<Foo>>();
|
= note: expected struct `Rc<Foo>`
found struct `Foo`
= note: this error occurred while resolving the `self` type of this method call

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error[E0308]: mismatched types
|
LL | foo.get::<&Foo>();
| ^^^ expected `&Foo`, found `Foo`
|
= note: this error occurred while resolving the `self` type of this method call

error: aborting due to 1 previous error

Expand Down

0 comments on commit 23db43a

Please sign in to comment.