diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 53bc9eb7e46..54cd8cc3efe 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -12,7 +12,7 @@ use std::borrow::Cow; use std::hash::{Hash, Hasher}; use std::sync::Arc; -use rustc_errors::{Applicability, Diag, EmissionGuarantee}; +use rustc_errors::{Applicability, Diag, EmissionGuarantee, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::DefId; @@ -996,4 +996,7 @@ pub enum CodegenObligationError { /// but was included during typeck due to the trivial_bounds feature. Unimplemented, FulfillmentError, + /// The selected impl has unconstrained generic parameters. This will emit an error + /// during impl WF checking. + UnconstrainedParam(ErrorGuaranteed), } diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index e5276e6d515..cc329ca3328 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -80,16 +80,14 @@ pub(crate) fn codegen_select_candidate<'tcx>( // but never resolved, causing the return value of a query to contain inference // vars. We do not have a concept for this and will in fact ICE in stable hashing // of the return value. So bail out instead. - match impl_source { - ImplSource::UserDefined(impl_) => { - tcx.dcx().span_delayed_bug( - tcx.def_span(impl_.impl_def_id), - "this impl has unconstrained generic parameters", - ); - } + let guar = match impl_source { + ImplSource::UserDefined(impl_) => tcx.dcx().span_delayed_bug( + tcx.def_span(impl_.impl_def_id), + "this impl has unconstrained generic parameters", + ), _ => unreachable!(), - } - return Err(CodegenObligationError::FulfillmentError); + }; + return Err(CodegenObligationError::UnconstrainedParam(guar)); } Ok(&*tcx.arena.alloc(impl_source)) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 8c6e3c86bf5..d059d6dcd13 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -112,6 +112,7 @@ fn resolve_associated_item<'tcx>( | CodegenObligationError::Unimplemented | CodegenObligationError::FulfillmentError, ) => return Ok(None), + Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar), }; // Now that we know which impl is being used, we can dispatch to diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index d460fc64f1f..c9b1e0a4b9e 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -15,4 +15,4 @@ impl A for u8 { //~ ERROR: the type parameter `C` is not constrained } #[rustc_layout(debug)] -struct S([u8; ::B]); //~ ERROR: the type `[u8; ::B]` has an unknown layout +struct S([u8; ::B]); //~ ERROR: the type has an unknown layout diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 03ee941d37e..615c131eb90 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -4,7 +4,7 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self LL | impl A for u8 { | ^ unconstrained type parameter -error: the type `[u8; ::B]` has an unknown layout +error: the type has an unknown layout --> $DIR/unconstrained-param-ice-137308.rs:18:1 | LL | struct S([u8; ::B]);