Skip to content

Commit 1827d52

Browse files
committed
rustc_typeck: Implement resolution advised in issue 45510.
When resolving Fn traits, the compiler failed to take into account overloaded implementations. To resolve this, we inform the trait dispatch code that the arguments will becoming as a tuple of correct arity.
1 parent 6de9c13 commit 1827d52

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/librustc_typeck/check/callee.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use hir::def_id::{DefId, LOCAL_CRATE};
88
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
99
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
1010
use rustc::{infer, traits};
11+
use rustc::infer::type_variable::TypeVariableOrigin;
1112
use rustc_target::spec::abi;
1213
use syntax::ast::Ident;
1314
use syntax_pos::Span;
@@ -46,7 +47,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4647
let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
4748
let mut result = None;
4849
while result.is_none() && autoderef.next().is_some() {
49-
result = self.try_overloaded_call_step(call_expr, callee_expr, &autoderef);
50+
result = self.try_overloaded_call_step(call_expr, callee_expr, arg_exprs, &autoderef);
5051
}
5152
autoderef.finalize(self);
5253

@@ -79,6 +80,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
7980
&self,
8081
call_expr: &'gcx hir::Expr,
8182
callee_expr: &'gcx hir::Expr,
83+
arg_exprs: &'gcx [hir::Expr],
8284
autoderef: &Autoderef<'a, 'gcx, 'tcx>,
8385
) -> Option<CallStep<'tcx>> {
8486
let adjusted_ty = autoderef.unambiguous_final_ty(self);
@@ -142,7 +144,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
142144
_ => {}
143145
}
144146

145-
self.try_overloaded_call_traits(call_expr, adjusted_ty)
147+
self.try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs))
146148
.map(|(autoref, method)| {
147149
let mut adjustments = autoderef.adjust_steps(self, Needs::None);
148150
adjustments.extend(autoref);
@@ -155,6 +157,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
155157
&self,
156158
call_expr: &hir::Expr,
157159
adjusted_ty: Ty<'tcx>,
160+
opt_arg_exprs: Option<&'gcx [hir::Expr]>,
158161
) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> {
159162
// Try the options that are least restrictive on the caller first.
160163
for &(opt_trait_def_id, method_name, borrow) in &[
@@ -179,12 +182,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
179182
None => continue,
180183
};
181184

185+
let opt_input_types = opt_arg_exprs.map(|arg_exprs| [self.tcx.mk_tup(
186+
arg_exprs
187+
.iter()
188+
.map(|e| self.next_ty_var(
189+
TypeVariableOrigin::TypeInference(e.span)
190+
))
191+
)]);
192+
let opt_input_types = opt_input_types.as_ref().map(AsRef::as_ref);
193+
182194
if let Some(ok) = self.lookup_method_in_trait(
183195
call_expr.span,
184196
method_name,
185197
trait_def_id,
186198
adjusted_ty,
187-
None,
199+
opt_input_types,
188200
) {
189201
let method = self.register_infer_ok_obligations(ok);
190202
let mut autoref = None;
@@ -445,7 +457,7 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> {
445457
.is_some());
446458

447459
// We may now know enough to figure out fn vs fnmut etc.
448-
match fcx.try_overloaded_call_traits(self.call_expr, self.adjusted_ty) {
460+
match fcx.try_overloaded_call_traits(self.call_expr, self.adjusted_ty, None) {
449461
Some((autoref, method_callee)) => {
450462
// One problem is that when we get here, we are going
451463
// to have a newly instantiated function signature

0 commit comments

Comments
 (0)