Skip to content

Commit 2320e12

Browse files
committed
Auto merge of rust-lang#16771 - Veykril:self-param-split, r=Veykril
internal: Don't desugar self param into a pattern Small experiment to see if this simplifies things
2 parents a0dd822 + 458f4a2 commit 2320e12

File tree

18 files changed

+256
-144
lines changed

18 files changed

+256
-144
lines changed

crates/hir-def/src/body.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use std::ops::Index;
1010

1111
use base_db::CrateId;
1212
use cfg::{CfgExpr, CfgOptions};
13-
use either::Either;
1413
use hir_expand::{name::Name, HirFileId, InFile};
1514
use la_arena::{Arena, ArenaMap};
1615
use rustc_hash::FxHashMap;
@@ -45,7 +44,8 @@ pub struct Body {
4544
///
4645
/// If this `Body` is for the body of a constant, this will just be
4746
/// empty.
48-
pub params: Vec<PatId>,
47+
pub params: Box<[PatId]>,
48+
pub self_param: Option<BindingId>,
4949
/// The `ExprId` of the actual body expression.
5050
pub body_expr: ExprId,
5151
/// Block expressions in this body that may contain inner items.
@@ -55,14 +55,15 @@ pub struct Body {
5555
pub type ExprPtr = AstPtr<ast::Expr>;
5656
pub type ExprSource = InFile<ExprPtr>;
5757

58-
pub type PatPtr = AstPtr<Either<ast::Pat, ast::SelfParam>>;
58+
pub type PatPtr = AstPtr<ast::Pat>;
5959
pub type PatSource = InFile<PatPtr>;
6060

6161
pub type LabelPtr = AstPtr<ast::Label>;
6262
pub type LabelSource = InFile<LabelPtr>;
6363

6464
pub type FieldPtr = AstPtr<ast::RecordExprField>;
6565
pub type FieldSource = InFile<FieldPtr>;
66+
6667
pub type PatFieldPtr = AstPtr<ast::RecordPatField>;
6768
pub type PatFieldSource = InFile<PatFieldPtr>;
6869

@@ -88,6 +89,8 @@ pub struct BodySourceMap {
8889
label_map: FxHashMap<LabelSource, LabelId>,
8990
label_map_back: ArenaMap<LabelId, LabelSource>,
9091

92+
self_param: Option<InFile<AstPtr<ast::SelfParam>>>,
93+
9194
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
9295
/// Instead, we use id of expression (`92`) to identify the field.
9396
field_map_back: FxHashMap<ExprId, FieldSource>,
@@ -215,18 +218,18 @@ impl Body {
215218
fn shrink_to_fit(&mut self) {
216219
let Self {
217220
body_expr: _,
221+
params: _,
222+
self_param: _,
218223
block_scopes,
219224
exprs,
220225
labels,
221-
params,
222226
pats,
223227
bindings,
224228
binding_owners,
225229
} = self;
226230
block_scopes.shrink_to_fit();
227231
exprs.shrink_to_fit();
228232
labels.shrink_to_fit();
229-
params.shrink_to_fit();
230233
pats.shrink_to_fit();
231234
bindings.shrink_to_fit();
232235
binding_owners.shrink_to_fit();
@@ -297,6 +300,7 @@ impl Default for Body {
297300
params: Default::default(),
298301
block_scopes: Default::default(),
299302
binding_owners: Default::default(),
303+
self_param: Default::default(),
300304
}
301305
}
302306
}
@@ -354,14 +358,12 @@ impl BodySourceMap {
354358
self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
355359
}
356360

357-
pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
358-
let src = node.map(|it| AstPtr::new(it).wrap_left());
359-
self.pat_map.get(&src).cloned()
361+
pub fn self_param_syntax(&self) -> Option<InFile<AstPtr<ast::SelfParam>>> {
362+
self.self_param
360363
}
361364

362-
pub fn node_self_param(&self, node: InFile<&ast::SelfParam>) -> Option<PatId> {
363-
let src = node.map(|it| AstPtr::new(it).wrap_right());
364-
self.pat_map.get(&src).cloned()
365+
pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
366+
self.pat_map.get(&node.map(AstPtr::new)).cloned()
365367
}
366368

367369
pub fn label_syntax(&self, label: LabelId) -> LabelSource {
@@ -401,6 +403,7 @@ impl BodySourceMap {
401403

402404
fn shrink_to_fit(&mut self) {
403405
let Self {
406+
self_param: _,
404407
expr_map,
405408
expr_map_back,
406409
pat_map,

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

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use std::mem;
55

66
use base_db::CrateId;
7-
use either::Either;
87
use hir_expand::{
98
name::{name, AsName, Name},
109
ExpandError, InFile,
@@ -29,7 +28,6 @@ use crate::{
2928
db::DefDatabase,
3029
expander::Expander,
3130
hir::{
32-
dummy_expr_id,
3331
format_args::{
3432
self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind,
3533
FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions,
@@ -66,16 +64,7 @@ pub(super) fn lower(
6664
def_map: expander.module.def_map(db),
6765
source_map: BodySourceMap::default(),
6866
ast_id_map: db.ast_id_map(expander.current_file_id()),
69-
body: Body {
70-
exprs: Default::default(),
71-
pats: Default::default(),
72-
bindings: Default::default(),
73-
binding_owners: Default::default(),
74-
labels: Default::default(),
75-
params: Vec::new(),
76-
body_expr: dummy_expr_id(),
77-
block_scopes: Vec::new(),
78-
},
67+
body: Body::default(),
7968
expander,
8069
current_try_block_label: None,
8170
is_lowering_assignee_expr: false,
@@ -191,35 +180,35 @@ impl ExprCollector<'_> {
191180
is_async_fn: bool,
192181
) -> (Body, BodySourceMap) {
193182
if let Some((param_list, mut attr_enabled)) = param_list {
183+
let mut params = vec![];
194184
if let Some(self_param) =
195185
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
196186
{
197187
let is_mutable =
198188
self_param.mut_token().is_some() && self_param.amp_token().is_none();
199-
let ptr = AstPtr::new(&Either::Right(self_param));
200189
let binding_id: la_arena::Idx<Binding> =
201190
self.alloc_binding(name![self], BindingAnnotation::new(is_mutable, false));
202-
let param_pat = self.alloc_pat(Pat::Bind { id: binding_id, subpat: None }, ptr);
203-
self.add_definition_to_binding(binding_id, param_pat);
204-
self.body.params.push(param_pat);
191+
self.body.self_param = Some(binding_id);
192+
self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param)));
205193
}
206194

207195
for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled)
208196
{
209197
let param_pat = self.collect_pat_top(param.pat());
210-
self.body.params.push(param_pat);
198+
params.push(param_pat);
211199
}
200+
self.body.params = params.into_boxed_slice();
212201
};
213202
self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
214203
if is_async_fn {
215204
match body {
216205
Some(e) => {
206+
let syntax_ptr = AstPtr::new(&e);
217207
let expr = this.collect_expr(e);
218-
this.alloc_expr_desugared(Expr::Async {
219-
id: None,
220-
statements: Box::new([]),
221-
tail: Some(expr),
222-
})
208+
this.alloc_expr_desugared_with_ptr(
209+
Expr::Async { id: None, statements: Box::new([]), tail: Some(expr) },
210+
syntax_ptr,
211+
)
223212
}
224213
None => this.missing_expr(),
225214
}
@@ -405,7 +394,7 @@ impl ExprCollector<'_> {
405394
}
406395
ast::Expr::ParenExpr(e) => {
407396
let inner = self.collect_expr_opt(e.expr());
408-
// make the paren expr point to the inner expression as well
397+
// make the paren expr point to the inner expression as well for IDE resolution
409398
let src = self.expander.in_file(syntax_ptr);
410399
self.source_map.expr_map.insert(src, inner);
411400
inner
@@ -707,6 +696,7 @@ impl ExprCollector<'_> {
707696
.alloc_label_desugared(Label { name: Name::generate_new_name(self.body.labels.len()) });
708697
let old_label = self.current_try_block_label.replace(label);
709698

699+
let ptr = AstPtr::new(&e).upcast();
710700
let (btail, expr_id) = self.with_labeled_rib(label, |this| {
711701
let mut btail = None;
712702
let block = this.collect_block_(e, |id, statements, tail| {
@@ -716,23 +706,21 @@ impl ExprCollector<'_> {
716706
(btail, block)
717707
});
718708

719-
let callee = self.alloc_expr_desugared(Expr::Path(try_from_output));
709+
let callee = self.alloc_expr_desugared_with_ptr(Expr::Path(try_from_output), ptr);
720710
let next_tail = match btail {
721-
Some(tail) => self.alloc_expr_desugared(Expr::Call {
722-
callee,
723-
args: Box::new([tail]),
724-
is_assignee_expr: false,
725-
}),
711+
Some(tail) => self.alloc_expr_desugared_with_ptr(
712+
Expr::Call { callee, args: Box::new([tail]), is_assignee_expr: false },
713+
ptr,
714+
),
726715
None => {
727-
let unit = self.alloc_expr_desugared(Expr::Tuple {
728-
exprs: Box::new([]),
729-
is_assignee_expr: false,
730-
});
731-
self.alloc_expr_desugared(Expr::Call {
732-
callee,
733-
args: Box::new([unit]),
734-
is_assignee_expr: false,
735-
})
716+
let unit = self.alloc_expr_desugared_with_ptr(
717+
Expr::Tuple { exprs: Box::new([]), is_assignee_expr: false },
718+
ptr,
719+
);
720+
self.alloc_expr_desugared_with_ptr(
721+
Expr::Call { callee, args: Box::new([unit]), is_assignee_expr: false },
722+
ptr,
723+
)
736724
}
737725
};
738726
let Expr::Block { tail, .. } = &mut self.body.exprs[expr_id] else {
@@ -1067,16 +1055,12 @@ impl ExprCollector<'_> {
10671055
None => None,
10681056
},
10691057
);
1070-
match expansion {
1071-
Some(tail) => {
1072-
// Make the macro-call point to its expanded expression so we can query
1073-
// semantics on syntax pointers to the macro
1074-
let src = self.expander.in_file(syntax_ptr);
1075-
self.source_map.expr_map.insert(src, tail);
1076-
Some(tail)
1077-
}
1078-
None => None,
1079-
}
1058+
expansion.inspect(|&tail| {
1059+
// Make the macro-call point to its expanded expression so we can query
1060+
// semantics on syntax pointers to the macro
1061+
let src = self.expander.in_file(syntax_ptr);
1062+
self.source_map.expr_map.insert(src, tail);
1063+
})
10801064
}
10811065

10821066
fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) {
@@ -1261,7 +1245,7 @@ impl ExprCollector<'_> {
12611245
(Some(id), Pat::Bind { id, subpat })
12621246
};
12631247

1264-
let ptr = AstPtr::new(&Either::Left(pat));
1248+
let ptr = AstPtr::new(&pat);
12651249
let pat = self.alloc_pat(pattern, ptr);
12661250
if let Some(binding_id) = binding {
12671251
self.add_definition_to_binding(binding_id, pat);
@@ -1359,9 +1343,10 @@ impl ExprCollector<'_> {
13591343
suffix: suffix.into_iter().map(|p| self.collect_pat(p, binding_list)).collect(),
13601344
}
13611345
}
1362-
#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5676
13631346
ast::Pat::LiteralPat(lit) => 'b: {
1364-
let Some((hir_lit, ast_lit)) = pat_literal_to_hir(lit) else { break 'b Pat::Missing };
1347+
let Some((hir_lit, ast_lit)) = pat_literal_to_hir(lit) else {
1348+
break 'b Pat::Missing;
1349+
};
13651350
let expr = Expr::Literal(hir_lit);
13661351
let expr_ptr = AstPtr::new(&ast::Expr::Literal(ast_lit));
13671352
let expr_id = self.alloc_expr(expr, expr_ptr);
@@ -1397,7 +1382,7 @@ impl ExprCollector<'_> {
13971382
ast::Pat::MacroPat(mac) => match mac.macro_call() {
13981383
Some(call) => {
13991384
let macro_ptr = AstPtr::new(&call);
1400-
let src = self.expander.in_file(AstPtr::new(&Either::Left(pat)));
1385+
let src = self.expander.in_file(AstPtr::new(&pat));
14011386
let pat =
14021387
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
14031388
this.collect_pat_opt(expanded_pat, binding_list)
@@ -1426,7 +1411,7 @@ impl ExprCollector<'_> {
14261411
Pat::Range { start, end }
14271412
}
14281413
};
1429-
let ptr = AstPtr::new(&Either::Left(pat));
1414+
let ptr = AstPtr::new(&pat);
14301415
self.alloc_pat(pattern, ptr)
14311416
}
14321417

@@ -1987,10 +1972,19 @@ impl ExprCollector<'_> {
19871972
self.source_map.expr_map.insert(src, id);
19881973
id
19891974
}
1990-
// FIXME: desugared exprs don't have ptr, that's wrong and should be fixed somehow.
1975+
// FIXME: desugared exprs don't have ptr, that's wrong and should be fixed.
1976+
// Migrate to alloc_expr_desugared_with_ptr and then rename back
19911977
fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
19921978
self.body.exprs.alloc(expr)
19931979
}
1980+
fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
1981+
let src = self.expander.in_file(ptr);
1982+
let id = self.body.exprs.alloc(expr);
1983+
self.source_map.expr_map_back.insert(id, src);
1984+
// We intentionally don't fill this as it could overwrite a non-desugared entry
1985+
// self.source_map.expr_map.insert(src, id);
1986+
id
1987+
}
19941988
fn missing_expr(&mut self) -> ExprId {
19951989
self.alloc_expr_desugared(Expr::Missing)
19961990
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
4848
let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false };
4949
if let DefWithBodyId::FunctionId(it) = owner {
5050
p.buf.push('(');
51-
body.params.iter().zip(db.function_data(it).params.iter()).for_each(|(&param, ty)| {
51+
let params = &db.function_data(it).params;
52+
let mut params = params.iter();
53+
if let Some(self_param) = body.self_param {
54+
p.print_binding(self_param);
55+
p.buf.push(':');
56+
if let Some(ty) = params.next() {
57+
p.print_type_ref(ty);
58+
}
59+
}
60+
body.params.iter().zip(params).for_each(|(&param, ty)| {
5261
p.print_pat(param);
5362
p.buf.push(':');
5463
p.print_type_ref(ty);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ impl ExprScopes {
9696
scope_by_expr: ArenaMap::with_capacity(body.exprs.len()),
9797
};
9898
let mut root = scopes.root_scope();
99+
if let Some(self_param) = body.self_param {
100+
scopes.add_bindings(body, root, self_param);
101+
}
99102
scopes.add_params_bindings(body, root, &body.params);
100103
compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
101104
scopes

crates/hir-ty/src/infer.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mod pat;
2222
mod path;
2323
pub(crate) mod unify;
2424

25-
use std::{convert::identity, ops::Index};
25+
use std::{convert::identity, iter, ops::Index};
2626

2727
use chalk_ir::{
2828
cast::Cast, fold::TypeFoldable, interner::HasInterner, DebruijnIndex, Mutability, Safety,
@@ -777,7 +777,15 @@ impl<'a> InferenceContext<'a> {
777777

778778
param_tys.push(va_list_ty)
779779
}
780-
for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
780+
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
781+
if let Some(self_param) = self.body.self_param {
782+
if let Some(ty) = param_tys.next() {
783+
let ty = self.insert_type_vars(ty);
784+
let ty = self.normalize_associated_types_in(ty);
785+
self.write_binding_ty(self_param, ty);
786+
}
787+
}
788+
for (ty, pat) in param_tys.zip(&*self.body.params) {
781789
let ty = self.insert_type_vars(ty);
782790
let ty = self.normalize_associated_types_in(ty);
783791

crates/hir-ty/src/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ pub fn layout_of_ty_query(
371371
TyKind::Never => cx.layout_of_never_type(),
372372
TyKind::Dyn(_) | TyKind::Foreign(_) => {
373373
let mut unit = layout_of_unit(&cx, dl)?;
374-
match unit.abi {
375-
Abi::Aggregate { ref mut sized } => *sized = false,
374+
match &mut unit.abi {
375+
Abi::Aggregate { sized } => *sized = false,
376376
_ => return Err(LayoutError::Unknown),
377377
}
378378
unit

crates/hir-ty/src/mir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,7 @@ impl MirBody {
11651165
pub enum MirSpan {
11661166
ExprId(ExprId),
11671167
PatId(PatId),
1168+
SelfParam,
11681169
Unknown,
11691170
}
11701171

0 commit comments

Comments
 (0)