diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 13f95024e5a67..9eb27e30fd46c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1557,7 +1557,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id ty::ConstKind::Unevaluated(uv) => { infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) } - ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(wfcx.param_env), + ty::ConstKind::Param(param_ct) => { + param_ct.find_ty_from_env(wfcx.param_env).unwrap() + } }; let param_ty = tcx.type_of(param.def_id).instantiate_identity(); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 58829f72a72f0..d3773a8e47034 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -346,7 +346,7 @@ impl ParamConst { } #[instrument(level = "debug")] - pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { + pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Option> { let mut candidates = env.caller_bounds().iter().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. match clause.kind().skip_binder() { @@ -362,9 +362,9 @@ impl ParamConst { } }); - let ty = candidates.next().unwrap(); + let ty = candidates.next()?; assert!(candidates.next().is_none()); - ty + Some(ty) } } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 36a8ae675c0ea..8e5250f9bc55f 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -39,7 +39,9 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>( ty::ConstKind::Unevaluated(uv) => { infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) } - ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env), + ty::ConstKind::Param(param_ct) => { + param_ct.find_ty_from_env(obligation.param_env).unwrap() + } ty::ConstKind::Value(cv) => cv.ty, kind => span_bug!( obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 951dfb879aed7..6d68be3e688f9 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -11,7 +11,7 @@ use rustc_infer::traits::{ use rustc_middle::bug; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, Ty, TypeVisitableExt, TypingMode}; use thin_vec::ThinVec; use tracing::{debug, debug_span, instrument}; @@ -507,7 +507,16 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct), ty::ConstKind::Param(param_ct) => { - param_ct.find_ty_from_env(obligation.param_env) + let Some(ty) = param_ct.find_ty_from_env(obligation.param_env) else { + return ProcessResult::Error(FulfillmentErrorCode::Select( + SelectionError::ConstArgHasWrongType { + ct, + ct_ty: Ty::new_misc_error(self.selcx.tcx()), + expected_ty: ty, + }, + )); + }; + ty } }; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9c0ccb26e53f6..a27415e019c55 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -979,7 +979,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct), ty::ConstKind::Param(param_ct) => { - param_ct.find_ty_from_env(obligation.param_env) + let Some(ty) = param_ct.find_ty_from_env(obligation.param_env) else { + return Ok(EvaluatedToErr); + }; + ty } }; diff --git a/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.rs b/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.rs new file mode 100644 index 0000000000000..a53a01ef7267e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.rs @@ -0,0 +1,11 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs, adt_const_params)] +struct X< + const FN: () = { + || { + let _: [(); B]; //~ ERROR cannot find value `B` in this scope + //~^ ERROR the constant `FN` is not of type `()` + }; + }, +>; +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.stderr b/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.stderr new file mode 100644 index 0000000000000..3a9af6b126369 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/missing_param_ty_while_evaluating_const_param.stderr @@ -0,0 +1,27 @@ +error[E0425]: cannot find value `B` in this scope + --> $DIR/missing_param_ty_while_evaluating_const_param.rs:6:25 + | +LL | let _: [(); B]; + | ^ not found in this scope + +error: the constant `FN` is not of type `()` + --> $DIR/missing_param_ty_while_evaluating_const_param.rs:6:20 + | +LL | let _: [(); B]; + | ^^^^^^^ expected `()`, found type error + | +note: required by a const generic parameter in `X` + --> $DIR/missing_param_ty_while_evaluating_const_param.rs:4:5 + | +LL | struct X< + | - required by a bound in this struct +LL | / const FN: () = { +LL | | || { +LL | | let _: [(); B]; +... | +LL | | }, + | |_____^ required by this const generic parameter in `X` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`.