Delay function resolution error until typeck
This commit is contained in:
parent
d4846f9d03
commit
66c8c5ad1d
35 changed files with 396 additions and 369 deletions
|
@ -460,6 +460,7 @@ pub enum StashKey {
|
|||
ItemNoType,
|
||||
UnderscoreForArrayLengths,
|
||||
EarlySyntaxWarning,
|
||||
CallIntoMethod,
|
||||
}
|
||||
|
||||
fn default_track_diagnostic(_: &Diagnostic) {}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue