Skip to content

Commit 6eb7777

Browse files
Merge pull request #22082 from Veykril/push-plvylxqznwky
Implement `pattern_type` macro
2 parents 43e7434 + 5cdd149 commit 6eb7777

36 files changed

Lines changed: 649 additions & 146 deletions

File tree

crates/hir-def/src/expr_store.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ impl ExpressionStore {
616616
visitor.on_expr_opt(*end);
617617
}
618618
Pat::Lit(expr) | Pat::ConstBlock(expr) | Pat::Expr(expr) => visitor.on_expr(*expr),
619-
Pat::Path(_) | Pat::Wild | Pat::Missing | Pat::Rest => {}
619+
Pat::Path(_) | Pat::Wild | Pat::Missing | Pat::Rest | Pat::NotNull => {}
620620
&Pat::Bind { subpat, id: _ } => visitor.on_pat_opt(subpat),
621621
Pat::Or(args) | Pat::Tuple { args, ellipsis: _ } => visitor.on_pats(args),
622622
Pat::TupleStruct { args, ellipsis: _, path } => {
@@ -855,6 +855,10 @@ impl ExpressionStore {
855855
pub fn visit_type_ref_children(&self, type_ref: TypeRefId, mut visitor: impl StoreVisitor) {
856856
match &self[type_ref] {
857857
TypeRef::Never | TypeRef::Placeholder | TypeRef::TypeParam(_) | TypeRef::Error => {}
858+
&TypeRef::PatternType(ty, pat) => {
859+
visitor.on_type(ty);
860+
visitor.on_pat(pat)
861+
}
858862
TypeRef::Tuple(types) => visitor.on_types(types),
859863
TypeRef::Path(path) => visitor.on_path(path),
860864
TypeRef::RawPtr(inner, _) | TypeRef::Slice(inner) => visitor.on_type(*inner),

crates/hir-def/src/expr_store/body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use syntax::ast;
99
use triomphe::Arc;
1010

1111
use crate::{
12-
DefWithBodyId, HasModule,
12+
DefWithBodyId, ExpressionStoreOwnerId, HasModule,
1313
db::DefDatabase,
1414
expr_store::{
1515
ExpressionStore, ExpressionStoreSourceMap, SelfParamPtr, lower::lower_body, pretty,
@@ -160,12 +160,12 @@ impl Body {
160160
pub fn pretty_print_pat(
161161
&self,
162162
db: &dyn DefDatabase,
163-
owner: DefWithBodyId,
163+
owner: ExpressionStoreOwnerId,
164164
pat: PatId,
165165
oneline: bool,
166166
edition: Edition,
167167
) -> String {
168-
pretty::print_pat_hir(db, self, owner.into(), pat, oneline, edition)
168+
pretty::print_pat_hir(db, self, owner, pat, oneline, edition)
169169
}
170170
}
171171

crates/hir-def/src/expr_store/lower.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,10 @@ impl<'db> ExprCollector<'db> {
719719
ast::Type::DynTraitType(inner) => TypeRef::DynTrait(
720720
self.type_bounds_from_ast(inner.type_bound_list(), impl_trait_lower_fn),
721721
),
722+
ast::Type::PatternType(inner) => TypeRef::PatternType(
723+
self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn),
724+
self.collect_pat_top(inner.pat()),
725+
),
722726
ast::Type::MacroType(mt) => match mt.macro_call() {
723727
Some(mcall) => {
724728
let macro_ptr = AstPtr::new(&mcall);
@@ -2782,6 +2786,7 @@ impl<'db> ExprCollector<'db> {
27822786
let inner = self.collect_pat_opt(inner.pat(), binding_list);
27832787
Pat::Deref { inner }
27842788
}
2789+
ast::Pat::NotNull(_) => Pat::NotNull,
27852790
ast::Pat::ConstBlockPat(const_block_pat) => {
27862791
if let Some(block) = const_block_pat.block_expr() {
27872792
let expr_id = self.with_label_rib(RibKind::Constant, |this| {

crates/hir-def/src/expr_store/pretty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ impl Printer<'_> {
906906
Pat::Missing => w!(self, "�"),
907907
Pat::Rest => w!(self, ".."),
908908
Pat::Wild => w!(self, "_"),
909+
Pat::NotNull => w!(self, "!null"),
909910
Pat::Tuple { args, ellipsis } => {
910911
w!(self, "(");
911912
for (i, pat) in args.iter().enumerate() {
@@ -1346,6 +1347,11 @@ impl Printer<'_> {
13461347
w!(self, "dyn ");
13471348
self.print_type_bounds(bounds);
13481349
}
1350+
TypeRef::PatternType(ty, pat) => {
1351+
self.print_type_ref(*ty);
1352+
w!(self, " is ");
1353+
self.print_pat(*pat);
1354+
}
13491355
}
13501356
}
13511357

crates/hir-def/src/hir.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ pub enum Pat {
717717
Deref {
718718
inner: PatId,
719719
},
720+
NotNull,
720721
ConstBlock(ExprId),
721722
/// An expression inside a pattern. That can only occur inside assignments.
722723
///
@@ -734,7 +735,8 @@ impl Pat {
734735
| Pat::Wild
735736
| Pat::Missing
736737
| Pat::Rest
737-
| Pat::Expr(_) => {}
738+
| Pat::Expr(_)
739+
| Pat::NotNull => {}
738740
Pat::Bind { subpat, .. } => {
739741
subpat.iter().copied().for_each(f);
740742
}

crates/hir-def/src/hir/type_ref.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use thin_vec::ThinVec;
99
use crate::{
1010
LifetimeParamId, TypeParamId,
1111
expr_store::{ExpressionStore, path::Path},
12-
hir::ExprId,
12+
hir::{ExprId, PatId},
1313
};
1414

1515
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -139,6 +139,7 @@ pub enum TypeRef {
139139
ImplTrait(ThinVec<TypeBound>),
140140
DynTrait(ThinVec<TypeBound>),
141141
TypeParam(TypeParamId),
142+
PatternType(TypeRefId, PatId),
142143
Error,
143144
}
144145

crates/hir-def/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,12 @@ impl From<VariantId> for ExpressionStoreOwnerId {
852852
}
853853
}
854854

855+
impl From<ImplId> for ExpressionStoreOwnerId {
856+
fn from(id: ImplId) -> Self {
857+
ExpressionStoreOwnerId::Signature(id.into())
858+
}
859+
}
860+
855861
impl GenericDefId {
856862
pub fn file_id_and_params_of(
857863
self,

crates/hir-expand/src/builtin/derive_macro.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,9 @@ fn coerce_pointee_expand(
14941494
ast::Type::TupleType(ty) => any_long(ty.fields(), |ty| {
14951495
substitute_type_in_bound(editor, ty, param_name, replacement)
14961496
}),
1497+
ast::Type::PatternType(ty) => ty
1498+
.ty()
1499+
.is_some_and(|ty| substitute_type_in_bound(editor, ty, param_name, replacement)),
14971500
ast::Type::InferType(_) | ast::Type::MacroType(_) | ast::Type::NeverType(_) => false,
14981501
};
14991502

crates/hir-expand/src/builtin/fn_macro.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ register_builtin! {
137137
(const_format_args, ConstFormatArgs) => format_args_expand,
138138
(format_args_nl, FormatArgsNl) => format_args_nl_expand,
139139
(quote, Quote) => quote_expand,
140+
(pattern_type, PatternType) => pattern_type_expand,
140141

141142
EagerExpander:
142143
(compile_error, CompileError) => compile_error_expand,
@@ -994,3 +995,15 @@ fn unescape_str(s: &str) -> Cow<'_, str> {
994995
Cow::Borrowed(s)
995996
}
996997
}
998+
999+
fn pattern_type_expand(
1000+
_db: &dyn ExpandDatabase,
1001+
_arg_id: MacroCallId,
1002+
tt: &tt::TopSubtree,
1003+
call_site: Span,
1004+
) -> ExpandResult<tt::TopSubtree> {
1005+
let mut tt = tt.clone();
1006+
tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible);
1007+
let pound = mk_pound(call_site);
1008+
ExpandResult::ok(quote! {call_site => builtin #pound pattern_type ( #tt ) })
1009+
}

crates/hir-ty/src/diagnostics/unsafe_check.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,8 @@ impl<'db> UnsafeVisitor<'db> {
255255
| Pat::Box { .. }
256256
| Pat::Deref { .. }
257257
| Pat::Expr(..)
258-
| Pat::ConstBlock(..) => {
259-
self.on_unsafe_op(current.into(), UnsafetyReason::UnionField)
260-
}
258+
| Pat::ConstBlock(..)
259+
| Pat::NotNull => self.on_unsafe_op(current.into(), UnsafetyReason::UnionField),
261260
// `Or` only wraps other patterns, and `Missing`/`Wild` do not constitute a read.
262261
Pat::Missing | Pat::Rest | Pat::Wild | Pat::Or(_) => {}
263262
}

0 commit comments

Comments
 (0)