diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-15 23:59:25 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-15 23:59:25 +0300 |
| commit | 3725cab5ac1cb6a32b59b7731ce1d6e114c0ae00 (patch) | |
| tree | a6c1e706621a7acc7b572b1d13c29aa2d390852d | |
| parent | 516570f2d6b2246cf2ae0269a201bd6a62c91881 (diff) | |
| download | rust-3725cab5ac1cb6a32b59b7731ce1d6e114c0ae00.tar.gz rust-3725cab5ac1cb6a32b59b7731ce1d6e114c0ae00.zip | |
rustc_typeck: return InferOk from lookup_method_in_trait_adjusted.
| -rw-r--r-- | src/librustc_typeck/check/autoderef.rs | 17 | ||||
| -rw-r--r-- | src/librustc_typeck/check/callee.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/confirm.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/mod.rs | 46 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 22 | ||||
| -rw-r--r-- | src/librustc_typeck/check/op.rs | 17 |
6 files changed, 67 insertions, 41 deletions
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index bfb69d620ac..92fb02c6379 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -158,11 +158,16 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { -> InferOk<'tcx, ()> where E: AsCoercionSite { - let methods: Vec<_> = self.steps + let Autoderef { fcx, span, mut obligations, steps, .. } = self; + let methods: Vec<_> = steps .iter() .map(|&(ty, kind)| { if let AutoderefKind::Overloaded = kind { - self.fcx.try_overloaded_deref(self.span, None, ty, pref) + fcx.try_overloaded_deref(span, None, ty, pref) + .map(|InferOk { value, obligations: o }| { + obligations.extend(o); + value + }) } else { None } @@ -172,7 +177,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { debug!("finalize({:?}) - {:?},{:?}", pref, methods, - self.obligations); + obligations); for expr in exprs { let expr = expr.as_coercion_site(); @@ -180,14 +185,14 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { for (n, method) in methods.iter().enumerate() { if let &Some(method) = method { let method_call = MethodCall::autoderef(expr.id, n as u32); - self.fcx.tables.borrow_mut().method_map.insert(method_call, method); + fcx.tables.borrow_mut().method_map.insert(method_call, method); } } } InferOk { value: (), - obligations: self.obligations + obligations } } } @@ -209,7 +214,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { base_expr: Option<&hir::Expr>, base_ty: Ty<'tcx>, lvalue_pref: LvaluePreference) - -> Option<MethodCallee<'tcx>> { + -> Option<InferOk<'tcx, MethodCallee<'tcx>>> { debug!("try_overloaded_deref({:?},{:?},{:?},{:?})", span, base_expr, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 70e585bd14f..32f130aca1c 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -173,7 +173,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { adjusted_ty, None) { None => continue, - Some(method_callee) => { + Some(ok) => { + let method_callee = self.register_infer_ok_obligations(ok); return Some(method_callee); } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index e64ad775d52..26ba965fe5c 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -543,7 +543,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { Some(&base_expr), self.node_ty(base_expr.id), PreferMutLvalue); - let method = method.expect("re-trying deref failed"); + let ok = method.expect("re-trying deref failed"); + let method = self.register_infer_ok_obligations(ok); self.tables.borrow_mut().method_map.insert(method_call, method); } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 9ecf0ffa71e..7dd2699a6ea 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -17,7 +17,8 @@ use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; -use rustc::infer; +use rustc::ty::subst::Subst; +use rustc::infer::{self, InferOk}; use syntax::ast; use syntax_pos::Span; @@ -159,7 +160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { trait_def_id: DefId, self_ty: ty::Ty<'tcx>, opt_input_types: Option<Vec<ty::Ty<'tcx>>>) - -> Option<ty::MethodCallee<'tcx>> { + -> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> { self.lookup_method_in_trait_adjusted(span, self_expr, m_name, @@ -190,7 +191,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { unsize: bool, self_ty: ty::Ty<'tcx>, opt_input_types: Option<Vec<ty::Ty<'tcx>>>) - -> Option<ty::MethodCallee<'tcx>> { + -> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> { debug!("lookup_in_trait_adjusted(self_ty={:?}, self_expr={:?}, \ m_name={}, trait_def_id={:?})", self_ty, @@ -236,6 +237,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert_eq!(generics.regions.len(), 0); debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); + let mut obligations = vec![]; // Instantiate late-bound regions and substitute the trait // parameters into the method type to get the actual method type. @@ -248,10 +250,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fn_sig = self.replace_late_bound_regions_with_fresh_var(span, infer::FnCall, &fn_sig).0; - let fn_sig = self.instantiate_type_scheme(span, trait_ref.substs, &fn_sig); + let fn_sig = fn_sig.subst(self.tcx, substs); + let fn_sig = match self.normalize_associated_types_in_as_infer_ok(span, &fn_sig) { + InferOk { value, obligations: o } => { + obligations.extend(o); + value + } + }; let transformed_self_ty = fn_sig.inputs()[0]; - let method_ty = tcx.mk_fn_def(def_id, trait_ref.substs, - ty::Binder(fn_sig)); + let method_ty = tcx.mk_fn_def(def_id, substs, ty::Binder(fn_sig)); debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}", method_ty, @@ -265,18 +272,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // // Note that as the method comes from a trait, it should not have // any late-bound regions appearing in its bounds. - let method_bounds = self.instantiate_bounds(span, def_id, trait_ref.substs); - assert!(!method_bounds.has_escaping_regions()); - self.add_obligations_for_parameters(traits::ObligationCause::misc(span, self.body_id), - &method_bounds); + let bounds = self.tcx.item_predicates(def_id).instantiate(self.tcx, substs); + let bounds = match self.normalize_associated_types_in_as_infer_ok(span, &bounds) { + InferOk { value, obligations: o } => { + obligations.extend(o); + value + } + }; + assert!(!bounds.has_escaping_regions()); - // Also register an obligation for the method type being well-formed. - self.register_wf_obligation(method_ty, span, traits::MiscObligation); + let cause = traits::ObligationCause::misc(span, self.body_id); + obligations.extend(traits::predicates_for_generics(cause.clone(), &bounds)); - // FIXME(#18653) -- Try to resolve obligations, giving us more - // typing information, which can sometimes be needed to avoid - // pathological region inference failures. - self.select_obligations_where_possible(); + // Also add an obligation for the method type being well-formed. + obligations.push(traits::Obligation::new(cause, ty::Predicate::WellFormed(method_ty))); // Insert any adjustments needed (always an autoref of some mutability). if let Some(self_expr) = self_expr { @@ -317,7 +326,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("callee = {:?}", callee); - Some(callee) + Some(InferOk { + obligations, + value: callee + }) } pub fn resolve_ufcs(&self, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2e69ad4cc61..8b40cb140ae 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1749,14 +1749,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { -> ty::InstantiatedPredicates<'tcx> { let bounds = self.tcx.item_predicates(def_id); let result = bounds.instantiate(self.tcx, substs); - let result = self.normalize_associated_types_in(span, &result.predicates); + let result = self.normalize_associated_types_in(span, &result); debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}", bounds, substs, result); - ty::InstantiatedPredicates { - predicates: result - } + result } /// Replace all anonymized types with fresh inference variables @@ -1799,7 +1797,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T where T : TypeFoldable<'tcx> { - self.inh.normalize_associated_types_in(span, self.body_id, value) + let ok = self.normalize_associated_types_in_as_infer_ok(span, value); + self.register_infer_ok_obligations(ok) + } + + fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T) + -> InferOk<'tcx, T> + where T : TypeFoldable<'tcx> + { + self.inh.normalize_associated_types_in_as_infer_ok(span, self.body_id, value) } pub fn write_nil(&self, node_id: ast::NodeId) { @@ -2171,8 +2177,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If some lookup succeeds, write callee into table and extract index/element // type from the method signature. // If some lookup succeeded, install method in table - method.map(|method| { + method.map(|ok| { debug!("try_index_step: success, using overloaded indexing"); + let method = self.register_infer_ok_obligations(ok); self.tables.borrow_mut().method_map.insert(method_call, method); (input_ty, self.make_overloaded_lvalue_return_type(method).ty) }) @@ -3302,8 +3309,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) { oprnd_t = mt.ty; - } else if let Some(method) = self.try_overloaded_deref( + } else if let Some(ok) = self.try_overloaded_deref( expr.span, Some(&oprnd), oprnd_t, lvalue_pref) { + let method = self.register_infer_ok_obligations(ok); oprnd_t = self.make_overloaded_lvalue_return_type(method).ty; self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id), method); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index cc33bd8754d..5b174aaf895 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -398,20 +398,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let method = match trait_did { Some(trait_did) => { - self.lookup_method_in_trait_adjusted(expr.span, - Some(lhs_expr), - opname, - trait_did, - 0, - false, - lhs_ty, - Some(other_tys)) + self.lookup_method_in_trait(expr.span, + Some(lhs_expr), + opname, + trait_did, + lhs_ty, + Some(other_tys)) } None => None }; match method { - Some(method) => { + Some(ok) => { + let method = self.register_infer_ok_obligations(ok); let method_ty = method.ty; // HACK(eddyb) Fully qualified path to work around a resolve bug. |
