Repository: rust-lang/rust
Pull request: fixed generics of crate node ICE

when `note_and_explain_type_err` is called during dyn-compatibility checking, the `body_owner_def_id` can be `CRATE_DEF_ID` because `ObligationCause::dummy()` uses it as a placeholder when there is no real body owner. calling `generics_of `on `CRATE_DEF_ID `caused an ICE because the crate root is a module and modules don't have generics. the fix guards all `generics_of` call sites by checking whether `body_owner_def_id` is `CRATE_DEF_ID` before attempting to look up generics, and skips the type parameter span labeling in that case. 

i also added regression test with original ice reproduce

fixes rust-lang/rust#152335

Changed files:
filename: compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
patch: @@ -55,7 +55,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::DefineOpaqueTypes;
@@ -1797,12 +1797,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
         }
 
-        self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
+        let body_owner_def_id = (cause.body_id != CRATE_DEF_ID).then(|| cause.body_id.to_def_id());
+        self.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id);
         if let Some(exp_found) = exp_found
             && let exp_found = TypeError::Sorts(exp_found)
             && exp_found != terr
         {
-            self.note_and_explain_type_err(diag, exp_found, cause, span, cause.body_id.to_def_id());
+            self.note_and_explain_type_err(diag, exp_found, cause, span, body_owner_def_id);
         }
 
         if let Some(ValuePairs::TraitRefs(exp_found)) = values

filename: compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
patch: @@ -22,12 +22,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         err: TypeError<'tcx>,
         cause: &ObligationCause<'tcx>,
         sp: Span,
-        body_owner_def_id: DefId,
+        body_owner_def_id: Option<DefId>,
     ) {
         debug!("note_and_explain_type_err err={:?} cause={:?}", err, cause);
 
         let tcx = self.tcx;
 
+        let body_generics = body_owner_def_id.map(|def_id| tcx.generics_of(def_id));
+
         match err {
             TypeError::ArgumentSorts(values, _) | TypeError::Sorts(values) => {
                 match (*values.expected.kind(), *values.found.kind()) {
@@ -64,14 +66,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         }
                     }
                     (ty::Param(expected), ty::Param(found)) => {
-                        let generics = tcx.generics_of(body_owner_def_id);
-                        let e_span = tcx.def_span(generics.type_param(expected, tcx).def_id);
-                        if !sp.contains(e_span) {
-                            diag.span_label(e_span, "expected type parameter");
-                        }
-                        let f_span = tcx.def_span(generics.type_param(found, tcx).def_id);
-                        if !sp.contains(f_span) {
-                            diag.span_label(f_span, "found type parameter");
+                        if let Some(generics) = body_generics {
+                            let e_span = tcx.def_span(generics.type_param(expected, tcx).def_id);
+                            if !sp.contains(e_span) {
+                                diag.span_label(e_span, "expected type parameter");
+                            }
+                            let f_span = tcx.def_span(generics.type_param(found, tcx).def_id);
+                            if !sp.contains(f_span) {
+                                diag.span_label(f_span, "found type parameter");
+                            }
                         }
                         diag.note(
                             "a type parameter was expected, but a different one was found; \
@@ -92,9 +95,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
                     (ty::Param(p), ty::Alias(ty::Projection, proj))
                     | (ty::Alias(ty::Projection, proj), ty::Param(p))
-                        if !tcx.is_impl_trait_in_trait(proj.def_id) =>
+                        if !tcx.is_impl_trait_in_trait(proj.def_id)
+                            && let Some(generics) = body_generics =>
                     {
-                        let param = tcx.generics_of(body_owner_def_id).type_param(p, tcx);
+                        let param = generics.type_param(p, tcx);
                         let p_def_id = param.def_id;
                         let p_span = tcx.def_span(p_def_id);
                         let expected = match (values.expected.kind(), values.found.kind()) {
@@ -106,9 +110,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             diag.span_label(p_span, format!("{expected}this type parameter"));
                         }
                         let param_def_id = match *proj.self_ty().kind() {
-                            ty::Param(param) => {
-                                tcx.generics_of(body_owner_def_id).type_param(param, tcx).def_id
-                            }
+                            ty::Param(param) => generics.type_param(param, tcx).def_id,
                             _ => p_def_id,
                         };
                         let parent = param_def_id.as_local().and_then(|id| {
@@ -188,15 +190,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                     (ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
                     | (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
-                        let generics = tcx.generics_of(body_owner_def_id);
-                        let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
-                        let expected = match (values.expected.kind(), values.found.kind()) {
-                            (ty::Param(_), _) => "expected ",
-                            (_, ty::Param(_)) => "found ",
-                            _ => "",
-                        };
-                        if !sp.contains(p_span) {
-                            diag.span_label(p_span, format!("{expected}this type parameter"));
+                        if let Some(generics) = body_generics {
+                            let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
+                            let expected = match (values.expected.kind(), values.found.kind()) {
+                                (ty::Param(_), _) => "expected ",
+                                (_, ty::Param(_)) => "found ",
+                                _ => "",
+                            };
+                            if !sp.contains(p_span) {
+                                diag.span_label(p_span, format!("{expected}this type parameter"));
+                            }
                         }
                         diag.help("type parameters must be constrained to match other types");
                         if diag.code.is_some_and(|code| tcx.sess.teach(code)) {
@@ -236,18 +239,18 @@ impl<T> Trait<T> for X {
                         ty::Param(p),
                         ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..),
                     ) => {
-                        let generics = tcx.generics_of(body_owner_def_id);
-                        let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
-                        if !sp.contains(p_span) {
-                            diag.span_label(p_span, "expected this type parameter");
+                        if let Some(generics) = body_generics {
+                            let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
+                            if !sp.contains(p_span) {
+                                diag.span_label(p_span, "expected this type parameter");
+                            }
                         }
                         diag.help(format!(
                             "every closure has a distinct type and so could not always match the \
                              caller-chosen type of parameter `{p}`"
                         ));
                     }
-                    (ty::Param(p), _) | (_, ty::Param(p)) => {
-                        let generics = tcx.generics_of(body_owner_def_id);
+                    (ty::Param(p), _) | (_, ty::Param(p)) if let Some(generics) = body_generics => {
                         let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
                         let expected = match (values.expected.kind(), values.found.kind()) {
                             (ty::Param(_), _) => "expected ",
@@ -366,7 +369,8 @@ impl<T> Trait<T> for X {
                     }
                     (_, ty::Alias(ty::Opaque, opaque_ty))
                     | (ty::Alias(ty::Opaque, opaque_ty), _) => {
-                        if opaque_ty.def_id.is_local()
+                        if let Some(body_owner_def_id) = body_owner_def_id
+                            && opaque_ty.def_id.is_local()
                             && matches!(
                                 tcx.def_kind(body_owner_def_id),
                                 DefKind::Fn
@@ -560,11 +564,14 @@ impl<T> Trait<T> for X {
         &self,
         diag: &mut Diag<'_>,
         msg: impl Fn() -> String,
-        body_owner_def_id: DefId,
+        body_owner_def_id: Option<DefId>,
         proj_ty: ty::AliasTy<'tcx>,
         ty: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
+        let Some(body_owner_def_id) = body_owner_def_id else {
+            return false;
+        };
         let assoc = tcx.associated_item(proj_ty.def_id);
         let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
         let Some(item) = tcx.hir_get_if_local(body_owner_def_id) else {
@@ -611,7 +618,7 @@ impl<T> Trait<T> for X {
             _ => return false,
         };
         let parent = tcx.hir_get_parent_item(hir_id).def_id;
-        self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty)
+        self.suggest_constraint(diag, msg, Some(parent.into()), proj_ty, ty)
     }
 
     /// An associated type was expected and a different type was found.
@@ -632,7 +639,7 @@ impl<T> Trait<T> for X {
         diag: &mut Diag<'_>,
         proj_ty: ty::AliasTy<'tcx>,
         values: ExpectedFound<Ty<'tcx>>,
-        body_owner_def_id: DefId,
+        body_owner_def_id: Option<DefId>,
         cause_code: &ObligationCauseCode<'_>,
     ) {
         let tcx = self.tcx;
@@ -653,7 +660,7 @@ impl<T> Trait<T> for X {
             )
         };
 
-        let body_owner = tcx.hir_get_if_local(body_owner_def_id);
+        let body_owner = body_owner_def_id.and_then(|id| tcx.hir_get_if_local(id));
         let current_method_ident = body_owner.and_then(|n| n.ident()).map(|i| i.name);
 
         // We don't want to suggest calling an assoc fn in a scope where that isn't feasible.
@@ -835,12 +842,12 @@ fn foo(&self) -> Self::T { String::new() }
     fn point_at_associated_type(
         &self,
         diag: &mut Diag<'_>,
-        body_owner_def_id: DefId,
+        body_owner_def_id: Option<DefId>,
         found: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
 
-        let Some(def_id) = body_owner_def_id.as_local() else {
+        let Some(def_id) = body_owner_def_id.and_then(|id| id.as_local()) else {
             return false;
         };
 
@@ -852,7 +859,7 @@ fn foo(&self) -> Self::T { String::new() }
 
         debug!("expected_projection parent item {:?}", item);
 
-        let param_env = tcx.param_env(body_owner_def_id);
+        let param_env = tcx.param_env(def_id);
 
         if let DefKind::Trait | DefKind::Impl { .. } = tcx.def_kind(parent_id) {
             let assoc_items = tcx.associated_items(parent_id);

filename: tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs
patch: @@ -0,0 +1,40 @@
+// Regression test for #152335.
+// The compiler used to ICE in `generics_of` when `note_and_explain_type_err`
+// was called with `CRATE_DEF_ID` as the body owner during dyn-compatibility
+// checking. This happened because `ObligationCause::dummy()` sets `body_id`
+// to `CRATE_DEF_ID`, and error reporting tried to look up generics on it.
+
+struct ActuallySuper;
+
+trait Super<B = Self> {
+    type Assoc;
+}
+
+trait Dyn {}
+impl<T, U> Dyn for dyn Foo<T, U> + '_ {}
+//~^ ERROR the trait `Foo` is not dyn compatible
+
+trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+//~^ ERROR type mismatch resolving
+//~| ERROR the size for values of type `Self` cannot be known
+where
+    <Self as Mirror>::Assoc: Super,
+    //~^ ERROR type mismatch resolving
+    //~| ERROR the size for values of type `Self` cannot be known
+    //~| ERROR type mismatch resolving
+    //~| ERROR the size for values of type `Self` cannot be known
+{
+    fn transmute(&self, t: T) -> <Self as B>::Assoc;
+    //~^ ERROR cannot find trait `B` in this scope
+    //~| ERROR type mismatch resolving
+    //~| ERROR the size for values of type `Self` cannot be known
+    //~| ERROR type mismatch resolving
+    //~| ERROR the size for values of type `Self` cannot be known
+}
+
+trait Mirror {
+    type Assoc: ?Sized;
+}
+impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+//~^ ERROR not all trait items implemented
+//~| ERROR `main` function not found

filename: tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr
patch: @@ -0,0 +1,236 @@
+error[E0405]: cannot find trait `B` in this scope
+  --> $DIR/ice-generics-of-crate-root-152335.rs:27:43
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc;
+   |                                           ^ not found in this scope
+
+error[E0601]: `main` function not found in crate `ice_generics_of_crate_root_152335`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:57
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                                                         ^ consider adding a `main` function to `$DIR/ice-generics-of-crate-root-152335.rs`
+
+error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:27:5
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `Self`, found type parameter `T`
+   |
+   = note: expected type parameter `Self`
+              found type parameter `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                              ---------   ^^^^^^     ^
+   |                              |
+   |                              unsatisfied trait bound introduced here
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/ice-generics-of-crate-root-152335.rs:27:5
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |      -                                   ^^^^^^     ^
+   |      |
+   |      unsatisfied trait bound implicitly introduced here
+
+error[E0038]: the trait `Foo` is not dyn compatible
+  --> $DIR/ice-generics-of-crate-root-152335.rs:14:20
+   |
+LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ {}
+   |                    ^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
+   |
+note: for a trait to be dyn compatible it needs to allow building a vtable
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $DIR/ice-generics-of-crate-root-152335.rs:21:30
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   |       --- this trait is not dyn compatible...
+...
+LL |     <Self as Mirror>::Assoc: Super,
+   |                              ^^^^^ ...because it uses `Self` as a type parameter
+
+error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:17:1
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `Self`, found type parameter `T`
+   |
+   = note: expected type parameter `Self`
+              found type parameter `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                              ---------   ^^^^^^     ^
+   |                              |
+   |                              unsatisfied trait bound introduced here
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/ice-generics-of-crate-root-152335.rs:17:1
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |      -                                   ^^^^^^     ^
+   |      |
+   |      unsatisfied trait bound implicitly introduced here
+help: consider further restricting `Self`
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + Sized
+   |                                                  +++++++
+
+error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:21:30
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   | ------------------------------------------------
+   | |         |
+   | |         found type parameter
+   | expected type parameter
+...
+LL |     <Self as Mirror>::Assoc: Super,
+   |                              ^^^^^ expected type parameter `Self`, found type parameter `T`
+   |
+   = note: expected type parameter `Self`
+              found type parameter `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                              ---------   ^^^^^^     ^
+   |                              |
+   |                              unsatisfied trait bound introduced here
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/ice-generics-of-crate-root-152335.rs:21:30
+   |
+LL |     <Self as Mirror>::Assoc: Super,
+   |                              ^^^^^ doesn't have a size known at compile-time
+   |
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |      -                                   ^^^^^^     ^
+   |      |
+   |      unsatisfied trait bound implicitly introduced here
+help: consider further restricting `Self`
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + Sized
+   |                                                  +++++++
+
+error[E0046]: not all trait items implemented, missing: `Assoc`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:1
+   |
+LL |     type Assoc: ?Sized;
+   |     ------------------ `Assoc` from trait
+LL | }
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
+
+error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:27:5
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   | ------------------------------------------------
+   | |         |
+   | |         found type parameter
+   | expected type parameter
+...
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `Self`, found type parameter `T`
+   |
+   = note: expected type parameter `Self`
+              found type parameter `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                              ---------   ^^^^^^     ^
+   |                              |
+   |                              unsatisfied trait bound introduced here
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/ice-generics-of-crate-root-152335.rs:27:5
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |      -                                   ^^^^^^     ^
+   |      |
+   |      unsatisfied trait bound implicitly introduced here
+help: consider further restricting `Self`
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc where Self: Sized;
+   |                                                     +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:21:30
+   |
+LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
+   | ------------------------------------------------
+   | |         |
+   | |         found type parameter
+   | expected type parameter
+...
+LL |     <Self as Mirror>::Assoc: Super,
+   |                              ^^^^^ expected type parameter `Self`, found type parameter `T`
+   |
+   = note: expected type parameter `Self`
+              found type parameter `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |                              ---------   ^^^^^^     ^
+   |                              |
+   |                              unsatisfied trait bound introduced here
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/ice-generics-of-crate-root-152335.rs:21:30
+   |
+LL |     <Self as Mirror>::Assoc: Super,
+   |                              ^^^^^ doesn't have a size known at compile-time
+   |
+note: required for `Self` to implement `Mirror`
+  --> $DIR/ice-generics-of-crate-root-152335.rs:38:42
+   |
+LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
+   |      -                                   ^^^^^^     ^
+   |      |
+   |      unsatisfied trait bound implicitly introduced here
+help: consider further restricting `Self`
+   |
+LL |     fn transmute(&self, t: T) -> <Self as B>::Assoc where Self: Sized;
+   |                                                     +++++++++++++++++
+
+error: aborting due to 14 previous errors
+
+Some errors have detailed explanations: E0038, E0046, E0271, E0277, E0405, E0601.
+For more information about an error, try `rustc --explain E0038`.