Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern types MVP #107606

Closed
wants to merge 13 commits into from
3 changes: 3 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2102,6 +2102,9 @@ pub enum TyKind {
Err,
/// Placeholder for a `va_list`.
CVarArgs,
/// Pattern types like `u32 as 1..=`, which is the same as `NonZeroU32`,
/// just as part of the type system.
Comment on lines +2105 to +2106
Copy link

@shua shua Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is supposed to be "is" or "as", but it seems like "is" is used everywhere else

Suggested change
/// Pattern types like `u32 as 1..=`, which is the same as `NonZeroU32`,
/// just as part of the type system.
/// Pattern types like `u32 is 1..=`, which is the same as `NonZeroU32`,
/// just as part of the type system.

Pat(P<Ty>, P<Pat>),
}

impl TyKind {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,10 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
}
TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
TyKind::Paren(ty) => vis.visit_ty(ty),
TyKind::Pat(ty, pat) => {
vis.visit_ty(ty);
vis.visit_pat(pat);
}
TyKind::Path(qself, path) => {
vis.visit_qself(qself);
vis.visit_path(path);
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
}
visitor.visit_path(path, typ.id);
}
TyKind::Pat(ty, pat) => {
visitor.visit_ty(ty);
visitor.visit_pat(pat);
}
TyKind::Array(ty, length) => {
visitor.visit_ty(ty);
visitor.visit_anon_const(length)
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,14 +1372,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
}
TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
TyKind::MacCall(_) => {
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
}
TyKind::CVarArgs => {
self.tcx.sess.delay_span_bug(
t.span,
"`TyKind::CVarArgs` should have been handled elsewhere",
);
hir::TyKind::Err
}
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
};

hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::TyKind::TraitObject(_, ast::TraitObjectSyntax::DynStar, ..) => {
gate_feature_post!(&self, dyn_star, ty.span, "dyn* trait objects are unstable");
}
ast::TyKind::Pat(..) => {
gate_feature_post!(&self, pattern_types, ty.span, "pattern types are unstable");
}
_ => {}
}
visit::walk_ty(self, ty)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,11 @@ impl<'a> State<'a> {
ast::TyKind::CVarArgs => {
self.word("...");
}
ast::TyKind::Pat(ty, pat) => {
self.print_type(ty);
self.word(" is ");
self.print_pat(pat);
}
}
self.end();
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ fn push_debuginfo_type_name<'tcx>(
}
}
}
ty::Pat(inner_type, pat) => {
if cpp_like_debuginfo {
output.push_str("pat$<");
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
write!(output, ",{:?}>", pat).unwrap();
} else {
write!(output, "{:?}", t).unwrap();
}
}
ty::Slice(inner_type) => {
if cpp_like_debuginfo {
output.push_str("slice2$<");
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
Ok(ty::ValTree::Leaf(val.assert_int()))
}

ty::Pat(..) => const_to_valtree_inner(ecx, &ecx.mplace_field(&place, 0).unwrap(), num_nodes),

// Raw pointers are not allowed in type level constants, as we cannot properly test them for
// equality at compile-time (see `ptr_guaranteed_cmp`).
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
Expand Down Expand Up @@ -265,7 +267,7 @@ pub fn valtree_to_const_value<'tcx>(
let (param_env, ty) = param_env_ty.into_parts();
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);

match ty.kind() {
match *ty.kind() {
ty::FnDef(..) => {
assert!(valtree.unwrap_branch().is_empty());
ConstValue::ZeroSized
Expand All @@ -276,6 +278,7 @@ pub fn valtree_to_const_value<'tcx>(
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
),
},
ty::Pat(ty, _) => valtree_to_const_value(tcx, param_env.and(ty), valtree),
ty::Ref(_, _, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
let mut place = match ty.kind() {
ty::Ref(_, inner_ty, _) => {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
throw_inval!(TooGeneric)
}
ty::Pat(..) => {
unimplemented!("pattern types need to calculate pattern from their pattern")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My confusion about this error message remains.^^ Who's asking for a pattern to be computed from anything here? We just want a variant count! What does it even mean to compute a pattern from a pattern? Seems trivial, just use the identity function...

}
ty::Bound(_, _) => bug!("bound ty during ctfe"),
ty::Bool
| ty::Char
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// Nothing to check.
Ok(true)
}
ty::Pat(..) => unimplemented!(),
// The above should be all the primitive types. The rest is compound, we
// check them by visiting their fields/variants.
ty::Adt(..)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::Pat(_, _)
| ty::Array(_, _)
| ty::Slice(_)
| ty::RawPtr(_)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,8 @@ hir_analysis_linkage_type =
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
.label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)

hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pattern types"
.label = "this type is the same as the inner type without a pattern"

hir_analysis_pattern_type_non_const_range = "range patterns must have constant range start and end"
Comment on lines +128 to +131
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pattern types"
.label = "this type is the same as the inner type without a pattern"
hir_analysis_pattern_type_non_const_range = "range patterns must have constant range start and end"
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
.label = this type is the same as the inner type without a pattern
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end

3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/lint.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab
lint_improper_ctypes_char_reason = the `char` type has no C equivalent
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead

lint_improper_ctypes_pat_reason = pattern types have no C equivalent
lint_improper_ctypes_pat_help = consider using the patterned type instead

lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ declare_features! (
(active, object_safe_for_dispatch, "1.40.0", Some(43561), None),
/// Allows using `#[optimize(X)]`.
(active, optimize_attribute, "1.34.0", Some(54882), None),
/// Allows using pattern types.
(incomplete, pattern_types, "CURRENT_RUSTC_VERSION", Some(54882), None),
/// Allows `extern "platform-intrinsic" { ... }`.
(active, platform_intrinsics, "1.4.0", Some(27731), None),
/// Allows using `#![plugin(myplugin)]`.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ pub struct InferArg {
}

impl InferArg {
pub fn to_ty(&self) -> Ty<'_> {
pub fn to_ty(&self) -> Ty<'static> {
Ty { kind: TyKind::Infer, span: self.span, hir_id: self.hir_id }
}
}
Expand Down Expand Up @@ -2682,6 +2682,8 @@ pub enum TyKind<'hir> {
Infer,
/// Placeholder for a type that has failed to be defined.
Err,
/// Pattern types (`u32 as 1..`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Pattern types (`u32 as 1..`)
/// Pattern types (`u32 is 1..`)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not u32 @ 1..?

Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
}

#[derive(Debug, HashStable_Generic)]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
}
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
TyKind::Infer | TyKind::Err => {}
TyKind::Pat(ty, pat) => {
visitor.visit_ty(ty);
visitor.visit_pat(pat)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn generic_arg_mismatch_err(
/// instantiate a `GenericArg`.
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
/// creates a suitable inference variable.
pub fn create_substs_for_generic_args<'tcx, 'a>(
pub fn create_substs_for_generic_args<'tcx: 'a, 'a>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
parent_substs: &[subst::GenericArg<'tcx>],
Expand Down
Loading