Skip to content

Commit 1af7266

Browse files
arielb1Ariel Ben-Yehuda
authored and
Ariel Ben-Yehuda
committed
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.
1 parent 0d82fb5 commit 1af7266

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/librustc_typeck/check/method/probe.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,19 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
398398
}
399399

400400
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
401-
let impl_ty = self.fcx.instantiate_type_scheme(self.span, &impl_substs, &impl_ty);
401+
402+
// We can't use instantiate_type_scheme here as it will pollute
403+
// the fcx's fulfillment context if this probe is rolled back.
404+
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
405+
let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx);
406+
let traits::Normalized { value: impl_ty, .. } =
407+
traits::normalize(selcx, cause, &impl_ty.subst(self.tcx(), &impl_substs));
402408

403409
// Determine the receiver type that the method itself expects.
404410
let xform_self_ty =
405411
self.xform_self_ty(&item, impl_ty, &impl_substs);
412+
debug!("assemble_inherent_impl_probe: self ty = {:?}",
413+
xform_self_ty.repr(self.tcx()));
406414

407415
self.inherent_candidates.push(Candidate {
408416
xform_self_ty: xform_self_ty,

src/test/run-pass/issue-25679.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Device {
12+
type Resources;
13+
}
14+
struct Foo<D, R>(D, R);
15+
16+
impl<D: Device, S> Foo<D, S> {
17+
fn present(&self) {}
18+
}
19+
20+
struct Res;
21+
struct Dev;
22+
23+
impl Device for Dev { type Resources = Res; }
24+
25+
fn main() {
26+
let foo = Foo(Dev, Res);
27+
foo.present();
28+
}

0 commit comments

Comments
 (0)