Don't call instantiate_type_scheme during method probing
It can introduce obligations to the fulfillment context, which would incorrectly still remain after the probe finished. Fixes #25679.
This commit is contained in:
parent
0d82fb55db
commit
1af72660a7
2 changed files with 37 additions and 1 deletions
|
@ -398,11 +398,19 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
}
|
||||
|
||||
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
|
||||
let impl_ty = self.fcx.instantiate_type_scheme(self.span, &impl_substs, &impl_ty);
|
||||
|
||||
// We can't use instantiate_type_scheme here as it will pollute
|
||||
// the fcx's fulfillment context if this probe is rolled back.
|
||||
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
|
||||
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx);
|
||||
let traits::Normalized { value: impl_ty, .. } =
|
||||
traits::normalize(selcx, cause, &impl_ty.subst(self.tcx(), &impl_substs));
|
||||
|
||||
// Determine the receiver type that the method itself expects.
|
||||
let xform_self_ty =
|
||||
self.xform_self_ty(&item, impl_ty, &impl_substs);
|
||||
debug!("assemble_inherent_impl_probe: self ty = {:?}",
|
||||
xform_self_ty.repr(self.tcx()));
|
||||
|
||||
self.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
|
|
28
src/test/run-pass/issue-25679.rs
Normal file
28
src/test/run-pass/issue-25679.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait Device {
|
||||
type Resources;
|
||||
}
|
||||
struct Foo<D, R>(D, R);
|
||||
|
||||
impl<D: Device, S> Foo<D, S> {
|
||||
fn present(&self) {}
|
||||
}
|
||||
|
||||
struct Res;
|
||||
struct Dev;
|
||||
|
||||
impl Device for Dev { type Resources = Res; }
|
||||
|
||||
fn main() {
|
||||
let foo = Foo(Dev, Res);
|
||||
foo.present();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue