about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorOli Scherer <github333195615777966@oli-obk.de>2025-02-05 15:22:10 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-03-06 10:03:11 +0000
commit0e7b2835735fc7fee08505fa6c14670bc7ee7601 (patch)
tree66e56105fd9b954d4217c828bf865929b6b8f0c2 /compiler/rustc_hir_analysis/src
parent4f2b108816e782f68d5964bec74448c04bd36ac5 (diff)
downloadrust-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.rs89
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs8
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);