about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-20 10:51:26 +0000
committerbors <bors@rust-lang.org>2019-11-20 10:51:26 +0000
commitea540b0892ed6b62d170c7f0a9aa362e590de8b4 (patch)
treed837319ab59d47cd410f04d3e2eb50f7a6abf1ab
parentf50d6ea348c2dd7c2f76e35ecde6560d87bb98ec (diff)
parent0ff73535ed0044c517697fa3527da3f52069dc3d (diff)
downloadrust-ea540b0892ed6b62d170c7f0a9aa362e590de8b4.tar.gz
rust-ea540b0892ed6b62d170c7f0a9aa362e590de8b4.zip
Auto merge of #66392 - estebank:trait-alias-ice, r=eddyb
Do not ICE on trait aliases with missing obligations

Fix #65673.
-rw-r--r--src/librustc_typeck/astconv.rs31
-rw-r--r--src/test/ui/issues/issue-65673.rs12
-rw-r--r--src/test/ui/issues/issue-65673.stderr17
3 files changed, 48 insertions, 12 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c3bd916b9ce..a33b2e32c86 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1224,16 +1224,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         )
     }
 
-    /// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
-    /// removing the dummy `Self` type (`trait_object_dummy_self`).
-    fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
-                                -> ty::ExistentialTraitRef<'tcx> {
-        if trait_ref.self_ty() != self.tcx().types.trait_object_dummy_self {
-            bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
-        }
-        ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
-    }
-
     fn conv_object_ty_poly_trait_ref(&self,
         span: Span,
         trait_bounds: &[hir::PolyTraitRef],
@@ -1415,13 +1405,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         debug!("regular_traits: {:?}", regular_traits);
         debug!("auto_traits: {:?}", auto_traits);
 
+        // Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
+        // removing the dummy `Self` type (`trait_object_dummy_self`).
+        let trait_ref_to_existential = |trait_ref: ty::TraitRef<'tcx>| {
+            if trait_ref.self_ty() != dummy_self {
+                // FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
+                // which picks up non-supertraits where clauses - but also, the object safety
+                // completely ignores trait aliases, which could be object safety hazards. We
+                // `delay_span_bug` here to avoid an ICE in stable even when the feature is
+                // disabled. (#66420)
+                tcx.sess.delay_span_bug(DUMMY_SP, &format!(
+                    "trait_ref_to_existential called on {:?} with non-dummy Self",
+                    trait_ref,
+                ));
+            }
+            ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+        };
+
         // Erase the `dummy_self` (`trait_object_dummy_self`) used above.
         let existential_trait_refs = regular_traits.iter().map(|i| {
-            i.trait_ref().map_bound(|trait_ref| self.trait_ref_to_existential(trait_ref))
+            i.trait_ref().map_bound(|trait_ref| trait_ref_to_existential(trait_ref))
         });
         let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
             bound.map_bound(|b| {
-                let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
+                let trait_ref = trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
                 ty::ExistentialProjection {
                     ty: b.ty,
                     item_def_id: b.projection_ty.item_def_id,
diff --git a/src/test/ui/issues/issue-65673.rs b/src/test/ui/issues/issue-65673.rs
new file mode 100644
index 00000000000..4b47bd493a5
--- /dev/null
+++ b/src/test/ui/issues/issue-65673.rs
@@ -0,0 +1,12 @@
+#![feature(trait_alias)] // Enabled to reduce stderr output, but can be triggered even if disabled.
+trait Trait {}
+trait WithType {
+    type Ctx;
+}
+trait Alias<T> = where T: Trait;
+
+impl<T> WithType for T {
+    type Ctx = dyn Alias<T>;
+//~^ ERROR the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+}
+fn main() {}
diff --git a/src/test/ui/issues/issue-65673.stderr b/src/test/ui/issues/issue-65673.stderr
new file mode 100644
index 00000000000..a556e35b6a9
--- /dev/null
+++ b/src/test/ui/issues/issue-65673.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+  --> $DIR/issue-65673.rs:9:5
+   |
+LL |     type Ctx;
+   |          --- associated type defined here
+...
+LL | impl<T> WithType for T {
+   | ---------------------- in this `impl` item
+LL |     type Ctx = dyn Alias<T>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.