1
Fork 0

Delay function resolution error until typeck

This commit is contained in:
Michael Goulet 2022-10-05 05:35:34 +00:00
parent d4846f9d03
commit 66c8c5ad1d
35 changed files with 396 additions and 369 deletions

View file

@ -460,6 +460,7 @@ pub enum StashKey {
ItemNoType,
UnderscoreForArrayLengths,
EarlySyntaxWarning,
CallIntoMethod,
}
fn default_track_diagnostic(_: &Diagnostic) {}

View file

@ -2,7 +2,7 @@ use super::method::MethodCallee;
use super::{DefIdOrName, Expectation, FnCtxt, TupleArgumentsFlag};
use crate::type_error_struct;
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
use rustc_errors::{struct_span_err, Applicability, Diagnostic, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{self, Namespace, Res};
use rustc_hir::def_id::DefId;
@ -60,6 +60,7 @@ pub fn check_legal_trait_for_method_call(
}
}
#[derive(Debug)]
enum CallStep<'tcx> {
Builtin(Ty<'tcx>),
DeferredClosure(LocalDefId, ty::FnSig<'tcx>),
@ -188,6 +189,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return None;
}
ty::Error(_) => {
return None;
}
_ => {}
}
@ -394,6 +399,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ty::FnPtr(sig) => (sig, None),
_ => {
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &callee_expr.kind
&& let [segment] = path.segments
&& let Some(mut diag) = self
.tcx
.sess
.diagnostic()
.steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod)
{
diag.emit();
}
self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
// This is the "default" function signature, used in case of error.

View file

@ -120,7 +120,7 @@ impl<'a> Resolver<'a> {
}
fn report_with_use_injections(&mut self, krate: &Crate) {
for UseError { mut err, candidates, def_id, instead, suggestion, path } in
for UseError { mut err, candidates, def_id, instead, suggestion, path, is_call } in
self.use_injections.drain(..)
{
let (span, found_use) = if let Some(def_id) = def_id.as_local() {
@ -128,6 +128,7 @@ impl<'a> Resolver<'a> {
} else {
(None, FoundUse::No)
};
if !candidates.is_empty() {
show_candidates(
&self.session,
@ -140,10 +141,15 @@ impl<'a> Resolver<'a> {
IsPattern::No,
path,
);
err.emit();
} else if let Some((span, msg, sugg, appl)) = suggestion {
err.span_suggestion(span, msg, sugg, appl);
err.emit();
} else if let [segment] = path.as_slice() && is_call {
err.stash(segment.ident.span, rustc_errors::StashKey::CallIntoMethod);
} else {
err.emit();
}
err.emit();
}
}

View file

@ -3263,6 +3263,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
instead,
suggestion,
path: path.into(),
is_call: source.is_call(),
});
}
@ -3327,6 +3328,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
instead: false,
suggestion: None,
path: path.into(),
is_call: source.is_call(),
});
} else {
err.cancel();

View file

@ -674,6 +674,8 @@ struct UseError<'a> {
/// Path `Segment`s at the place of use that failed. Used for accurate suggestion after telling
/// the user to import the item directly.
path: Vec<Segment>,
/// Whether the expected source is a call
is_call: bool,
}
#[derive(Clone, Copy, PartialEq, Debug)]