about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2019-12-27 11:44:36 -0500
committerWesley Wiser <wwiser@gmail.com>2019-12-27 13:04:32 -0500
commit25a8b5d58e3899084e191ffd9456f39d29c3263b (patch)
tree770a1239529778173c709cf29b2826faee379a12 /src/librustc
parent41501a6b03a8f10d8c29dfcb37dbd5ff84b33f34 (diff)
downloadrust-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.rs2
-rw-r--r--src/librustc/traits/project.rs3
-rw-r--r--src/librustc/ty/instance.rs19
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))
         }