diff options
| author | Oli Scherer <github333195615777966@oli-obk.de> | 2025-02-05 15:22:10 +0000 |
|---|---|---|
| committer | Oli Scherer <github333195615777966@oli-obk.de> | 2025-03-06 10:03:11 +0000 |
| commit | 0e7b2835735fc7fee08505fa6c14670bc7ee7601 (patch) | |
| tree | 66e56105fd9b954d4217c828bf865929b6b8f0c2 /compiler/rustc_hir_analysis/src | |
| parent | 4f2b108816e782f68d5964bec74448c04bd36ac5 (diff) | |
| download | rust-0e7b2835735fc7fee08505fa6c14670bc7ee7601.tar.gz rust-0e7b2835735fc7fee08505fa6c14670bc7ee7601.zip | |
Avoid having to handle an `Option` in the type system
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 89 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/variance/constraints.rs | 8 |
2 files changed, 80 insertions, 17 deletions
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 fe446492aca..21581d304d9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -21,8 +21,9 @@ pub mod generics; mod lint; use std::assert_matches::assert_matches; -use std::slice; +use std::{char, slice}; +use rustc_abi::Size; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; @@ -31,7 +32,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; +use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; @@ -2693,20 +2694,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = self.lower_ty(ty); let pat_ty = match pat.kind { hir::TyPatKind::Range(start, end, include_end) => { - let ty = match ty.kind() { - ty::Int(_) | ty::Uint(_) | ty::Char => ty, - _ => Ty::new_error( - tcx, - self.dcx().emit_err(InvalidBaseType { + let (ty, start, end) = match ty.kind() { + ty::Int(_) | ty::Uint(_) | ty::Char => { + let (start, end) = self.lower_ty_pat_range(ty, start, end); + (ty, start, end) + } + _ => { + let guar = self.dcx().emit_err(InvalidBaseType { ty, pat: "range", ty_span, pat_span: pat.span, - }), - ), + }); + let errc = ty::Const::new_error(tcx, guar); + (Ty::new_error(tcx, guar), errc, errc) + } }; - let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); - let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end }); Ty::new_pat(tcx, ty, pat) @@ -2723,6 +2726,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { result_ty } + fn lower_ty_pat_range( + &self, + base: Ty<'tcx>, + start: Option<&ConstArg<'tcx>>, + end: Option<&ConstArg<'tcx>>, + ) -> (ty::Const<'tcx>, ty::Const<'tcx>) { + let tcx = self.tcx(); + let size = match base.kind() { + ty::Int(i) => { + i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) + } + ty::Uint(ui) => { + ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits)) + } + ty::Char => Size::from_bytes(4), + _ => unreachable!(), + }; + let start = + start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| { + match base.kind() { + ty::Char | ty::Uint(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)), + base, + ), + ty::Int(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0, + ), + base, + ), + _ => unreachable!(), + } + }); + let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else( + || match base.kind() { + ty::Char => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_uint(char::MAX, size).0, + ), + base, + ), + ty::Uint(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0, + ), + base, + ), + ty::Int(_) => ty::Const::new_value( + tcx, + ty::ValTree::from_scalar_int( + ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0, + ), + base, + ), + _ => unreachable!(), + }, + ); + (start, end) + } + /// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR. #[instrument(level = "debug", skip(self), ret)] fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index e954d2b9ea4..4b336769cfb 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -253,12 +253,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::Pat(typ, pat) => { match *pat { ty::PatternKind::Range { start, end, include_end: _ } => { - if let Some(start) = start { - self.add_constraints_from_const(current, start, variance); - } - if let Some(end) = end { - self.add_constraints_from_const(current, end, variance); - } + self.add_constraints_from_const(current, start, variance); + self.add_constraints_from_const(current, end, variance); } } self.add_constraints_from_ty(current, typ, variance); |
