From 15f6540ec02a6e1c556f0a915c494d8a45ea9338 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 21 Aug 2017 16:44:42 +0300 Subject: [PATCH] resolve type vars with obligations in more places This fixes a few cases of inference misses, some of them regressions caused by the impl selected for a method not being immediately evaluated. --- src/librustc_typeck/check/mod.rs | 2 + ...thod-argument-inference-associated-type.rs | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/test/run-pass/method-argument-inference-associated-type.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0427727269607..e937770bb0161 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2818,6 +2818,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { formal_ret: Ty<'tcx>, formal_args: &[Ty<'tcx>]) -> Vec> { + let formal_ret = self.resolve_type_vars_with_obligations(formal_ret); let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| { self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || { // Attempt to apply a subtyping relationship between the formal @@ -3978,6 +3979,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } hir::ExprTup(ref elts) => { let flds = expected.only_has_type(self).and_then(|ty| { + let ty = self.resolve_type_vars_with_obligations(ty); match ty.sty { ty::TyTuple(ref flds, _) => Some(&flds[..]), _ => None diff --git a/src/test/run-pass/method-argument-inference-associated-type.rs b/src/test/run-pass/method-argument-inference-associated-type.rs new file mode 100644 index 0000000000000..76b8cf92329d1 --- /dev/null +++ b/src/test/run-pass/method-argument-inference-associated-type.rs @@ -0,0 +1,37 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct ClientMap; +pub struct ClientMap2; + +pub trait Service { + type Request; + fn call(&self, _req: Self::Request); +} + +pub struct S(T); + +impl Service for ClientMap { + type Request = S>; + fn call(&self, _req: Self::Request) {} +} + + +impl Service for ClientMap2 { + type Request = (Box,); + fn call(&self, _req: Self::Request) {} +} + + +fn main() { + ClientMap.call(S { 0: Box::new(|_msgid| ()) }); + ClientMap.call(S(Box::new(|_msgid| ()))); + ClientMap2.call((Box::new(|_msgid| ()),)); +}