Skip to content

Commit f2cbbb9

Browse files
Rollup merge of #88218 - Aaron1011:missing-method-dyn, r=nagisa
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.
2 parents 891fa3c + 41f9f38 commit f2cbbb9

File tree

4 files changed

+23
-15
lines changed

4 files changed

+23
-15
lines changed

compiler/rustc_infer/src/traits/error_reporting/mod.rs

-6
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,5 @@ pub fn report_object_safety_error(
104104
to be resolvable dynamically; for more information visit \
105105
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
106106
);
107-
108-
if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) {
109-
// Avoid emitting error caused by non-existing method (#58734)
110-
err.cancel();
111-
}
112-
113107
err
114108
}

compiler/rustc_session/src/session.rs

-4
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,6 @@ pub struct Session {
189189
/// Cap lint level specified by a driver specifically.
190190
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
191191

192-
/// `Span`s of trait methods that weren't found to avoid emitting object safety errors
193-
pub trait_methods_not_found: Lock<FxHashSet<Span>>,
194-
195192
/// Mapping from ident span to path span for paths that don't exist as written, but that
196193
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
197194
pub confused_type_with_std_module: Lock<FxHashMap<Span, Span>>,
@@ -1326,7 +1323,6 @@ pub fn build_session(
13261323
print_fuel,
13271324
jobserver: jobserver::client(),
13281325
driver_lint_caps,
1329-
trait_methods_not_found: Lock::new(Default::default()),
13301326
confused_type_with_std_module: Lock::new(Default::default()),
13311327
ctfe_backtrace,
13321328
miri_unleashed_features: Lock::new(Default::default()),

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -858,13 +858,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
858858
path.segments,
859859
);
860860
}
861-
QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
861+
QPath::TypeRelative(ref qself, ref segment) => {
862+
// Don't use `self.to_ty`, since this will register a WF obligation.
863+
// If we're trying to call a non-existent method on a trait
864+
// (e.g. `MyTrait::missing_method`), then resolution will
865+
// give us a `QPath::TypeRelative` with a trait object as
866+
// `qself`. In that case, we want to avoid registering a WF obligation
867+
// for `dyn MyTrait`, since we don't actually need the trait
868+
// to be object-safe.
869+
// We manually call `register_wf_obligation` in the success path
870+
// below.
871+
(<dyn AstConv<'_>>::ast_ty_to_ty(self, qself), qself, segment)
872+
}
862873
QPath::LangItem(..) => {
863874
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
864875
}
865876
};
866877
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
867878
{
879+
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
868880
// Return directly on cache hit. This is useful to avoid doubly reporting
869881
// errors with default match binding modes. See #44614.
870882
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> {
878890
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
879891
_ => Err(ErrorReported),
880892
};
893+
894+
// If we have a path like `MyTrait::missing_method`, then don't register
895+
// a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise,
896+
// register a WF obligation so that we can detect any additional
897+
// errors in the self type.
898+
if !(matches!(error, method::MethodError::NoMatch(_)) && ty.is_trait()) {
899+
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
900+
}
881901
if item_name.name != kw::Empty {
882902
if let Some(mut e) = self.report_method_error(
883903
span,
@@ -895,6 +915,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895915

896916
if result.is_ok() {
897917
self.maybe_lint_bare_trait(qpath, hir_id);
918+
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
898919
}
899920

900921
// Write back the new resolution.

compiler/rustc_typeck/src/check/method/suggest.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7070

7171
pub fn report_method_error(
7272
&self,
73-
span: Span,
73+
mut span: Span,
7474
rcvr_ty: Ty<'tcx>,
7575
item_name: Ident,
7676
source: SelfSource<'tcx>,
7777
error: MethodError<'tcx>,
7878
args: Option<&'tcx [hir::Expr<'tcx>]>,
7979
) -> Option<DiagnosticBuilder<'_>> {
80-
let orig_span = span;
81-
let mut span = span;
8280
// Avoid suggestions when we don't know what's going on.
8381
if rcvr_ty.references_error() {
8482
return None;
@@ -545,7 +543,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
545543
} else {
546544
err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds"));
547545
}
548-
self.tcx.sess.trait_methods_not_found.borrow_mut().insert(orig_span);
549546
};
550547

551548
// If the method name is the name of a field with a function or closure type,

0 commit comments

Comments
 (0)