diff options
| author | Wesley Wiser <wwiser@gmail.com> | 2019-12-27 11:44:36 -0500 |
|---|---|---|
| committer | Wesley Wiser <wwiser@gmail.com> | 2019-12-27 13:04:32 -0500 |
| commit | 25a8b5d58e3899084e191ffd9456f39d29c3263b (patch) | |
| tree | 770a1239529778173c709cf29b2826faee379a12 /src/librustc | |
| parent | 41501a6b03a8f10d8c29dfcb37dbd5ff84b33f34 (diff) | |
| download | rust-25a8b5d58e3899084e191ffd9456f39d29c3263b.tar.gz rust-25a8b5d58e3899084e191ffd9456f39d29c3263b.zip | |
Fix `Instance::resolve()` incorrectly returning specialized instances
We only want to return specializations when `Reveal::All` is passed, not when `Reveal::UserFacing` is. Resolving this fixes several issues with the `ConstProp`, `SimplifyBranches`, and `Inline` MIR optimization passes. Fixes #66901
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/mir/interpret/queries.rs | 2 | ||||
| -rw-r--r-- | src/librustc/traits/project.rs | 3 | ||||
| -rw-r--r-- | src/librustc/ty/instance.rs | 19 |
3 files changed, 23 insertions, 1 deletions
diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs index e6caa146a62..c593a51e457 100644 --- a/src/librustc/mir/interpret/queries.rs +++ b/src/librustc/mir/interpret/queries.rs @@ -18,7 +18,7 @@ impl<'tcx> TyCtxt<'tcx> { let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; - let param_env = self.param_env(def_id); + let param_env = self.param_env(def_id).with_reveal_all(); self.const_eval_validated(param_env.and(cid)) } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 90381895f0a..bcb012ea514 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1028,6 +1028,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // In either case, we handle this by not adding a // candidate for an impl if it contains a `default` // type. + // + // NOTE: This should be kept in sync with the similar code in + // `rustc::ty::instance::resolve_associated_item()`. let node_item = assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id); diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index faa83ceadde..cfd1779c080 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -346,6 +346,25 @@ fn resolve_associated_item<'tcx>( traits::VtableImpl(impl_data) => { let (def_id, substs) = traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data); + + let resolved_item = tcx.associated_item(def_id); + + // Since this is a trait item, we need to see if the item is either a trait default item + // or a specialization because we can't resolve those unless we can `Reveal::All`. + // NOTE: This should be kept in sync with the similar code in + // `rustc::traits::project::assemble_candidates_from_impls()`. + let eligible = if !resolved_item.defaultness.is_default() { + true + } else if param_env.reveal == traits::Reveal::All { + !trait_ref.needs_subst() + } else { + false + }; + + if !eligible { + return None; + } + let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } |
