Remove Session.trait_methods_not_found
Instead, avoid registering the problematic well-formed obligation to begin with. This removes global untracked mutable state, and avoids potential issues with incremental compilation.
This commit is contained in:
parent
b6e334d873
commit
41f9f38d6e
|
@ -104,11 +104,5 @@ pub fn report_object_safety_error(
|
|||
to be resolvable dynamically; for more information visit \
|
||||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
err.cancel();
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
|
|
@ -189,9 +189,6 @@ pub struct Session {
|
|||
/// Cap lint level specified by a driver specifically.
|
||||
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||
|
||||
/// `Span`s of trait methods that weren't found to avoid emitting object safety errors
|
||||
pub trait_methods_not_found: Lock<FxHashSet<Span>>,
|
||||
|
||||
/// Mapping from ident span to path span for paths that don't exist as written, but that
|
||||
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
|
||||
pub confused_type_with_std_module: Lock<FxHashMap<Span, Span>>,
|
||||
|
@ -1353,7 +1350,6 @@ pub fn build_session(
|
|||
print_fuel,
|
||||
jobserver: jobserver::client(),
|
||||
driver_lint_caps,
|
||||
trait_methods_not_found: Lock::new(Default::default()),
|
||||
confused_type_with_std_module: Lock::new(Default::default()),
|
||||
ctfe_backtrace,
|
||||
miri_unleashed_features: Lock::new(Default::default()),
|
||||
|
|
|
@ -858,13 +858,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
path.segments,
|
||||
);
|
||||
}
|
||||
QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
|
||||
QPath::TypeRelative(ref qself, ref segment) => {
|
||||
// Don't use `self.to_ty`, since this will register a WF obligation.
|
||||
// If we're trying to call a non-existent method on a trait
|
||||
// (e.g. `MyTrait::missing_method`), then resolution will
|
||||
// give us a `QPath::TypeRelative` with a trait object as
|
||||
// `qself`. In that case, we want to avoid registering a WF obligation
|
||||
// for `dyn MyTrait`, since we don't actually need the trait
|
||||
// to be object-safe.
|
||||
// We manually call `register_wf_obligation` in the success path
|
||||
// below.
|
||||
(<dyn AstConv<'_>>::ast_ty_to_ty(self, qself), qself, segment)
|
||||
}
|
||||
QPath::LangItem(..) => {
|
||||
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
|
||||
}
|
||||
};
|
||||
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
|
||||
{
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
// Return directly on cache hit. This is useful to avoid doubly reporting
|
||||
// errors with default match binding modes. See #44614.
|
||||
let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id));
|
||||
|
@ -878,6 +890,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
|
||||
_ => Err(ErrorReported),
|
||||
};
|
||||
|
||||
// If we have a path like `MyTrait::missing_method`, then don't register
|
||||
// a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise,
|
||||
// register a WF obligation so that we can detect any additional
|
||||
// errors in the self type.
|
||||
if !(matches!(error, method::MethodError::NoMatch(_)) && ty.is_trait()) {
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
}
|
||||
if item_name.name != kw::Empty {
|
||||
if let Some(mut e) = self.report_method_error(
|
||||
span,
|
||||
|
@ -895,6 +915,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
if result.is_ok() {
|
||||
self.maybe_lint_bare_trait(qpath, hir_id);
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
}
|
||||
|
||||
// Write back the new resolution.
|
||||
|
|
|
@ -70,15 +70,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
pub fn report_method_error(
|
||||
&self,
|
||||
span: Span,
|
||||
mut span: Span,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: Ident,
|
||||
source: SelfSource<'tcx>,
|
||||
error: MethodError<'tcx>,
|
||||
args: Option<&'tcx [hir::Expr<'tcx>]>,
|
||||
) -> Option<DiagnosticBuilder<'_>> {
|
||||
let orig_span = span;
|
||||
let mut span = span;
|
||||
// Avoid suggestions when we don't know what's going on.
|
||||
if rcvr_ty.references_error() {
|
||||
return None;
|
||||
|
@ -545,7 +543,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
|
||||
}
|
||||
self.tcx.sess.trait_methods_not_found.borrow_mut().insert(orig_span);
|
||||
};
|
||||
|
||||
// If the method name is the name of a field with a function or closure type,
|
||||
|
|
Loading…
Reference in a new issue