Skip to content

Commit 910c32f

Browse files
committed
Actually create ranged int types in the type system.
1 parent 6ecf3c6 commit 910c32f

File tree

68 files changed

+530
-50
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+530
-50
lines changed

compiler/rustc_borrowck/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16081608
| ty::Foreign(_)
16091609
| ty::Str
16101610
| ty::Array(_, _)
1611+
| ty::Pat(_, _)
16111612
| ty::Slice(_)
16121613
| ty::FnDef(_, _)
16131614
| ty::FnPtr(_)
@@ -1646,6 +1647,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16461647
| ty::Foreign(_)
16471648
| ty::Str
16481649
| ty::Array(_, _)
1650+
| ty::Pat(_, _)
16491651
| ty::Slice(_)
16501652
| ty::RawPtr(_)
16511653
| ty::Ref(_, _, _)

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+9
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ fn push_debuginfo_type_name<'tcx>(
201201
}
202202
}
203203
}
204+
ty::Pat(inner_type, pat) => {
205+
if cpp_like_debuginfo {
206+
output.push_str("pat$<");
207+
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
208+
write!(output, ",{:?}>", pat).unwrap();
209+
} else {
210+
write!(output, "{:?}", t).unwrap();
211+
}
212+
}
204213
ty::Slice(inner_type) => {
205214
if cpp_like_debuginfo {
206215
output.push_str("slice2$<");

compiler/rustc_const_eval/src/const_eval/valtrees.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
9797
Ok(ty::ValTree::Leaf(val.assert_int()))
9898
}
9999

100+
ty::Pat(..) => const_to_valtree_inner(ecx, &ecx.project_field(place, 0).unwrap(), num_nodes),
101+
100102
ty::RawPtr(_) => {
101103
// Not all raw pointers are allowed, as we cannot properly test them for
102104
// equality at compile-time (see `ptr_guaranteed_cmp`).
@@ -238,7 +240,7 @@ pub fn valtree_to_const_value<'tcx>(
238240

239241
let (param_env, ty) = param_env_ty.into_parts();
240242

241-
match ty.kind() {
243+
match *ty.kind() {
242244
ty::FnDef(..) => {
243245
assert!(valtree.unwrap_branch().is_empty());
244246
mir::ConstValue::ZeroSized
@@ -251,9 +253,10 @@ pub fn valtree_to_const_value<'tcx>(
251253
),
252254
}
253255
}
256+
ty::Pat(ty, _) => valtree_to_const_value(tcx, param_env.and(ty), valtree),
254257
ty::Ref(_, inner_ty, _) => {
255258
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
256-
let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty);
259+
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
257260
let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap());
258261
op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
259262
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10141014

10151015
ty::Tuple(tys) => tys.last().iter().all(|ty| is_very_trivially_sized(**ty)),
10161016

1017+
ty::Pat(ty, ..) => is_very_trivially_sized(*ty),
1018+
10171019
// We don't want to do any queries, so there is not much we can do with ADTs.
10181020
ty::Adt(..) => false,
10191021

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
6969
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
7070
throw_inval!(TooGeneric)
7171
}
72+
ty::Pat(..) => {
73+
unimplemented!("pattern types need to calculate pattern from their pattern")
74+
}
7275
ty::Bound(_, _) => bug!("bound ty during ctfe"),
7376
ty::Bool
7477
| ty::Char

compiler/rustc_const_eval/src/interpret/validity.rs

+1
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
571571
// Nothing to check.
572572
Ok(true)
573573
}
574+
ty::Pat(..) => unimplemented!(),
574575
// The above should be all the primitive types. The rest is compound, we
575576
// check them by visiting their fields/variants.
576577
ty::Adt(..)

compiler/rustc_const_eval/src/util/type_name.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
3131
| ty::Uint(_)
3232
| ty::Float(_)
3333
| ty::Str
34+
| ty::Pat(_, _)
3435
| ty::Array(_, _)
3536
| ty::Slice(_)
3637
| ty::RawPtr(_)

compiler/rustc_hir_analysis/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function
299299
.suggestion = cast the value to `{$cast_ty}`
300300
.help = cast the value to `{$cast_ty}`
301301
302+
hir_analysis_pattern_type_non_const_range = "range patterns must have constant range start and end"
302303
hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pattern types"
303304
.label = "this type is the same as the inner type without a pattern"
304305
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}

compiler/rustc_hir_analysis/src/astconv/mod.rs

+71-19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
2929
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3030
use rustc_infer::traits::ObligationCause;
3131
use rustc_middle::middle::stability::AllowUnstable;
32+
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
3233
use rustc_middle::ty::{
3334
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, IsSuggestable, ParamEnv, Ty,
3435
TyCtxt, TypeVisitableExt,
@@ -2559,25 +2560,76 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25592560
// handled specially and will not descend into this routine.
25602561
self.ty_infer(None, ast_ty.span)
25612562
}
2562-
hir::TyKind::Pat(_ty, pat) => match pat.kind {
2563-
hir::PatKind::Wild => {
2564-
let err = tcx.dcx().emit_err(WildPatTy { span: pat.span });
2565-
Ty::new_error(tcx, err)
2566-
}
2567-
hir::PatKind::Binding(_, _, _, _) => todo!(),
2568-
hir::PatKind::Struct(_, _, _) => todo!(),
2569-
hir::PatKind::TupleStruct(_, _, _) => todo!(),
2570-
hir::PatKind::Or(_) => todo!(),
2571-
hir::PatKind::Path(_) => todo!(),
2572-
hir::PatKind::Tuple(_, _) => todo!(),
2573-
hir::PatKind::Box(_) => todo!(),
2574-
hir::PatKind::Ref(_, _) => todo!(),
2575-
hir::PatKind::Lit(_) => todo!(),
2576-
hir::PatKind::Range(_, _, _) => Ty::new_misc_error(tcx),
2577-
hir::PatKind::Slice(_, _, _) => todo!(),
2578-
hir::PatKind::Never => todo!(),
2579-
hir::PatKind::Err(e) => Ty::new_error(tcx, e),
2580-
},
2563+
hir::TyKind::Pat(ty, pat) => {
2564+
let ty = self.ast_ty_to_ty(ty);
2565+
let pat_ty = match pat.kind {
2566+
hir::PatKind::Wild => {
2567+
let err = tcx.dcx().emit_err(WildPatTy { span: pat.span });
2568+
Ty::new_error(tcx, err)
2569+
}
2570+
hir::PatKind::Binding(_, _, _, _) => todo!(),
2571+
hir::PatKind::Struct(_, _, _) => todo!(),
2572+
hir::PatKind::TupleStruct(_, _, _) => todo!(),
2573+
hir::PatKind::Or(_) => todo!(),
2574+
hir::PatKind::Path(_) => todo!(),
2575+
hir::PatKind::Tuple(_, _) => todo!(),
2576+
hir::PatKind::Box(_) => todo!(),
2577+
hir::PatKind::Ref(_, _) => todo!(),
2578+
hir::PatKind::Lit(_) => todo!(),
2579+
hir::PatKind::Range(start, end, include_end) => {
2580+
let expr_to_const = |expr: &'tcx hir::Expr<'tcx>, neg| -> ty::Const<'tcx> {
2581+
match &expr.kind {
2582+
hir::ExprKind::Lit(lit) => {
2583+
let lit_input = LitToConstInput { lit: &lit.node, ty, neg };
2584+
match tcx.lit_to_const(lit_input) {
2585+
Ok(c) => c,
2586+
Err(LitToConstError::Reported(err)) => {
2587+
ty::Const::new_error(tcx, err, ty)
2588+
}
2589+
Err(LitToConstError::TypeError) => todo!(),
2590+
}
2591+
}
2592+
_ => {
2593+
let err = tcx
2594+
.dcx()
2595+
.emit_err(crate::errors::NonConstRange { span: expr.span });
2596+
ty::Const::new_error(tcx, err, ty)
2597+
}
2598+
}
2599+
};
2600+
let expr_to_const = |expr, neg| {
2601+
let c = expr_to_const(expr, neg);
2602+
self.record_ty(expr.hir_id, c.ty(), expr.span);
2603+
c
2604+
};
2605+
let expr_to_const = |expr: &'tcx hir::Expr<'tcx>| match &expr.kind {
2606+
hir::ExprKind::Unary(hir::UnOp::Neg, expr) => expr_to_const(expr, true),
2607+
_ => expr_to_const(expr, false),
2608+
};
2609+
let expr_to_const = |expr| {
2610+
let c = expr_to_const(expr);
2611+
self.record_ty(expr.hir_id, c.ty(), expr.span);
2612+
c
2613+
};
2614+
2615+
let start = start.map(expr_to_const);
2616+
let end = end.map(expr_to_const);
2617+
2618+
let include_end = match include_end {
2619+
hir::RangeEnd::Included => true,
2620+
hir::RangeEnd::Excluded => false,
2621+
};
2622+
2623+
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
2624+
Ty::new_pat(tcx, ty, pat)
2625+
}
2626+
hir::PatKind::Slice(_, _, _) => todo!(),
2627+
hir::PatKind::Never => todo!(),
2628+
hir::PatKind::Err(e) => Ty::new_error(tcx, e),
2629+
};
2630+
self.record_ty(pat.hir_id, ty, pat.span);
2631+
pat_ty
2632+
}
25812633
hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
25822634
};
25832635

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+5
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ impl<'tcx> InherentCollect<'tcx> {
137137
ty::Dynamic(..) => {
138138
self.tcx.dcx().emit_err(errors::InherentDyn { span: item_span });
139139
}
140+
ty::Pat(..) => {
141+
self.tcx
142+
.dcx()
143+
.span_err(item_span, "cannot define inherent `impl` for pattern types");
144+
}
140145
ty::Bool
141146
| ty::Char
142147
| ty::Int(_)

compiler/rustc_hir_analysis/src/coherence/orphan.rs

+5
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ fn do_orphan_check_impl<'tcx>(
228228
(LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
229229
}
230230

231+
ty::Pat(..) => (
232+
LocalImpl::Disallow { problematic_kind: "pattern type" },
233+
NonlocalImpl::DisallowOther,
234+
),
235+
231236
ty::Bool
232237
| ty::Char
233238
| ty::Int(..)

compiler/rustc_hir_analysis/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1513,3 +1513,10 @@ pub struct NotSupportedDelegation<'a> {
15131513
#[label]
15141514
pub callee_span: Span,
15151515
}
1516+
1517+
#[derive(Diagnostic)]
1518+
#[diag(hir_analysis_pattern_type_non_const_range)]
1519+
pub struct NonConstRange {
1520+
#[primary_span]
1521+
pub span: Span,
1522+
}

compiler/rustc_hir_analysis/src/variance/constraints.rs

+14
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,20 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
249249
self.add_constraints_from_ty(current, typ, variance);
250250
}
251251

252+
ty::Pat(typ, pat) => {
253+
match *pat {
254+
ty::PatternKind::Range { start, end, include_end: _ } => {
255+
if let Some(start) = start {
256+
self.add_constraints_from_const(current, start, variance);
257+
}
258+
if let Some(end) = end {
259+
self.add_constraints_from_const(current, end, variance);
260+
}
261+
}
262+
}
263+
self.add_constraints_from_ty(current, typ, variance);
264+
}
265+
252266
ty::Slice(typ) => {
253267
self.add_constraints_from_ty(current, typ, variance);
254268
}

compiler/rustc_hir_typeck/src/cast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
130130
| ty::CoroutineWitness(..)
131131
| ty::RawPtr(_)
132132
| ty::Ref(..)
133+
| ty::Pat(..)
133134
| ty::FnDef(..)
134135
| ty::FnPtr(..)
135136
| ty::Closure(..)

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+1
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
435435
| ty::Tuple(..)
436436
| ty::Alias(..)
437437
| ty::Foreign(..)
438+
| ty::Pat(..)
438439
| ty::Param(..) => {
439440
if t.flags().intersects(self.needs_canonical_flags) {
440441
t.super_fold_with(self)

compiler/rustc_infer/src/infer/outlives/components.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fn compute_components<'tcx>(
9393
}
9494
}
9595

96+
ty::Pat(element, _) |
9697
ty::Array(element, _) => {
9798
// Don't look into the len const as it doesn't affect regions
9899
compute_components(tcx, element, out, visited);

compiler/rustc_lint/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
274274
275275
lint_improper_ctypes_opaque = opaque types have no C equivalent
276276
277+
lint_improper_ctypes_pat_help = consider using the patterned type instead
278+
279+
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
277280
lint_improper_ctypes_slice_help = consider using a raw pointer instead
278281
279282
lint_improper_ctypes_slice_reason = slices have no C equivalent

compiler/rustc_lint/src/types.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13351335
help: Some(fluent::lint_improper_ctypes_char_help),
13361336
},
13371337

1338+
ty::Pat(..) => FfiUnsafe {
1339+
ty,
1340+
reason: fluent::lint_improper_ctypes_pat_reason,
1341+
help: Some(fluent::lint_improper_ctypes_pat_help),
1342+
},
1343+
13381344
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
13391345
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }
13401346
}

compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ macro_rules! arena_types {
9191
[decode] attribute: rustc_ast::Attribute,
9292
[] name_set: rustc_data_structures::unord::UnordSet<rustc_span::symbol::Symbol>,
9393
[] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::symbol::Symbol>,
94+
[] pats: rustc_middle::ty::PatternKind<'tcx>,
9495

9596
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
9697
// since we need to allocate this type on both the `rustc_hir` arena

compiler/rustc_middle/src/ty/codec.rs

+12
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Const<'tcx> {
147147
}
148148
}
149149

150+
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Pattern<'tcx> {
151+
fn encode(&self, e: &mut E) {
152+
self.0.0.encode(e);
153+
}
154+
}
155+
150156
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ConstAllocation<'tcx> {
151157
fn encode(&self, e: &mut E) {
152158
self.inner().encode(e)
@@ -363,6 +369,12 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Const<'tcx> {
363369
}
364370
}
365371

372+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Pattern<'tcx> {
373+
fn decode(decoder: &mut D) -> Self {
374+
decoder.interner().mk_pat(Decodable::decode(decoder))
375+
}
376+
}
377+
366378
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
367379
fn decode(decoder: &mut D) -> &'tcx Self {
368380
decoder

0 commit comments

Comments
 (0)