diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 59f0fac5aa76f..8c9852a29590a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2223,6 +2223,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Err(LitToConstError::TypeError) => todo!(), } } + + hir::ExprKind::Path(hir::QPath::Resolved( + _, + &hir::Path { + res: Res::Def(DefKind::ConstParam, def_id), .. + }, + )) => { + let ty = tcx.type_of(def_id).instantiate_identity(); + let item_def_id = tcx.parent(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.item_name(def_id); + ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty) + } + _ => { let err = tcx .dcx() diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 50e68bfdbe7eb..342674241920f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -312,6 +312,11 @@ impl<'tcx> SizeSkeleton<'tcx> { ) -> Result, &'tcx LayoutError<'tcx>> { debug_assert!(!ty.has_non_region_infer()); + let ty = match *ty.kind() { + ty::Pat(inner_ty, pat) if matches!(*pat, ty::PatternKind::Range { .. }) => inner_ty, + _ => ty, + }; + // First try computing a static layout. let err = match tcx.layout_of(param_env.and(ty)) { Ok(layout) => { diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 77cd4662ae575..902b76e8c1e26 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -133,10 +133,14 @@ fn layout_of_uncached<'tcx>( ty::PatternKind::Range { start, end, include_end } => { if let Abi::Scalar(scalar) | Abi::ScalarPair(scalar, _) = &mut layout.abi { if let Some(start) = start { - scalar.valid_range_mut().start = start.eval_bits(tcx, param_env); + scalar.valid_range_mut().start = start + .try_eval_bits(tcx, param_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { - let mut end = end.eval_bits(tcx, param_env); + let mut end = end + .try_eval_bits(tcx, param_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { end = end.wrapping_sub(1); } diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs index 534cc430a6435..5bc6fd54e0fce 100644 --- a/tests/ui/type/pattern_types/const_generics.rs +++ b/tests/ui/type/pattern_types/const_generics.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(pattern_types)] #![feature(core_pattern_types)] #![feature(core_pattern_type)] @@ -7,7 +9,5 @@ use std::pat::pattern_type; trait Foo {} impl Foo for pattern_type!(u32 is START..=END) {} -//~^ ERROR: range patterns must have constant range start and end -//~| ERROR: range patterns must have constant range start and end fn main() {} diff --git a/tests/ui/type/pattern_types/const_generics.stderr b/tests/ui/type/pattern_types/const_generics.stderr deleted file mode 100644 index ce415ea05ba3a..0000000000000 --- a/tests/ui/type/pattern_types/const_generics.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: "range patterns must have constant range start and end" - --> $DIR/const_generics.rs:9:69 - | -LL | impl Foo for pattern_type!(u32 is START..=END) {} - | ^^^^^ - -error: "range patterns must have constant range start and end" - --> $DIR/const_generics.rs:9:77 - | -LL | impl Foo for pattern_type!(u32 is START..=END) {} - | ^^^ - -error: aborting due to 2 previous errors -