about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-06 08:24:48 +0000
committerbors <bors@rust-lang.org>2020-03-06 08:24:48 +0000
commit865b44a3e330f3ef8be0f6edf69896c9ed957ac0 (patch)
treee2c7ac42fbf4174f9c79482780463676ce5c3fe3
parent4a1b69d53aeb59a83de192ea67dbe4707b9a7b73 (diff)
parent7b6f5ed9562ad13b68224138992a06463de299c2 (diff)
downloadrust-865b44a3e330f3ef8be0f6edf69896c9ed957ac0.tar.gz
rust-865b44a3e330f3ef8be0f6edf69896c9ed957ac0.zip
Auto merge of #69614 - estebank:ice-age, r=davidtwco
`delay_span_bug` when codegen cannot select obligation

Fix #69602, introduced in #60126 by letting the compiler continue past
type checking after encountering errors.
-rw-r--r--src/librustc/query/mod.rs2
-rw-r--r--src/librustc_infer/traits/codegen/mod.rs18
-rw-r--r--src/librustc_mir/monomorphize/mod.rs2
-rw-r--r--src/librustc_ty/instance.rs2
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs22
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr19
6 files changed, 55 insertions, 10 deletions
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 9277f5a380b..b7f4f432838 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -650,7 +650,7 @@ rustc_queries! {
     Codegen {
         query codegen_fulfill_obligation(
             key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
-        ) -> Vtable<'tcx, ()> {
+        ) -> Option<Vtable<'tcx, ()>> {
             no_force
             cache_on_disk_if { true }
             desc { |tcx|
diff --git a/src/librustc_infer/traits/codegen/mod.rs b/src/librustc_infer/traits/codegen/mod.rs
index bd4129a4de7..f499565e919 100644
--- a/src/librustc_infer/traits/codegen/mod.rs
+++ b/src/librustc_infer/traits/codegen/mod.rs
@@ -19,7 +19,7 @@ use rustc::ty::{self, TyCtxt};
 pub fn codegen_fulfill_obligation<'tcx>(
     ty: TyCtxt<'tcx>,
     (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
-) -> Vtable<'tcx, ()> {
+) -> Option<Vtable<'tcx, ()>> {
     // Remove any references to regions; this helps improve caching.
     let trait_ref = ty.erase_regions(&trait_ref);
 
@@ -47,11 +47,15 @@ pub fn codegen_fulfill_obligation<'tcx>(
                 // leading to an ambiguous result. So report this as an
                 // overflow bug, since I believe this is the only case
                 // where ambiguity can result.
-                bug!(
-                    "Encountered ambiguity selecting `{:?}` during codegen, \
-                      presuming due to overflow",
-                    trait_ref
-                )
+                infcx.tcx.sess.delay_span_bug(
+                    rustc_span::DUMMY_SP,
+                    &format!(
+                        "encountered ambiguity selecting `{:?}` during codegen, presuming due to \
+                         overflow or prior type error",
+                        trait_ref
+                    ),
+                );
+                return None;
             }
             Err(e) => {
                 bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref)
@@ -71,7 +75,7 @@ pub fn codegen_fulfill_obligation<'tcx>(
         let vtable = infcx.drain_fulfillment_cx_or_panic(&mut fulfill_cx, &vtable);
 
         info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
-        vtable
+        Some(vtable)
     })
 }
 
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 8bc63bfcfcb..3dff06967e5 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -18,7 +18,7 @@ pub fn custom_coerce_unsize_info<'tcx>(
     });
 
     match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
-        traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
+        Some(traits::VtableImpl(traits::VtableImplData { impl_def_id, .. })) => {
             tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap()
         }
         vtable => {
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 484b774add4..c2b2196e74c 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -70,7 +70,7 @@ fn resolve_associated_item<'tcx>(
     );
 
     let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
-    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
+    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)))?;
 
     // Now that we know which impl is being used, we can dispatch to
     // the actual function:
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
new file mode 100644
index 00000000000..2c5257ce063
--- /dev/null
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
@@ -0,0 +1,22 @@
+trait TraitA {
+    const VALUE: usize;
+}
+
+struct A;
+impl TraitA for A {
+  const VALUE: usize = 0;
+}
+
+trait TraitB {
+    type MyA: TraitA;
+    const VALUE: usize = Self::MyA::VALUE;
+}
+
+struct B;
+impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA`
+    type M   = A; //~ ERROR type `M` is not a member of trait `TraitB`
+}
+
+fn main() {
+    let _ = [0; B::VALUE];
+}
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
new file mode 100644
index 00000000000..8ae0f8b804c
--- /dev/null
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
@@ -0,0 +1,19 @@
+error[E0437]: type `M` is not a member of trait `TraitB`
+  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:17:5
+   |
+LL |     type M   = A;
+   |     ^^^^^^^^^^^^^ not a member of trait `TraitB`
+
+error[E0046]: not all trait items implemented, missing: `MyA`
+  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:16:1
+   |
+LL |     type MyA: TraitA;
+   |     ----------------- `MyA` from trait
+...
+LL | impl TraitB for B {
+   | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0046, E0437.
+For more information about an error, try `rustc --explain E0046`.