1
Fork 0

Avoid having to handle an Option in the type system

This commit is contained in:
Oli Scherer 2025-02-05 15:22:10 +00:00
parent 4f2b108816
commit 0e7b283573
21 changed files with 146 additions and 109 deletions

View file

@ -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> {

View file

@ -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);