Skip to content

Commit d1720e2

Browse files
committed
Add pattern types to the compiler
1 parent e187f88 commit d1720e2

File tree

55 files changed

+342
-28
lines changed

Some content is hidden

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

55 files changed

+342
-28
lines changed

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ fn push_debuginfo_type_name<'tcx>(
194194
}
195195
}
196196
}
197+
ty::Pat(inner_type, pat) => {
198+
if cpp_like_debuginfo {
199+
output.push_str("pat$<");
200+
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
201+
write!(output, ",{:?}>", pat).unwrap();
202+
} else {
203+
write!(output, "{:?}", t).unwrap();
204+
}
205+
}
197206
ty::Slice(inner_type) => {
198207
if cpp_like_debuginfo {
199208
output.push_str("slice2$<");

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
9696
Ok(ty::ValTree::Leaf(val.assert_int()))
9797
}
9898

99+
ty::Pat(..) => const_to_valtree_inner(ecx, &ecx.mplace_field(&place, 0).unwrap(), num_nodes),
100+
99101
// Raw pointers are not allowed in type level constants, as we cannot properly test them for
100102
// equality at compile-time (see `ptr_guaranteed_cmp`).
101103
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
@@ -265,7 +267,7 @@ pub fn valtree_to_const_value<'tcx>(
265267
let (param_env, ty) = param_env_ty.into_parts();
266268
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
267269

268-
match ty.kind() {
270+
match *ty.kind() {
269271
ty::FnDef(..) => {
270272
assert!(valtree.unwrap_branch().is_empty());
271273
ConstValue::ZeroSized
@@ -276,6 +278,7 @@ pub fn valtree_to_const_value<'tcx>(
276278
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
277279
),
278280
},
281+
ty::Pat(ty, _) => valtree_to_const_value(tcx, param_env.and(ty), valtree),
279282
ty::Ref(_, _, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
280283
let mut place = match ty.kind() {
281284
ty::Ref(_, inner_ty, _) => {

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
8383
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
8484
throw_inval!(TooGeneric)
8585
}
86+
ty::Pat(..) => {
87+
unimplemented!("pattern types need to calculate pattern from their pattern")
88+
}
8689
ty::Bound(_, _) => bug!("bound ty during ctfe"),
8790
ty::Bool
8891
| ty::Char

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
584584
// Nothing to check.
585585
Ok(true)
586586
}
587+
ty::Pat(..) => unimplemented!(),
587588
// The above should be all the primitive types. The rest is compound, we
588589
// check them by visiting their fields/variants.
589590
ty::Adt(..)

compiler/rustc_const_eval/src/util/type_name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
4040
| ty::Uint(_)
4141
| ty::Float(_)
4242
| ty::Str
43+
| ty::Pat(_, _)
4344
| ty::Array(_, _)
4445
| ty::Slice(_)
4546
| ty::RawPtr(_)

compiler/rustc_error_messages/locales/en-US/lint.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab
237237
lint_improper_ctypes_char_reason = the `char` type has no C equivalent
238238
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
239239
240+
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
241+
lint_improper_ctypes_pat_help = consider using the patterned type instead
242+
240243
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
241244
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
242245

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ impl<'tcx> InherentCollect<'tcx> {
208208
.note("define and implement a new trait or type instead")
209209
.emit();
210210
}
211+
ty::Pat(..) => {
212+
self.tcx.sess.span_err(ty.span, "cannot define inherent `impl` for pattern types");
213+
}
211214
ty::Bool
212215
| ty::Char
213216
| ty::Int(_)

compiler/rustc_hir_analysis/src/variance/constraints.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
231231
self.add_constraints_from_ty(current, typ, variance);
232232
}
233233

234+
ty::Pat(typ, pat) => {
235+
match *pat {
236+
ty::PatternKind::Range { start, end } => {
237+
self.add_constraints_from_const(current, start, variance);
238+
self.add_constraints_from_const(current, end, variance);
239+
}
240+
}
241+
self.add_constraints_from_ty(current, typ, variance);
242+
}
243+
234244
ty::Slice(typ) => {
235245
self.add_constraints_from_ty(current, typ, variance);
236246
}

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
132132
| ty::GeneratorWitness(..)
133133
| ty::RawPtr(_)
134134
| ty::Ref(..)
135+
| ty::Pat(..)
135136
| ty::FnDef(..)
136137
| ty::FnPtr(..)
137138
| ty::Closure(..)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
454454
| ty::Tuple(..)
455455
| ty::Alias(..)
456456
| ty::Foreign(..)
457+
| ty::Pat(..)
457458
| ty::Param(..) => {
458459
if t.flags().intersects(self.needs_canonical_flags) {
459460
t.super_fold_with(self)

compiler/rustc_infer/src/infer/freshen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
201201
| ty::RawPtr(..)
202202
| ty::Ref(..)
203203
| ty::FnDef(..)
204+
| ty::Pat(..)
204205
| ty::FnPtr(_)
205206
| ty::Dynamic(..)
206207
| ty::Never

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ fn compute_components<'tcx>(
9292
}
9393
}
9494

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

compiler/rustc_lint/src/types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
999999
help: Some(fluent::lint_improper_ctypes_char_help),
10001000
},
10011001

1002+
ty::Pat(..) => FfiUnsafe {
1003+
ty,
1004+
reason: fluent::lint_improper_ctypes_pat_reason,
1005+
help: Some(fluent::lint_improper_ctypes_pat_help),
1006+
},
1007+
10021008
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
10031009
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }
10041010
}

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ macro_rules! arena_types {
9999
[] tys: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::TyKind<'tcx>>,
100100
[] predicates: rustc_type_ir::WithCachedTypeInfo<rustc_middle::ty::PredicateKind<'tcx>>,
101101
[] consts: rustc_middle::ty::ConstData<'tcx>,
102+
[] pats: rustc_middle::ty::PatternKind<'tcx>,
102103

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

compiler/rustc_middle/src/ty/codec.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Const<'tcx> {
139139
}
140140
}
141141

142+
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Pattern<'tcx> {
143+
fn encode(&self, e: &mut E) {
144+
self.0.0.encode(e);
145+
}
146+
}
147+
142148
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ConstAllocation<'tcx> {
143149
fn encode(&self, e: &mut E) {
144150
self.inner().encode(e)
@@ -315,6 +321,12 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Const<'tcx> {
315321
}
316322
}
317323

324+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Pattern<'tcx> {
325+
fn decode(decoder: &mut D) -> Self {
326+
decoder.interner().mk_pat(Decodable::decode(decoder))
327+
}
328+
}
329+
318330
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
319331
fn decode(decoder: &mut D) -> &'tcx Self {
320332
decoder.interner().arena.alloc_from_iter(

compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use crate::ty::query::{self, TyCtxtAt};
1919
use crate::ty::{
2020
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
2121
FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
22-
ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind,
23-
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy,
24-
Visibility,
22+
ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
23+
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut,
24+
TypeckResults, UintTy, Visibility,
2525
};
2626
use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
2727
use rustc_ast as ast;
@@ -96,6 +96,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
9696
type SubstsRef = ty::SubstsRef<'tcx>;
9797
type DefId = DefId;
9898
type Ty = Ty<'tcx>;
99+
type Pat = Pattern<'tcx>;
99100
type Const = ty::Const<'tcx>;
100101
type Region = Region<'tcx>;
101102
type TypeAndMut = TypeAndMut<'tcx>;
@@ -140,6 +141,7 @@ pub struct CtxtInterners<'tcx> {
140141
projs: InternedSet<'tcx, List<ProjectionKind>>,
141142
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
142143
const_: InternedSet<'tcx, ConstData<'tcx>>,
144+
pat: InternedSet<'tcx, PatternKind<'tcx>>,
143145
const_allocation: InternedSet<'tcx, Allocation>,
144146
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
145147
layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
@@ -161,6 +163,7 @@ impl<'tcx> CtxtInterners<'tcx> {
161163
projs: Default::default(),
162164
place_elems: Default::default(),
163165
const_: Default::default(),
166+
pat: Default::default(),
164167
const_allocation: Default::default(),
165168
bound_variable_kinds: Default::default(),
166169
layout: Default::default(),
@@ -1196,6 +1199,7 @@ macro_rules! nop_list_lift {
11961199
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
11971200
nop_lift! {region; Region<'a> => Region<'tcx>}
11981201
nop_lift! {const_; Const<'a> => Const<'tcx>}
1202+
nop_lift! {pat; Pattern<'a> => Pattern<'tcx>}
11991203
nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
12001204
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
12011205

@@ -1483,6 +1487,7 @@ impl<'tcx> TyCtxt<'tcx> {
14831487
Param,
14841488
Infer,
14851489
Alias,
1490+
Pat,
14861491
Foreign
14871492
)?;
14881493

@@ -1609,6 +1614,7 @@ macro_rules! direct_interners {
16091614
direct_interners! {
16101615
region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
16111616
const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
1617+
pat: mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
16121618
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
16131619
layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
16141620
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,

compiler/rustc_middle/src/ty/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ impl<'tcx> Ty<'tcx> {
287287
}
288288
"array".into()
289289
}
290+
ty::Pat(ty, _) if ty.is_simple_ty() => format!("pattern `{}`", self).into(),
291+
ty::Pat(..) => "pattern".into(),
290292
ty::Slice(ty) if ty.is_simple_ty() => format!("slice `{}`", self).into(),
291293
ty::Slice(_) => "slice".into(),
292294
ty::RawPtr(tymut) => {
@@ -363,6 +365,7 @@ impl<'tcx> Ty<'tcx> {
363365
ty::Adt(def, _) => def.descr().into(),
364366
ty::Foreign(_) => "extern type".into(),
365367
ty::Array(..) => "array".into(),
368+
ty::Pat(..) => "pattern type".into(),
366369
ty::Slice(_) => "slice".into(),
367370
ty::RawPtr(_) => "raw pointer".into(),
368371
ty::Ref(.., mutbl) => match mutbl {

compiler/rustc_middle/src/ty/fast_reject.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub enum SimplifiedType {
2121
StrSimplifiedType,
2222
ArraySimplifiedType,
2323
SliceSimplifiedType,
24+
PatSimplifiedType,
2425
RefSimplifiedType(Mutability),
2526
PtrSimplifiedType(Mutability),
2627
NeverSimplifiedType,
@@ -97,6 +98,7 @@ pub fn simplify_type<'tcx>(
9798
ty::Str => Some(StrSimplifiedType),
9899
ty::Array(..) => Some(ArraySimplifiedType),
99100
ty::Slice(..) => Some(SliceSimplifiedType),
101+
ty::Pat(..) => Some(PatSimplifiedType),
100102
ty::RawPtr(ptr) => Some(PtrSimplifiedType(ptr.mutbl)),
101103
ty::Dynamic(trait_info, ..) => match trait_info.principal_def_id() {
102104
Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => {
@@ -199,6 +201,7 @@ impl DeepRejectCtxt {
199201
| ty::Slice(..)
200202
| ty::RawPtr(..)
201203
| ty::Dynamic(..)
204+
| ty::Pat(..)
202205
| ty::Ref(..)
203206
| ty::Never
204207
| ty::Tuple(..)
@@ -238,6 +241,9 @@ impl DeepRejectCtxt {
238241
}
239242
_ => false,
240243
},
244+
ty::Pat(obl_ty, _) => {
245+
matches!(k, &ty::Pat(impl_ty, _) if self.types_may_unify(obl_ty, impl_ty))
246+
}
241247
ty::Slice(obl_ty) => {
242248
matches!(k, &ty::Slice(impl_ty) if self.types_may_unify(obl_ty, impl_ty))
243249
}

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,20 @@ impl FlagComputation {
195195
self.add_const(len);
196196
}
197197

198+
&ty::Pat(ty, pat) => {
199+
self.add_ty(ty);
200+
match *pat {
201+
ty::PatternKind::Range { start, end, include_end: _ } => {
202+
if let Some(start) = start {
203+
self.add_const(start)
204+
}
205+
if let Some(end) = end {
206+
self.add_const(end)
207+
}
208+
}
209+
}
210+
}
211+
198212
&ty::Slice(tt) => self.add_ty(tt),
199213

200214
ty::RawPtr(m) => {

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ where
646646
| ty::FnDef(..)
647647
| ty::GeneratorWitness(..)
648648
| ty::Foreign(..)
649+
| ty::Pat(_, _)
649650
| ty::Dynamic(_, _, ty::Dyn) => {
650651
bug!("TyAndLayout::field({:?}): not applicable", this)
651652
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub use self::context::{
8888
pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams};
8989
pub use self::list::List;
9090
pub use self::parameterized::ParameterizedOverTcx;
91+
pub use self::pattern::{Pattern, PatternKind};
9192
pub use self::rvalue_scopes::RvalueScopes;
9293
pub use self::sty::BoundRegionKind::*;
9394
pub use self::sty::{
@@ -119,6 +120,7 @@ pub mod fold;
119120
pub mod inhabitedness;
120121
pub mod layout;
121122
pub mod normalize_erasing_regions;
123+
pub mod pattern;
122124
pub mod print;
123125
pub mod query;
124126
pub mod relate;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std::fmt;
2+
3+
use crate::ty;
4+
use rustc_data_structures::intern::Interned;
5+
6+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
7+
#[rustc_pass_by_value]
8+
pub struct Pattern<'tcx>(pub Interned<'tcx, PatternKind<'tcx>>);
9+
10+
impl<'tcx> std::ops::Deref for Pattern<'tcx> {
11+
type Target = PatternKind<'tcx>;
12+
13+
fn deref(&self) -> &Self::Target {
14+
&*self.0
15+
}
16+
}
17+
18+
impl<'tcx> fmt::Debug for Pattern<'tcx> {
19+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20+
write!(f, "{:?}", **self)
21+
}
22+
}
23+
24+
impl<'tcx> fmt::Debug for PatternKind<'tcx> {
25+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26+
match *self {
27+
PatternKind::Range { start, end, include_end } => {
28+
if let Some(start) = start {
29+
write!(f, "{start}")?;
30+
}
31+
write!(f, "..")?;
32+
if include_end {
33+
write!(f, "=")?;
34+
}
35+
if let Some(end) = end {
36+
write!(f, "{end}")?;
37+
}
38+
Ok(())
39+
}
40+
}
41+
}
42+
}
43+
44+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
45+
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
46+
pub enum PatternKind<'tcx> {
47+
Range { start: ty::Const<'tcx>, end: ty::Const<'tcx> },
48+
}

compiler/rustc_middle/src/ty/print/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ fn characteristic_def_id_of_type_cached<'a>(
247247

248248
ty::Dynamic(data, ..) => data.principal_def_id(),
249249

250-
ty::Array(subty, _) | ty::Slice(subty) => {
250+
ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
251251
characteristic_def_id_of_type_cached(subty, visited)
252252
}
253253

0 commit comments

Comments
 (0)