Skip to content

Commit 3725cab

Browse files
committed
rustc_typeck: return InferOk from lookup_method_in_trait_adjusted.
1 parent 516570f commit 3725cab

File tree

6 files changed

+67
-41
lines changed

6 files changed

+67
-41
lines changed

src/librustc_typeck/check/autoderef.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,16 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
158158
-> InferOk<'tcx, ()>
159159
where E: AsCoercionSite
160160
{
161-
let methods: Vec<_> = self.steps
161+
let Autoderef { fcx, span, mut obligations, steps, .. } = self;
162+
let methods: Vec<_> = steps
162163
.iter()
163164
.map(|&(ty, kind)| {
164165
if let AutoderefKind::Overloaded = kind {
165-
self.fcx.try_overloaded_deref(self.span, None, ty, pref)
166+
fcx.try_overloaded_deref(span, None, ty, pref)
167+
.map(|InferOk { value, obligations: o }| {
168+
obligations.extend(o);
169+
value
170+
})
166171
} else {
167172
None
168173
}
@@ -172,22 +177,22 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
172177
debug!("finalize({:?}) - {:?},{:?}",
173178
pref,
174179
methods,
175-
self.obligations);
180+
obligations);
176181

177182
for expr in exprs {
178183
let expr = expr.as_coercion_site();
179184
debug!("finalize - finalizing #{} - {:?}", expr.id, expr);
180185
for (n, method) in methods.iter().enumerate() {
181186
if let &Some(method) = method {
182187
let method_call = MethodCall::autoderef(expr.id, n as u32);
183-
self.fcx.tables.borrow_mut().method_map.insert(method_call, method);
188+
fcx.tables.borrow_mut().method_map.insert(method_call, method);
184189
}
185190
}
186191
}
187192

188193
InferOk {
189194
value: (),
190-
obligations: self.obligations
195+
obligations
191196
}
192197
}
193198
}
@@ -209,7 +214,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
209214
base_expr: Option<&hir::Expr>,
210215
base_ty: Ty<'tcx>,
211216
lvalue_pref: LvaluePreference)
212-
-> Option<MethodCallee<'tcx>> {
217+
-> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
213218
debug!("try_overloaded_deref({:?},{:?},{:?},{:?})",
214219
span,
215220
base_expr,

src/librustc_typeck/check/callee.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
173173
adjusted_ty,
174174
None) {
175175
None => continue,
176-
Some(method_callee) => {
176+
Some(ok) => {
177+
let method_callee = self.register_infer_ok_obligations(ok);
177178
return Some(method_callee);
178179
}
179180
}

src/librustc_typeck/check/method/confirm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
543543
Some(&base_expr),
544544
self.node_ty(base_expr.id),
545545
PreferMutLvalue);
546-
let method = method.expect("re-trying deref failed");
546+
let ok = method.expect("re-trying deref failed");
547+
let method = self.register_infer_ok_obligations(ok);
547548
self.tables.borrow_mut().method_map.insert(method_call, method);
548549
}
549550
}

src/librustc_typeck/check/method/mod.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use rustc::ty::subst::Substs;
1717
use rustc::traits;
1818
use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
1919
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
20-
use rustc::infer;
20+
use rustc::ty::subst::Subst;
21+
use rustc::infer::{self, InferOk};
2122

2223
use syntax::ast;
2324
use syntax_pos::Span;
@@ -159,7 +160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
159160
trait_def_id: DefId,
160161
self_ty: ty::Ty<'tcx>,
161162
opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
162-
-> Option<ty::MethodCallee<'tcx>> {
163+
-> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> {
163164
self.lookup_method_in_trait_adjusted(span,
164165
self_expr,
165166
m_name,
@@ -190,7 +191,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
190191
unsize: bool,
191192
self_ty: ty::Ty<'tcx>,
192193
opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
193-
-> Option<ty::MethodCallee<'tcx>> {
194+
-> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> {
194195
debug!("lookup_in_trait_adjusted(self_ty={:?}, self_expr={:?}, \
195196
m_name={}, trait_def_id={:?})",
196197
self_ty,
@@ -236,6 +237,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
236237
assert_eq!(generics.regions.len(), 0);
237238

238239
debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
240+
let mut obligations = vec![];
239241

240242
// Instantiate late-bound regions and substitute the trait
241243
// parameters into the method type to get the actual method type.
@@ -248,10 +250,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
248250
let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
249251
infer::FnCall,
250252
&fn_sig).0;
251-
let fn_sig = self.instantiate_type_scheme(span, trait_ref.substs, &fn_sig);
253+
let fn_sig = fn_sig.subst(self.tcx, substs);
254+
let fn_sig = match self.normalize_associated_types_in_as_infer_ok(span, &fn_sig) {
255+
InferOk { value, obligations: o } => {
256+
obligations.extend(o);
257+
value
258+
}
259+
};
252260
let transformed_self_ty = fn_sig.inputs()[0];
253-
let method_ty = tcx.mk_fn_def(def_id, trait_ref.substs,
254-
ty::Binder(fn_sig));
261+
let method_ty = tcx.mk_fn_def(def_id, substs, ty::Binder(fn_sig));
255262

256263
debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
257264
method_ty,
@@ -265,18 +272,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
265272
//
266273
// Note that as the method comes from a trait, it should not have
267274
// any late-bound regions appearing in its bounds.
268-
let method_bounds = self.instantiate_bounds(span, def_id, trait_ref.substs);
269-
assert!(!method_bounds.has_escaping_regions());
270-
self.add_obligations_for_parameters(traits::ObligationCause::misc(span, self.body_id),
271-
&method_bounds);
275+
let bounds = self.tcx.item_predicates(def_id).instantiate(self.tcx, substs);
276+
let bounds = match self.normalize_associated_types_in_as_infer_ok(span, &bounds) {
277+
InferOk { value, obligations: o } => {
278+
obligations.extend(o);
279+
value
280+
}
281+
};
282+
assert!(!bounds.has_escaping_regions());
272283

273-
// Also register an obligation for the method type being well-formed.
274-
self.register_wf_obligation(method_ty, span, traits::MiscObligation);
284+
let cause = traits::ObligationCause::misc(span, self.body_id);
285+
obligations.extend(traits::predicates_for_generics(cause.clone(), &bounds));
275286

276-
// FIXME(#18653) -- Try to resolve obligations, giving us more
277-
// typing information, which can sometimes be needed to avoid
278-
// pathological region inference failures.
279-
self.select_obligations_where_possible();
287+
// Also add an obligation for the method type being well-formed.
288+
obligations.push(traits::Obligation::new(cause, ty::Predicate::WellFormed(method_ty)));
280289

281290
// Insert any adjustments needed (always an autoref of some mutability).
282291
if let Some(self_expr) = self_expr {
@@ -317,7 +326,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
317326

318327
debug!("callee = {:?}", callee);
319328

320-
Some(callee)
329+
Some(InferOk {
330+
obligations,
331+
value: callee
332+
})
321333
}
322334

323335
pub fn resolve_ufcs(&self,

src/librustc_typeck/check/mod.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,14 +1749,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17491749
-> ty::InstantiatedPredicates<'tcx> {
17501750
let bounds = self.tcx.item_predicates(def_id);
17511751
let result = bounds.instantiate(self.tcx, substs);
1752-
let result = self.normalize_associated_types_in(span, &result.predicates);
1752+
let result = self.normalize_associated_types_in(span, &result);
17531753
debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
17541754
bounds,
17551755
substs,
17561756
result);
1757-
ty::InstantiatedPredicates {
1758-
predicates: result
1759-
}
1757+
result
17601758
}
17611759

17621760
/// Replace all anonymized types with fresh inference variables
@@ -1799,7 +1797,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17991797
fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
18001798
where T : TypeFoldable<'tcx>
18011799
{
1802-
self.inh.normalize_associated_types_in(span, self.body_id, value)
1800+
let ok = self.normalize_associated_types_in_as_infer_ok(span, value);
1801+
self.register_infer_ok_obligations(ok)
1802+
}
1803+
1804+
fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
1805+
-> InferOk<'tcx, T>
1806+
where T : TypeFoldable<'tcx>
1807+
{
1808+
self.inh.normalize_associated_types_in_as_infer_ok(span, self.body_id, value)
18031809
}
18041810

18051811
pub fn write_nil(&self, node_id: ast::NodeId) {
@@ -2171,8 +2177,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21712177
// If some lookup succeeds, write callee into table and extract index/element
21722178
// type from the method signature.
21732179
// If some lookup succeeded, install method in table
2174-
method.map(|method| {
2180+
method.map(|ok| {
21752181
debug!("try_index_step: success, using overloaded indexing");
2182+
let method = self.register_infer_ok_obligations(ok);
21762183
self.tables.borrow_mut().method_map.insert(method_call, method);
21772184
(input_ty, self.make_overloaded_lvalue_return_type(method).ty)
21782185
})
@@ -3302,8 +3309,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
33023309

33033310
if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
33043311
oprnd_t = mt.ty;
3305-
} else if let Some(method) = self.try_overloaded_deref(
3312+
} else if let Some(ok) = self.try_overloaded_deref(
33063313
expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3314+
let method = self.register_infer_ok_obligations(ok);
33073315
oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
33083316
self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
33093317
method);

src/librustc_typeck/check/op.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,20 +398,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
398398

399399
let method = match trait_did {
400400
Some(trait_did) => {
401-
self.lookup_method_in_trait_adjusted(expr.span,
402-
Some(lhs_expr),
403-
opname,
404-
trait_did,
405-
0,
406-
false,
407-
lhs_ty,
408-
Some(other_tys))
401+
self.lookup_method_in_trait(expr.span,
402+
Some(lhs_expr),
403+
opname,
404+
trait_did,
405+
lhs_ty,
406+
Some(other_tys))
409407
}
410408
None => None
411409
};
412410

413411
match method {
414-
Some(method) => {
412+
Some(ok) => {
413+
let method = self.register_infer_ok_obligations(ok);
415414
let method_ty = method.ty;
416415

417416
// HACK(eddyb) Fully qualified path to work around a resolve bug.

0 commit comments

Comments
 (0)