Skip to content

Commit 5d1adbb

Browse files
committed
Use generics_of instead of incorrectly inspecting FnSig arguments
1 parent 6b76d82 commit 5d1adbb

File tree

3 files changed

+48
-27
lines changed

3 files changed

+48
-27
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
377377
err.span_label(pattern.span, msg);
378378
} else if let Some(e) = local_visitor.found_method_call {
379379
if let ExprKind::MethodCall(segment, ..) = &e.kind {
380-
// Suggest specifiying type params or point out the return type of the call.
380+
// Suggest specifiying type params or point out the return type of the call:
381+
//
382+
// error[E0282]: type annotations needed
383+
// --> $DIR/type-annotations-needed-expr.rs:2:39
384+
// |
385+
// LL | let _ = x.into_iter().sum() as f64;
386+
// | ^^^
387+
// | |
388+
// | cannot infer type for `S`
389+
// | help: consider specifying the type argument in
390+
// | the method call: `sum::<S>`
391+
// |
392+
// = note: type must be known at this point
393+
//
394+
// or
395+
//
396+
// error[E0282]: type annotations needed
397+
// --> $DIR/issue-65611.rs:59:20
398+
// |
399+
// LL | let x = buffer.last().unwrap().0.clone();
400+
// | -------^^^^--
401+
// | | |
402+
// | | cannot infer type for `T`
403+
// | this method call resolves to `std::option::Option<&T>`
404+
// |
405+
// = note: type must be known at this point
381406
self.annotate_method_call(segment, e, &mut err);
382407
}
383408
}
@@ -422,34 +447,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
422447
&segment.args,
423448
) {
424449
let borrow = tables.borrow();
425-
let sigs = borrow.node_method_sig();
426-
if let Some(sig) = sigs.get(e.hir_id) {
427-
let mut params = vec![];
428-
for arg in sig.inputs_and_output().skip_binder().iter() {
429-
if let ty::Param(param) = arg.kind {
430-
if param.name != kw::SelfUpper {
431-
let name = param.name.to_string();
432-
if !params.contains(&name) {
433-
params.push(name);
434-
}
435-
}
436-
}
437-
}
438-
if !params.is_empty() {
450+
let method_defs = borrow.node_method_def_id();
451+
if let Some(did) = method_defs.get(e.hir_id) {
452+
let generics = self.tcx.generics_of(*did);
453+
if !generics.params.is_empty() {
439454
err.span_suggestion(
440455
segment.ident.span,
441456
&format!(
442457
"consider specifying the type argument{} in the method call",
443-
if params.len() > 1 {
458+
if generics.params.len() > 1 {
444459
"s"
445460
} else {
446461
""
447462
},
448463
),
449-
format!("{}::<{}>", snippet, params.join(", ")),
464+
format!("{}::<{}>", snippet, generics.params.iter()
465+
.map(|p| p.name.to_string())
466+
.collect::<Vec<String>>()
467+
.join(", ")),
450468
Applicability::HasPlaceholders,
451469
);
452470
} else {
471+
let sig = self.tcx.fn_sig(*did);
453472
err.span_label(e.span, &format!(
454473
"this method call resolves to `{:?}`",
455474
sig.output().skip_binder(),

src/librustc/ty/context.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ pub struct TypeckTables<'tcx> {
338338
/// typeck::check::fn_ctxt for details.
339339
node_types: ItemLocalMap<Ty<'tcx>>,
340340

341-
node_method_sig: ItemLocalMap<ty::PolyFnSig<'tcx>>,
341+
node_method_def_id: ItemLocalMap<DefId>,
342342

343343
/// Stores the type parameters which were substituted to obtain the type
344344
/// of this node. This only applies to nodes that refer to entities
@@ -444,7 +444,7 @@ impl<'tcx> TypeckTables<'tcx> {
444444
user_provided_types: Default::default(),
445445
user_provided_sigs: Default::default(),
446446
node_types: Default::default(),
447-
node_method_sig: Default::default(),
447+
node_method_def_id: Default::default(),
448448
node_substs: Default::default(),
449449
adjustments: Default::default(),
450450
pat_binding_modes: Default::default(),
@@ -545,17 +545,17 @@ impl<'tcx> TypeckTables<'tcx> {
545545
}
546546
}
547547

548-
pub fn node_method_sig(&self) -> LocalTableInContext<'_, ty::PolyFnSig<'tcx>> {
548+
pub fn node_method_def_id(&self) -> LocalTableInContext<'_, DefId> {
549549
LocalTableInContext {
550550
local_id_root: self.local_id_root,
551-
data: &self.node_method_sig
551+
data: &self.node_method_def_id
552552
}
553553
}
554554

555-
pub fn node_method_sig_mut(&mut self) -> LocalTableInContextMut<'_, ty::PolyFnSig<'tcx>> {
555+
pub fn node_method_def_id_mut(&mut self) -> LocalTableInContextMut<'_, DefId> {
556556
LocalTableInContextMut {
557557
local_id_root: self.local_id_root,
558-
data: &mut self.node_method_sig
558+
data: &mut self.node_method_def_id
559559
}
560560
}
561561

@@ -765,7 +765,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
765765
ref user_provided_types,
766766
ref user_provided_sigs,
767767
ref node_types,
768-
ref node_method_sig,
768+
ref node_method_def_id,
769769
ref node_substs,
770770
ref adjustments,
771771
ref pat_binding_modes,
@@ -792,7 +792,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
792792
user_provided_types.hash_stable(hcx, hasher);
793793
user_provided_sigs.hash_stable(hcx, hasher);
794794
node_types.hash_stable(hcx, hasher);
795-
node_method_sig.hash_stable(hcx, hasher);
795+
node_method_def_id.hash_stable(hcx, hasher);
796796
node_substs.hash_stable(hcx, hasher);
797797
adjustments.hash_stable(hcx, hasher);
798798
pat_binding_modes.hash_stable(hcx, hasher);

src/librustc_typeck/check/expr.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
871871

872872
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
873873
Ok(method) => {
874-
let sig = self.tcx.fn_sig(method.def_id);
875874
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
876875
// trigger this codepath causing `structuraly_resolved_type` to emit an error.
877876

@@ -890,7 +889,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
890889
// |
891890
// = note: type must be known at this point
892891
// ```
893-
self.tables.borrow_mut().node_method_sig_mut().insert(expr.hir_id, sig);
892+
self.tables.borrow_mut().node_method_def_id_mut().insert(
893+
expr.hir_id,
894+
method.def_id,
895+
);
894896

895897
self.write_method_call(expr.hir_id, method);
896898
Ok(method)

0 commit comments

Comments
 (0)