Skip to content

Commit 92fa077

Browse files
committed
rustc: ignore still-specializable VtableImpl's in Instance::resolve.
1 parent f1878ff commit 92fa077

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/librustc/ty/instance.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,39 @@ fn resolve_associated_item<'a, 'tcx>(
260260
traits::VtableImpl(impl_data) => {
261261
let (def_id, substs) = traits::find_associated_item(
262262
tcx, trait_item, rcvr_substs, &impl_data);
263-
let substs = tcx.erase_regions(&substs);
264-
Some(ty::Instance::new(def_id, substs))
263+
264+
let eligible = {
265+
let item = tcx.associated_item(def_id);
266+
let is_default = match item.container {
267+
ty::TraitContainer(_) => item.defaultness.has_value(),
268+
ty::ImplContainer(impl_def_id) => {
269+
item.defaultness.is_default() || tcx.impl_is_default(impl_def_id)
270+
}
271+
};
272+
273+
// Only reveal a specializable default if we're past type-checking
274+
// and the obligations is monomorphic, otherwise passes such as
275+
// transmute checking and polymorphic MIR optimizations could
276+
// get a result which isn't correct for all monomorphizations.
277+
if !is_default {
278+
true
279+
} else if param_env.reveal == traits::Reveal::All {
280+
assert!(!trait_ref.needs_infer());
281+
if !trait_ref.needs_subst() {
282+
true
283+
} else {
284+
false
285+
}
286+
} else {
287+
false
288+
}
289+
};
290+
if eligible {
291+
let substs = tcx.erase_regions(&substs);
292+
Some(ty::Instance::new(def_id, substs))
293+
} else {
294+
None
295+
}
265296
}
266297
traits::VtableGenerator(closure_data) => {
267298
Some(Instance {

0 commit comments

Comments
 (0)