Use a different hir type for patterns in pattern types than we use in match patterns
This commit is contained in:
parent
613bdd4997
commit
f0308938ba
27 changed files with 311 additions and 168 deletions
|
@ -412,8 +412,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
|
||||
self.visit_pat(p)
|
||||
fn visit_pattern_type_pattern(&mut self, pat: &'hir hir::TyPat<'hir>) {
|
||||
self.insert(pat.span, pat.hir_id, Node::TyPat(pat));
|
||||
|
||||
self.with_parent(pat.hir_id, |this| {
|
||||
intravisit::walk_ty_pat(this, pat);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_precise_capturing_arg(
|
||||
|
|
|
@ -1377,7 +1377,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
}
|
||||
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
|
||||
TyKind::Pat(ty, pat) => {
|
||||
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
|
||||
}
|
||||
TyKind::MacCall(_) => {
|
||||
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_span::source_map::{Spanned, respan};
|
||||
use rustc_span::{Ident, Span};
|
||||
use rustc_span::{Ident, Span, kw};
|
||||
|
||||
use super::errors::{
|
||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||
|
@ -429,4 +429,80 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
};
|
||||
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
||||
}
|
||||
|
||||
pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
|
||||
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||
}
|
||||
|
||||
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
|
||||
// loop here to avoid recursion
|
||||
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||
let node = loop {
|
||||
match &pattern.kind {
|
||||
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
||||
let mut lower_expr = |e: &Expr| -> &_ {
|
||||
let kind = if let ExprKind::Path(qself, path) = &e.kind {
|
||||
hir::ConstArgKind::Path(self.lower_qpath(
|
||||
e.id,
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
let node_id = self.next_node_id();
|
||||
let def_id = self.create_def(
|
||||
self.current_hir_id_owner.def_id,
|
||||
node_id,
|
||||
kw::Empty,
|
||||
DefKind::AnonConst,
|
||||
e.span,
|
||||
);
|
||||
let hir_id = self.lower_node_id(node_id);
|
||||
let ac = self.arena.alloc(hir::AnonConst {
|
||||
def_id,
|
||||
hir_id,
|
||||
body: self.lower_const_body(pattern.span, Some(e)),
|
||||
span: self.lower_span(pattern.span),
|
||||
});
|
||||
hir::ConstArgKind::Anon(ac)
|
||||
};
|
||||
self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind })
|
||||
};
|
||||
break hir::TyPatKind::Range(
|
||||
e1.as_deref().map(|e| lower_expr(e)),
|
||||
e2.as_deref().map(|e| lower_expr(e)),
|
||||
self.lower_range_end(end, e2.is_some()),
|
||||
);
|
||||
}
|
||||
// return inner to be processed in next loop
|
||||
PatKind::Paren(inner) => pattern = inner,
|
||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
|
||||
PatKind::Deref(..)
|
||||
| PatKind::Box(..)
|
||||
| PatKind::Or(..)
|
||||
| PatKind::Struct(..)
|
||||
| PatKind::TupleStruct(..)
|
||||
| PatKind::Tuple(..)
|
||||
| PatKind::Ref(..)
|
||||
| PatKind::Expr(..)
|
||||
| PatKind::Guard(..)
|
||||
| PatKind::Slice(_)
|
||||
| PatKind::Ident(..)
|
||||
| PatKind::Path(..)
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Rest => {
|
||||
break hir::TyPatKind::Err(
|
||||
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue