Use generics_of
instead of incorrectly inspecting FnSig
arguments
This commit is contained in:
parent
6b76d82b13
commit
5d1adbb629
@ -377,7 +377,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
err.span_label(pattern.span, msg);
|
||||
} else if let Some(e) = local_visitor.found_method_call {
|
||||
if let ExprKind::MethodCall(segment, ..) = &e.kind {
|
||||
// Suggest specifiying type params or point out the return type of the call.
|
||||
// Suggest specifiying type params or point out the return type of the call:
|
||||
//
|
||||
// error[E0282]: type annotations needed
|
||||
// --> $DIR/type-annotations-needed-expr.rs:2:39
|
||||
// |
|
||||
// LL | let _ = x.into_iter().sum() as f64;
|
||||
// | ^^^
|
||||
// | |
|
||||
// | cannot infer type for `S`
|
||||
// | help: consider specifying the type argument in
|
||||
// | the method call: `sum::<S>`
|
||||
// |
|
||||
// = note: type must be known at this point
|
||||
//
|
||||
// or
|
||||
//
|
||||
// error[E0282]: type annotations needed
|
||||
// --> $DIR/issue-65611.rs:59:20
|
||||
// |
|
||||
// LL | let x = buffer.last().unwrap().0.clone();
|
||||
// | -------^^^^--
|
||||
// | | |
|
||||
// | | cannot infer type for `T`
|
||||
// | this method call resolves to `std::option::Option<&T>`
|
||||
// |
|
||||
// = note: type must be known at this point
|
||||
self.annotate_method_call(segment, e, &mut err);
|
||||
}
|
||||
}
|
||||
@ -422,34 +447,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
&segment.args,
|
||||
) {
|
||||
let borrow = tables.borrow();
|
||||
let sigs = borrow.node_method_sig();
|
||||
if let Some(sig) = sigs.get(e.hir_id) {
|
||||
let mut params = vec![];
|
||||
for arg in sig.inputs_and_output().skip_binder().iter() {
|
||||
if let ty::Param(param) = arg.kind {
|
||||
if param.name != kw::SelfUpper {
|
||||
let name = param.name.to_string();
|
||||
if !params.contains(&name) {
|
||||
params.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !params.is_empty() {
|
||||
let method_defs = borrow.node_method_def_id();
|
||||
if let Some(did) = method_defs.get(e.hir_id) {
|
||||
let generics = self.tcx.generics_of(*did);
|
||||
if !generics.params.is_empty() {
|
||||
err.span_suggestion(
|
||||
segment.ident.span,
|
||||
&format!(
|
||||
"consider specifying the type argument{} in the method call",
|
||||
if params.len() > 1 {
|
||||
if generics.params.len() > 1 {
|
||||
"s"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
),
|
||||
format!("{}::<{}>", snippet, params.join(", ")),
|
||||
format!("{}::<{}>", snippet, generics.params.iter()
|
||||
.map(|p| p.name.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
} else {
|
||||
let sig = self.tcx.fn_sig(*did);
|
||||
err.span_label(e.span, &format!(
|
||||
"this method call resolves to `{:?}`",
|
||||
sig.output().skip_binder(),
|
||||
|
@ -338,7 +338,7 @@ pub struct TypeckTables<'tcx> {
|
||||
/// typeck::check::fn_ctxt for details.
|
||||
node_types: ItemLocalMap<Ty<'tcx>>,
|
||||
|
||||
node_method_sig: ItemLocalMap<ty::PolyFnSig<'tcx>>,
|
||||
node_method_def_id: ItemLocalMap<DefId>,
|
||||
|
||||
/// Stores the type parameters which were substituted to obtain the type
|
||||
/// of this node. This only applies to nodes that refer to entities
|
||||
@ -444,7 +444,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||
user_provided_types: Default::default(),
|
||||
user_provided_sigs: Default::default(),
|
||||
node_types: Default::default(),
|
||||
node_method_sig: Default::default(),
|
||||
node_method_def_id: Default::default(),
|
||||
node_substs: Default::default(),
|
||||
adjustments: Default::default(),
|
||||
pat_binding_modes: Default::default(),
|
||||
@ -545,17 +545,17 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_method_sig(&self) -> LocalTableInContext<'_, ty::PolyFnSig<'tcx>> {
|
||||
pub fn node_method_def_id(&self) -> LocalTableInContext<'_, DefId> {
|
||||
LocalTableInContext {
|
||||
local_id_root: self.local_id_root,
|
||||
data: &self.node_method_sig
|
||||
data: &self.node_method_def_id
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_method_sig_mut(&mut self) -> LocalTableInContextMut<'_, ty::PolyFnSig<'tcx>> {
|
||||
pub fn node_method_def_id_mut(&mut self) -> LocalTableInContextMut<'_, DefId> {
|
||||
LocalTableInContextMut {
|
||||
local_id_root: self.local_id_root,
|
||||
data: &mut self.node_method_sig
|
||||
data: &mut self.node_method_def_id
|
||||
}
|
||||
}
|
||||
|
||||
@ -765,7 +765,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||
ref user_provided_types,
|
||||
ref user_provided_sigs,
|
||||
ref node_types,
|
||||
ref node_method_sig,
|
||||
ref node_method_def_id,
|
||||
ref node_substs,
|
||||
ref adjustments,
|
||||
ref pat_binding_modes,
|
||||
@ -792,7 +792,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||
user_provided_types.hash_stable(hcx, hasher);
|
||||
user_provided_sigs.hash_stable(hcx, hasher);
|
||||
node_types.hash_stable(hcx, hasher);
|
||||
node_method_sig.hash_stable(hcx, hasher);
|
||||
node_method_def_id.hash_stable(hcx, hasher);
|
||||
node_substs.hash_stable(hcx, hasher);
|
||||
adjustments.hash_stable(hcx, hasher);
|
||||
pat_binding_modes.hash_stable(hcx, hasher);
|
||||
|
@ -871,7 +871,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
|
||||
Ok(method) => {
|
||||
let sig = self.tcx.fn_sig(method.def_id);
|
||||
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
|
||||
// trigger this codepath causing `structuraly_resolved_type` to emit an error.
|
||||
|
||||
@ -890,7 +889,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// |
|
||||
// = note: type must be known at this point
|
||||
// ```
|
||||
self.tables.borrow_mut().node_method_sig_mut().insert(expr.hir_id, sig);
|
||||
self.tables.borrow_mut().node_method_def_id_mut().insert(
|
||||
expr.hir_id,
|
||||
method.def_id,
|
||||
);
|
||||
|
||||
self.write_method_call(expr.hir_id, method);
|
||||
Ok(method)
|
||||
|
Loading…
x
Reference in New Issue
Block a user