Make Pat::Range's start and end Option<ExprId>

This commit is contained in:
Ali Bektas 2025-01-07 22:57:40 +01:00
parent b7b09d2acb
commit 06097c3388
6 changed files with 48 additions and 26 deletions

View file

@ -112,9 +112,9 @@ pub struct ExpressionStoreSourceMap {
// AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
// to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected). // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
expr_map: FxHashMap<ExprSource, ExprOrPatId>, expr_map: FxHashMap<ExprSource, ExprOrPatId>,
expr_map_back: ArenaMap<ExprId, ExprSource>, expr_map_back: ArenaMap<ExprId, ExprOrPatSource>,
pat_map: FxHashMap<PatSource, PatId>, pat_map: FxHashMap<PatSource, ExprOrPatId>,
pat_map_back: ArenaMap<PatId, ExprOrPatSource>, pat_map_back: ArenaMap<PatId, ExprOrPatSource>,
label_map: FxHashMap<LabelSource, LabelId>, label_map: FxHashMap<LabelSource, LabelId>,
@ -606,12 +606,12 @@ impl Index<TypeRefId> for ExpressionStore {
impl ExpressionStoreSourceMap { impl ExpressionStoreSourceMap {
pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> { pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> {
match id { match id {
ExprOrPatId::ExprId(id) => self.expr_syntax(id).map(|it| it.map(AstPtr::wrap_left)), ExprOrPatId::ExprId(id) => self.expr_syntax(id),
ExprOrPatId::PatId(id) => self.pat_syntax(id), ExprOrPatId::PatId(id) => self.pat_syntax(id),
} }
} }
pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprOrPatSource, SyntheticSyntax> {
self.expr_map_back.get(expr).cloned().ok_or(SyntheticSyntax) self.expr_map_back.get(expr).cloned().ok_or(SyntheticSyntax)
} }
@ -633,7 +633,7 @@ impl ExpressionStoreSourceMap {
self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax) self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
} }
pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> { pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<ExprOrPatId> {
self.pat_map.get(&node.map(AstPtr::new)).cloned() self.pat_map.get(&node.map(AstPtr::new)).cloned()
} }

View file

@ -1784,23 +1784,32 @@ impl ExprCollector<'_> {
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
this.collect_pat_opt(expanded_pat, binding_list) this.collect_pat_opt(expanded_pat, binding_list)
}); });
self.source_map.pat_map.insert(src, pat); self.source_map.pat_map.insert(src, pat.into());
return pat; return pat;
} }
None => Pat::Missing, None => Pat::Missing,
}, },
// FIXME: implement in a way that also builds source map and calculates assoc resolutions in type inference. // FIXME: implement in a way that also builds source map and calculates assoc resolutions in type inference.
ast::Pat::RangePat(p) => { ast::Pat::RangePat(p) => {
let mut range_part_lower = |p: Option<ast::Pat>| { let mut range_part_lower = |p: Option<ast::Pat>| -> Option<ExprId> {
p.and_then(|it| match &it { p.and_then(|it| {
ast::Pat::LiteralPat(it) => { let ptr = PatPtr::new(&it);
Some(Box::new(LiteralOrConst::Literal(pat_literal_to_hir(it)?.0))) match &it {
ast::Pat::LiteralPat(it) => {
// Some(Box::new(LiteralOrConst::Literal(pat_literal_to_hir(it)?.0)))
Some(self.alloc_expr_from_pat(
Expr::Literal(pat_literal_to_hir(it)?.0),
ptr,
))
}
pat @ (ast::Pat::IdentPat(_) | ast::Pat::PathPat(_)) => {
// let subpat = self.collect_pat(pat.clone(), binding_list);
// Some(Box::new(LiteralOrConst::Const(subpat)))
// TODO
Some(self.missing_expr())
}
_ => None,
} }
pat @ (ast::Pat::IdentPat(_) | ast::Pat::PathPat(_)) => {
let subpat = self.collect_pat(pat.clone(), binding_list);
Some(Box::new(LiteralOrConst::Const(subpat)))
}
_ => None,
}) })
}; };
let start = range_part_lower(p.start()); let start = range_part_lower(p.start());
@ -1863,7 +1872,7 @@ impl ExprCollector<'_> {
} }
}); });
if let Some(pat) = pat.left() { if let Some(pat) = pat.left() {
self.source_map.pat_map.insert(src, pat); self.source_map.pat_map.insert(src, pat.into());
} }
pat pat
} }
@ -2490,7 +2499,7 @@ impl ExprCollector<'_> {
fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
let src = self.expander.in_file(ptr); let src = self.expander.in_file(ptr);
let id = self.store.exprs.alloc(expr); let id = self.store.exprs.alloc(expr);
self.source_map.expr_map_back.insert(id, src); self.source_map.expr_map_back.insert(id, src.map(AstPtr::wrap_left));
self.source_map.expr_map.insert(src, id.into()); self.source_map.expr_map.insert(src, id.into());
id id
} }
@ -2502,7 +2511,7 @@ impl ExprCollector<'_> {
fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
let src = self.expander.in_file(ptr); let src = self.expander.in_file(ptr);
let id = self.store.exprs.alloc(expr); let id = self.store.exprs.alloc(expr);
self.source_map.expr_map_back.insert(id, src); self.source_map.expr_map_back.insert(id, src.map(AstPtr::wrap_left));
// We intentionally don't fill this as it could overwrite a non-desugared entry // We intentionally don't fill this as it could overwrite a non-desugared entry
// self.source_map.expr_map.insert(src, id); // self.source_map.expr_map.insert(src, id);
id id
@ -2526,11 +2535,20 @@ impl ExprCollector<'_> {
self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_left)); self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_left));
id id
} }
fn alloc_expr_from_pat(&mut self, expr: Expr, ptr: PatPtr) -> ExprId {
let src = self.expander.in_file(ptr);
let id = self.body.exprs.alloc(expr);
self.source_map.pat_map.insert(src, id.into());
self.source_map.expr_map_back.insert(id, src.map(AstPtr::wrap_right));
id
}
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
let src = self.expander.in_file(ptr); let src = self.expander.in_file(ptr);
let id = self.store.pats.alloc(pat); let id = self.store.pats.alloc(pat);
self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_right)); self.source_map.pat_map_back.insert(id, src.map(AstPtr::wrap_right));
self.source_map.pat_map.insert(src, id); self.source_map.pat_map.insert(src, id.into());
id id
} }
// FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow. // FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow.

View file

@ -656,11 +656,11 @@ impl Printer<'_> {
} }
Pat::Range { start, end } => { Pat::Range { start, end } => {
if let Some(start) = start { if let Some(start) = start {
self.print_literal_or_const(start); self.print_expr(*start);
} }
w!(self, "..="); w!(self, "..=");
if let Some(end) = end { if let Some(end) = end {
self.print_literal_or_const(end); self.print_expr(*end);
} }
} }
Pat::Slice { prefix, slice, suffix } => { Pat::Slice { prefix, slice, suffix } => {

View file

@ -571,8 +571,8 @@ pub enum Pat {
ellipsis: bool, ellipsis: bool,
}, },
Range { Range {
start: Option<Box<LiteralOrConst>>, start: Option<ExprId>,
end: Option<Box<LiteralOrConst>>, end: Option<ExprId>,
}, },
Slice { Slice {
prefix: Box<[PatId]>, prefix: Box<[PatId]>,

View file

@ -440,7 +440,9 @@ impl ExprValidator {
return; return;
}; };
let root = source_ptr.file_syntax(db.upcast()); let root = source_ptr.file_syntax(db.upcast());
let ast::Expr::IfExpr(if_expr) = source_ptr.value.to_node(&root) else { let either::Left(ast::Expr::IfExpr(if_expr)) =
source_ptr.value.to_node(&root)
else {
return; return;
}; };
let mut top_if_expr = if_expr; let mut top_if_expr = if_expr;

View file

@ -234,10 +234,12 @@ impl MirLowerCtx<'_> {
}; };
if mode == MatchingMode::Check { if mode == MatchingMode::Check {
if let Some(start) = start { if let Some(start) = start {
add_check(start, BinOp::Le)?; // TODO
// add_check(start, BinOp::Le)?;
} }
if let Some(end) = end { if let Some(end) = end {
add_check(end, BinOp::Ge)?; // TODO
// add_check(end, BinOp::Ge)?;
} }
} }
(current, current_else) (current, current_else)