Skip to content

Commit cbdbf6c

Browse files
authored
Merge pull request #21900 from Veykril/push-ylmpryvvpsym
Fully implement `VariantFields `expression support
2 parents 617da06 + 9fb997f commit cbdbf6c

76 files changed

Lines changed: 740 additions & 457 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/hir-def/src/db.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ use hir_expand::{
44
EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind,
55
db::ExpandDatabase,
66
};
7-
use la_arena::ArenaMap;
87
use triomphe::Arc;
98

109
use crate::{
1110
AnonConstId, AnonConstLoc, AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc,
1211
EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId,
13-
ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc,
14-
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId,
15-
ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
16-
TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
12+
ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, Macro2Id, Macro2Loc, MacroExpander,
13+
MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId,
14+
StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId,
15+
UnionLoc, UseId, UseLoc,
1716
attrs::AttrFlags,
1817
item_tree::{ItemTree, file_item_tree_query},
1918
nameres::crate_def_map,
@@ -98,9 +97,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
9897

9998
// region:visibilities
10099

101-
#[salsa::invoke(visibility::field_visibilities_query)]
102-
fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>;
103-
104100
#[salsa::invoke(visibility::assoc_visibility_query)]
105101
fn assoc_visibility(&self, def: AssocItemId) -> Visibility;
106102

crates/hir-def/src/expr_store.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::{
3131
PatId, RecordFieldPat, RecordSpread, Statement,
3232
},
3333
nameres::{DefMap, block_def_map},
34+
signatures::VariantFields,
3435
type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId},
3536
};
3637

@@ -95,14 +96,16 @@ pub type LifetimeSource = InFile<LifetimePtr>;
9596
/// Used by signature/body inference to determine the expected type for each
9697
/// const expression root.
9798
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
98-
pub enum ConstExprOrigin {
99+
pub enum RootExprOrigin {
99100
/// Array length expression: `[T; <expr>]` — expected type is `usize`.
100101
ArrayLength,
101102
/// Const parameter default value: `const N: usize = <expr>`.
102103
ConstParam(crate::hir::generics::LocalTypeOrConstParamId),
103104
/// Const generic argument in a path: `SomeType::<{ <expr> }>` or `some_fn::<{ <expr> }>()`.
104105
/// Determining the expected type requires path resolution, so it is deferred.
105106
GenericArgsPath,
107+
/// The root expression of a body.
108+
BodyRoot,
106109
}
107110

108111
// We split the store into types-only and expressions, because most stores (e.g. generics)
@@ -125,11 +128,8 @@ struct ExpressionOnlyStore {
125128
/// to variables and have hygiene (some refer to items, we don't know at this stage).
126129
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
127130

128-
/// Maps const expression roots to their origin.
129-
///
130-
/// Populated during lowering. Used by signature inference to determine expected types,
131-
/// and by `signature_const_expr_roots()` to enumerate roots for scope computation.
132-
const_expr_origins: ThinVec<(ExprId, ConstExprOrigin)>,
131+
/// Maps expression roots to their origin.
132+
expr_roots: SmallVec<[(ExprId, RootExprOrigin); 1]>,
133133
}
134134

135135
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -243,7 +243,7 @@ pub struct ExpressionStoreBuilder {
243243
pub types: Arena<TypeRef>,
244244
block_scopes: Vec<BlockId>,
245245
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
246-
pub const_expr_origins: Option<ThinVec<(ExprId, ConstExprOrigin)>>,
246+
pub inference_roots: Option<SmallVec<[(ExprId, RootExprOrigin); 1]>>,
247247

248248
// AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
249249
// to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
@@ -315,7 +315,7 @@ impl ExpressionStoreBuilder {
315315
mut bindings,
316316
mut binding_owners,
317317
mut ident_hygiene,
318-
mut const_expr_origins,
318+
inference_roots: mut expr_roots,
319319
mut types,
320320
mut lifetimes,
321321

@@ -375,7 +375,7 @@ impl ExpressionStoreBuilder {
375375

376376
let store = {
377377
let expr_only = if has_exprs {
378-
if let Some(const_expr_origins) = &mut const_expr_origins {
378+
if let Some(const_expr_origins) = &mut expr_roots {
379379
const_expr_origins.shrink_to_fit();
380380
}
381381
Some(Box::new(ExpressionOnlyStore {
@@ -386,7 +386,7 @@ impl ExpressionStoreBuilder {
386386
binding_owners,
387387
block_scopes: block_scopes.into_boxed_slice(),
388388
ident_hygiene,
389-
const_expr_origins: const_expr_origins.unwrap_or_default(),
389+
expr_roots: expr_roots.unwrap_or_default(),
390390
}))
391391
} else {
392392
None
@@ -448,6 +448,9 @@ impl ExpressionStore {
448448
}
449449
}
450450
ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store,
451+
ExpressionStoreOwnerId::VariantFields(variant_id) => {
452+
&VariantFields::of(db, variant_id).store
453+
}
451454
}
452455
}
453456

@@ -505,30 +508,27 @@ impl ExpressionStore {
505508
let (store, sm) = Body::with_source_map(db, body);
506509
(&store.store, &sm.store)
507510
}
511+
ExpressionStoreOwnerId::VariantFields(variant_id) => {
512+
let (store, sm) = VariantFields::with_source_map(db, variant_id);
513+
(&store.store, sm)
514+
}
508515
}
509516
}
510517

511-
/// Returns all const expression root `ExprId`s found in this store.
512-
///
513-
/// Used to compute expression scopes for signature stores.
514-
pub fn signature_const_expr_roots(&self) -> impl Iterator<Item = ExprId> {
518+
/// Returns all expression root `ExprId`s found in this store.
519+
pub fn expr_roots(&self) -> impl Iterator<Item = ExprId> {
515520
self.const_expr_origins().iter().map(|&(id, _)| id)
516521
}
517522

518523
/// Like [`Self::signature_const_expr_roots`], but also returns the origin
519-
/// of each const expression.
520-
///
521-
/// This is used by signature inference to determine the expected type for
522-
/// each root expression.
523-
pub fn signature_const_expr_roots_with_origins(
524-
&self,
525-
) -> impl Iterator<Item = (ExprId, ConstExprOrigin)> {
524+
/// of each expression.
525+
pub fn expr_roots_with_origins(&self) -> impl Iterator<Item = (ExprId, RootExprOrigin)> {
526526
self.const_expr_origins().iter().map(|&(id, origin)| (id, origin))
527527
}
528528

529529
/// Returns the map of const expression roots to their origins.
530-
pub fn const_expr_origins(&self) -> &[(ExprId, ConstExprOrigin)] {
531-
self.expr_only.as_ref().map_or(&[], |it| &it.const_expr_origins)
530+
pub fn const_expr_origins(&self) -> &[(ExprId, RootExprOrigin)] {
531+
self.expr_only.as_ref().map_or(&[], |it| &it.expr_roots)
532532
}
533533

534534
/// Returns an iterator over all block expressions in this store that define inner items.

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ pub struct Body {
2929
/// empty.
3030
pub params: Box<[PatId]>,
3131
pub self_param: Option<BindingId>,
32-
/// The `ExprId` of the actual body expression.
33-
pub body_expr: ExprId,
3432
}
3533

3634
impl ops::Deref for Body {
@@ -115,6 +113,10 @@ impl Body {
115113
}
116114

117115
impl Body {
116+
pub fn root_expr(&self) -> ExprId {
117+
self.store.expr_roots().next().unwrap()
118+
}
119+
118120
pub fn pretty_print(
119121
&self,
120122
db: &dyn DefDatabase,

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

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use hir_expand::{
1818
};
1919
use intern::{Symbol, sym};
2020
use rustc_hash::FxHashMap;
21+
use smallvec::smallvec;
2122
use stdx::never;
2223
use syntax::{
2324
AstNode, AstPtr, SyntaxNodePtr,
@@ -36,9 +37,9 @@ use crate::{
3637
attrs::AttrFlags,
3738
db::DefDatabase,
3839
expr_store::{
39-
Body, BodySourceMap, ConstExprOrigin, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
40+
Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
4041
ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr,
41-
PatPtr, TypePtr,
42+
PatPtr, RootExprOrigin, TypePtr,
4243
expander::Expander,
4344
lower::generics::ImplTraitLowerFn,
4445
path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path},
@@ -117,9 +118,10 @@ pub(super) fn lower_body(
117118
params = (0..count).map(|_| collector.missing_pat()).collect();
118119
};
119120
let body_expr = collector.missing_expr();
121+
collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]);
120122
let (store, source_map) = collector.store.finish();
121123
return (
122-
Body { store, params: params.into_boxed_slice(), self_param, body_expr },
124+
Body { store, params: params.into_boxed_slice(), self_param },
123125
BodySourceMap { self_param: source_map_self_param, store: source_map },
124126
);
125127
}
@@ -173,10 +175,11 @@ pub(super) fn lower_body(
173175
}
174176
},
175177
);
178+
collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]);
176179

177180
let (store, source_map) = collector.store.finish();
178181
(
179-
Body { store, params: params.into_boxed_slice(), self_param, body_expr },
182+
Body { store, params: params.into_boxed_slice(), self_param },
180183
BodySourceMap { self_param: source_map_self_param, store: source_map },
181184
)
182185
}
@@ -535,7 +538,7 @@ impl<'db> ExprCollector<'db> {
535538
current_file_id: HirFileId,
536539
) -> ExprCollector<'_> {
537540
let mut this = Self::body(db, module, current_file_id);
538-
this.store.const_expr_origins = Some(Default::default());
541+
this.store.inference_roots = Some(Default::default());
539542
this
540543
}
541544

@@ -635,8 +638,8 @@ impl<'db> ExprCollector<'db> {
635638
}
636639
ast::Type::ArrayType(inner) => {
637640
let len = self.lower_const_arg_opt(inner.const_arg());
638-
if let Some(const_expr_origins) = &mut self.store.const_expr_origins {
639-
const_expr_origins.push((len.expr, ConstExprOrigin::ArrayLength));
641+
if let Some(const_expr_origins) = &mut self.store.inference_roots {
642+
const_expr_origins.push((len.expr, RootExprOrigin::ArrayLength));
640643
}
641644
TypeRef::Array(ArrayType {
642645
ty: self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn),
@@ -922,8 +925,8 @@ impl<'db> ExprCollector<'db> {
922925
}
923926
ast::GenericArg::ConstArg(arg) => {
924927
let arg = self.lower_const_arg(arg);
925-
if let Some(const_expr_origins) = &mut self.store.const_expr_origins {
926-
const_expr_origins.push((arg.expr, ConstExprOrigin::GenericArgsPath));
928+
if let Some(const_expr_origins) = &mut self.store.inference_roots {
929+
const_expr_origins.push((arg.expr, RootExprOrigin::GenericArgsPath));
927930
}
928931
args.push(GenericArg::Const(arg))
929932
}
@@ -1065,16 +1068,16 @@ impl<'db> ExprCollector<'db> {
10651068
}
10661069

10671070
fn lower_const_arg_opt(&mut self, arg: Option<ast::ConstArg>) -> ConstRef {
1068-
let const_expr_origins = self.store.const_expr_origins.take();
1071+
let const_expr_origins = self.store.inference_roots.take();
10691072
let r = ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) };
1070-
self.store.const_expr_origins = const_expr_origins;
1073+
self.store.inference_roots = const_expr_origins;
10711074
r
10721075
}
10731076

10741077
pub fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef {
1075-
let const_expr_origins = self.store.const_expr_origins.take();
1078+
let const_expr_origins = self.store.inference_roots.take();
10761079
let r = ConstRef { expr: self.collect_expr_opt(arg.expr()) };
1077-
self.store.const_expr_origins = const_expr_origins;
1080+
self.store.inference_roots = const_expr_origins;
10781081
r
10791082
}
10801083

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ impl GenericParamsCollector {
130130
let param = ConstParamData { name, ty, default };
131131
let idx = self.type_or_consts.alloc(param.into());
132132
if let Some(default) = default
133-
&& let Some(const_expr_origins) = &mut ec.store.const_expr_origins
133+
&& let Some(const_expr_origins) = &mut ec.store.inference_roots
134134
{
135135
const_expr_origins.push((
136136
default.expr,
137-
crate::expr_store::ConstExprOrigin::ConstParam(idx),
137+
crate::expr_store::RootExprOrigin::ConstParam(idx),
138138
));
139139
}
140140
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub fn print_body_hir(
105105
p.buf.push(')');
106106
p.buf.push(' ');
107107
}
108-
p.print_expr(body.body_expr);
108+
p.print_expr(body.root_expr());
109109
if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) {
110110
p.buf.push(';');
111111
}

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use hir_expand::{MacroDefId, name::Name};
33
use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx};
44

55
use crate::{
6-
BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId,
6+
BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, VariantId,
77
db::DefDatabase,
88
expr_store::{Body, ExpressionStore, HygieneId},
99
hir::{
1010
Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement,
1111
generics::GenericParams,
1212
},
13+
signatures::VariantFields,
1314
};
1415

1516
pub type ScopeId = Idx<ScopeData>;
@@ -65,11 +66,20 @@ impl ExprScopes {
6566
#[salsa::tracked(returns(ref))]
6667
pub fn sig_expr_scopes(db: &dyn DefDatabase, def: GenericDefId) -> ExprScopes {
6768
let (_, store) = GenericParams::with_store(db, def);
68-
let roots = store.signature_const_expr_roots();
69+
let roots = store.expr_roots();
6970
let mut scopes = ExprScopes::new_store(store, roots);
7071
scopes.shrink_to_fit();
7172
scopes
7273
}
74+
75+
#[salsa::tracked(returns(ref))]
76+
pub fn variant_scopes(db: &dyn DefDatabase, def: VariantId) -> ExprScopes {
77+
let fields = VariantFields::of(db, def);
78+
let roots = fields.store.expr_roots();
79+
let mut scopes = ExprScopes::new_store(&fields.store, roots);
80+
scopes.shrink_to_fit();
81+
scopes
82+
}
7383
}
7484

7585
impl ExprScopes {
@@ -78,6 +88,9 @@ impl ExprScopes {
7888
match def.into() {
7989
ExpressionStoreOwnerId::Body(def) => Self::body_expr_scopes(db, def),
8090
ExpressionStoreOwnerId::Signature(def) => Self::sig_expr_scopes(db, def),
91+
ExpressionStoreOwnerId::VariantFields(variant_id) => {
92+
Self::variant_scopes(db, variant_id)
93+
}
8194
}
8295
}
8396

@@ -138,7 +151,7 @@ impl ExprScopes {
138151
scopes.add_bindings(body, root, self_param, body.binding_hygiene(self_param));
139152
}
140153
scopes.add_params_bindings(body, root, &body.params);
141-
compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
154+
compute_expr_scopes(body.root_expr(), body, &mut scopes, &mut root);
142155
scopes
143156
}
144157

0 commit comments

Comments
 (0)