diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 6709c822dc7b1..fa4c8182184c7 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -209,9 +209,7 @@ impl<'a, 'tcx> TypeFolder> for InferenceFudger<'a, 'tcx> { ty } } - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { - unreachable!("unexpected fresh infcx var") - } + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty, } } else if ty.has_infer() { ty.super_fold_with(self) @@ -247,7 +245,9 @@ impl<'a, 'tcx> TypeFolder> for InferenceFudger<'a, 'tcx> { } } ty::InferConst::Fresh(_) => { - unreachable!("unexpected fresh infcx var") + // `Fresh` const vars are produced by `TypeFreshener` and don't refer to infcx state. + // They can safely be forwarded through `fudge_inference_if_ok`. + ct } } } else if ct.has_infer() { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f015d0edc56c8..ffef2b78ec35e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -653,10 +653,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> { // into the witness. ty::CoroutineWitness(..) => (), + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => (), + // These variants should not exist as a self type. - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) - | ty::Param(_) - | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"), + ty::Infer(ty::TyVar(_)) | ty::Param(_) | ty::Bound(_, _) => { + bug!("unexpected self type: {self_ty}") + } } #[allow(rustc::usage_of_type_ir_traits)] diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 63f246db8a5fb..4c5999ab7fc98 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -707,7 +707,10 @@ where | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Error(_) => return, - ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => { + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + return; + } + ty::Bound(..) => { panic!("unexpected self type for `{goal:?}`") } @@ -799,6 +802,14 @@ where } let self_ty = goal.predicate.self_ty(); + // FreshTy is used as trait_object_dummy_self and should not reach here + if matches!( + self_ty.kind(), + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + ) { + return; + } + let bounds = match self_ty.kind() { ty::Bool | ty::Char diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 05ea217c1de08..81035750a9f37 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -148,8 +148,10 @@ where ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => Err(NoSolution), - ty::Bound(..) - | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + // FreshTy is used as trait_object_dummy_self and should not reach here + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => Err(NoSolution), + + ty::Bound(..) | ty::Infer(ty::TyVar(_)) => { panic!("unexpected type `{ty:?}`") } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 19ccf6a55bf1a..2cede4bb4c107 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -383,7 +383,16 @@ pub fn sizedness_fast_path<'tcx>( _ => return false, }; - if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) { + let self_ty = trait_pred.self_ty(); + // FreshTy is used as trait_object_dummy_self and should not reach has_trivial_sizedness + if matches!( + self_ty.kind(), + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + ) { + return false; + } + + if self_ty.has_trivial_sizedness(tcx, sizedness) { debug!("fast path -- trivial sizedness"); return true; } diff --git a/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.rs b/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.rs new file mode 100644 index 0000000000000..ea49026181a6f --- /dev/null +++ b/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.rs @@ -0,0 +1,15 @@ +// Fixes #151709 +//@ compile-flags: -Znext-solver=globally + +trait A { + type Ty; + const CT: Self::Ty; +} + +fn main() { + let _: &dyn A = &(); + //~^ ERROR associated const equality is incomplete + //~| ERROR the trait `A` is not dyn compatible + //~| ERROR the size for values of type `FreshTy(0)` cannot be known + //~| ERROR the trait bound `FreshTy(0): A` is not satisfied +} diff --git a/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.stderr b/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.stderr new file mode 100644 index 0000000000000..e57e06feae53f --- /dev/null +++ b/tests/ui/traits/next-solver/fresh-ty-has-trivial-sizedness.stderr @@ -0,0 +1,59 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/fresh-ty-has-trivial-sizedness.rs:12:29 + | +LL | let _: &dyn A = &(); + | ^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0038]: the trait `A` is not dyn compatible + --> $DIR/fresh-ty-has-trivial-sizedness.rs:12:17 + | +LL | let _: &dyn A = &(); + | ^^^^^^^^^^^^^^^^^^^ `A` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/fresh-ty-has-trivial-sizedness.rs:8:11 + | +LL | trait A { + | - this trait is not dyn compatible... +LL | type Ty; +LL | const CT: Self::Ty; + | ^^ ...because it contains this associated `const` + = help: consider moving `CT` to another trait + +error[E0277]: the size for values of type `FreshTy(0)` cannot be known + --> $DIR/fresh-ty-has-trivial-sizedness.rs:12:34 + | +LL | let _: &dyn A = &(); + | ^ doesn't have a known size + | + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `FreshTy(0)` +note: required by a bound in `A` + --> $DIR/fresh-ty-has-trivial-sizedness.rs:6:1 + | +LL | / trait A { +LL | | type Ty; +LL | | const CT: Self::Ty; +LL | | } + | |_^ required by this bound in `A` + +error[E0277]: the trait bound `FreshTy(0): A` is not satisfied + --> $DIR/fresh-ty-has-trivial-sizedness.rs:12:34 + | +LL | let _: &dyn A = &(); + | ^ the trait `A` is not implemented for `FreshTy(0)` + | +help: this trait has no implementations, consider adding one + --> $DIR/fresh-ty-has-trivial-sizedness.rs:6:1 + | +LL | trait A { + | ^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0038, E0277, E0658. +For more information about an error, try `rustc --explain E0038`.