Skip to content

Commit 4d247ad

Browse files
committed
Auto merge of rust-lang#77306 - lcnr:inline-ok, r=eddyb
normalize substs while inlining fixes rust-lang#68347 or more precisely, this fixes the same ICE in rust analyser as veloren is pinned to a specific nightly and had an error with the current one. I didn't look into creating an MVCE here as that seems fairly annoying, will spend a few minutes doing so rn. (failed) r? `@eddyb` cc `@bjorn3`
2 parents 834821e + ac893b8 commit 4d247ad

File tree

5 files changed

+91
-7
lines changed

5 files changed

+91
-7
lines changed

compiler/rustc_mir/src/transform/inline.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,13 @@ impl Inliner<'tcx> {
201201
let terminator = bb_data.terminator();
202202
if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
203203
if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() {
204-
let instance = Instance::resolve(self.tcx, self.param_env, callee_def_id, substs)
205-
.ok()
206-
.flatten()?;
204+
// To resolve an instance its substs have to be fully normalized, so
205+
// we do this here.
206+
let normalized_substs = self.tcx.normalize_erasing_regions(self.param_env, substs);
207+
let instance =
208+
Instance::resolve(self.tcx, self.param_env, callee_def_id, normalized_substs)
209+
.ok()
210+
.flatten()?;
207211

208212
if let InstanceDef::Virtual(..) = instance.def {
209213
return None;

compiler/rustc_trait_selection/src/traits/codegen/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ use rustc_middle::ty::{self, TyCtxt};
1717
/// (necessarily) resolve all nested obligations on the impl. Note
1818
/// that type check should guarantee to us that all nested
1919
/// obligations *could be* resolved if we wanted to.
20+
///
2021
/// Assumes that this is run after the entire crate has been successfully type-checked.
22+
/// This also expects that `trait_ref` is fully normalized.
2123
pub fn codegen_fulfill_obligation<'tcx>(
22-
ty: TyCtxt<'tcx>,
24+
tcx: TyCtxt<'tcx>,
2325
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
2426
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
2527
// Remove any references to regions; this helps improve caching.
26-
let trait_ref = ty.erase_regions(&trait_ref);
27-
28+
let trait_ref = tcx.erase_regions(&trait_ref);
29+
// We expect the input to be fully normalized.
30+
debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));
2831
debug!(
2932
"codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
3033
(param_env, trait_ref),
@@ -33,7 +36,7 @@ pub fn codegen_fulfill_obligation<'tcx>(
3336

3437
// Do the initial selection for the obligation. This yields the
3538
// shallow result we are looking for -- that is, what specific impl.
36-
ty.infer_ctxt().enter(|infcx| {
39+
tcx.infer_ctxt().enter(|infcx| {
3740
let mut selcx = SelectionContext::new(&infcx);
3841

3942
let obligation_cause = ObligationCause::dummy();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// run-pass
2+
// compile-flags:-Zmir-opt-level=2
3+
pub fn main() {
4+
let _x: fn() = handle_debug_column;
5+
}
6+
7+
fn handle_debug_column() {
8+
let sampler = sample_columns();
9+
10+
let foo = || {
11+
sampler.get(17);
12+
};
13+
foo();
14+
}
15+
16+
fn sample_columns() -> impl Sampler {
17+
ColumnGen {}
18+
}
19+
20+
struct ColumnGen {}
21+
22+
trait Sampler {
23+
fn get(&self, index: i32);
24+
}
25+
26+
impl Sampler for ColumnGen {
27+
fn get(&self, _index: i32) {}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
// compile-flags:-Zmir-opt-level=2
3+
4+
// Previously ICEd because we did not normalize during inlining,
5+
// see https://github.com/rust-lang/rust/pull/77306 for more discussion.
6+
7+
pub fn write() {
8+
create()()
9+
}
10+
11+
pub fn create() -> impl FnOnce() {
12+
|| ()
13+
}
14+
15+
fn main() {
16+
write();
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// run-pass
2+
// compile-flags:-Zmir-opt-level=2
3+
4+
struct Cursor {}
5+
struct TokenTree {}
6+
7+
impl Iterator for Cursor {
8+
type Item = TokenTree;
9+
10+
fn next(&mut self) -> Option<TokenTree> {
11+
None
12+
}
13+
}
14+
15+
fn tokenstream_probably_equal_for_proc_macro() {
16+
fn break_tokens(_tree: TokenTree) -> impl Iterator<Item = TokenTree> {
17+
let token_trees: Vec<TokenTree> = vec![];
18+
token_trees.into_iter()
19+
}
20+
21+
let c1 = Cursor {};
22+
let c2 = Cursor {};
23+
24+
let mut t1 = c1.flat_map(break_tokens);
25+
let mut t2 = c2.flat_map(break_tokens);
26+
27+
for (_t1, _t2) in t1.by_ref().zip(t2.by_ref()) {}
28+
}
29+
30+
fn main() {
31+
tokenstream_probably_equal_for_proc_macro();
32+
}

0 commit comments

Comments
 (0)