Skip to content

Commit 408301a

Browse files
committed
Hookup semantics
1 parent 3fe9faf commit 408301a

4 files changed

Lines changed: 80 additions & 34 deletions

File tree

crates/hir/src/semantics.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,15 +2149,15 @@ impl<'db> SemanticsImpl<'db> {
21492149
node: InFile<&SyntaxNode>,
21502150
offset: Option<TextSize>,
21512151
// replace this, just make the inference result a `LazyCell`
2152-
infer_body: bool,
2152+
infer: bool,
21532153
) -> Option<SourceAnalyzer<'db>> {
21542154
let _p = tracing::info_span!("SemanticsImpl::analyze_impl").entered();
21552155

21562156
let container = self.with_ctx(|ctx| ctx.find_container(node))?;
21572157

21582158
let resolver = match container {
21592159
ChildContainer::DefWithBodyId(def) => {
2160-
return Some(if infer_body {
2160+
return Some(if infer {
21612161
SourceAnalyzer::new_for_body(self.db, def, node, offset)
21622162
} else {
21632163
SourceAnalyzer::new_for_body_no_infer(self.db, def, node, offset)
@@ -2167,16 +2167,32 @@ impl<'db> SemanticsImpl<'db> {
21672167
return Some(SourceAnalyzer::new_variant_body(self.db, def, node, offset));
21682168
}
21692169
ChildContainer::TraitId(it) => {
2170-
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
2170+
return Some(if infer {
2171+
SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)
2172+
} else {
2173+
SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset)
2174+
});
21712175
}
21722176
ChildContainer::ImplId(it) => {
2173-
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
2177+
return Some(if infer {
2178+
SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)
2179+
} else {
2180+
SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset)
2181+
});
21742182
}
21752183
ChildContainer::EnumId(it) => {
2176-
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
2184+
return Some(if infer {
2185+
SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)
2186+
} else {
2187+
SourceAnalyzer::new_generic_def_no_infer(self.db, it.into(), node, offset)
2188+
});
21772189
}
21782190
ChildContainer::GenericDefId(it) => {
2179-
return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset));
2191+
return Some(if infer {
2192+
SourceAnalyzer::new_generic_def(self.db, it, node, offset)
2193+
} else {
2194+
SourceAnalyzer::new_generic_def_no_infer(self.db, it, node, offset)
2195+
});
21802196
}
21812197
ChildContainer::ModuleId(it) => it.resolver(self.db),
21822198
};

crates/hir/src/source_analyzer.rs

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use hir_def::{
1717
path::Path,
1818
scope::{ExprScopes, ScopeId},
1919
},
20-
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId},
20+
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId, generics::GenericParams},
2121
lang_item::LangItems,
2222
nameres::MacroSubNs,
2323
resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope},
@@ -92,7 +92,9 @@ pub(crate) enum BodyOrSig<'db> {
9292
def: GenericDefId,
9393
store: Arc<ExpressionStore>,
9494
source_map: Arc<ExpressionStoreSourceMap>,
95-
// infer: Option<Arc<InferenceResult>>,
95+
infer: Option<&'db InferenceResult>,
96+
#[expect(dead_code)]
97+
generics: Arc<GenericParams>,
9698
},
9799
}
98100

@@ -147,14 +149,46 @@ impl<'db> SourceAnalyzer<'db> {
147149
pub(crate) fn new_generic_def(
148150
db: &'db dyn HirDatabase,
149151
def: GenericDefId,
150-
InFile { file_id, .. }: InFile<&SyntaxNode>,
151-
_offset: Option<TextSize>,
152+
node: InFile<&SyntaxNode>,
153+
offset: Option<TextSize>,
152154
) -> SourceAnalyzer<'db> {
153-
let (_params, store, source_map) = db.generic_params_and_store_and_source_map(def);
154-
let resolver = def.resolver(db);
155+
Self::new_generic_def_(db, def, node, offset, Some(InferenceResult::for_signature(db, def)))
156+
}
157+
158+
pub(crate) fn new_generic_def_no_infer(
159+
db: &'db dyn HirDatabase,
160+
def: GenericDefId,
161+
node: InFile<&SyntaxNode>,
162+
offset: Option<TextSize>,
163+
) -> SourceAnalyzer<'db> {
164+
Self::new_generic_def_(db, def, node, offset, None)
165+
}
166+
167+
pub(crate) fn new_generic_def_(
168+
db: &'db dyn HirDatabase,
169+
def: GenericDefId,
170+
node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
171+
offset: Option<TextSize>,
172+
infer: Option<&'db InferenceResult>,
173+
) -> SourceAnalyzer<'db> {
174+
let (generics, store, source_map) = db.generic_params_and_store_and_source_map(def);
175+
let scopes = db.expr_scopes(def.into());
176+
let scope = match offset {
177+
None => scope_for(db, &scopes, &source_map, node),
178+
Some(offset) => {
179+
debug_assert!(
180+
node.text_range().contains_inclusive(offset),
181+
"{:?} not in {:?}",
182+
offset,
183+
node.text_range()
184+
);
185+
scope_for_offset(db, &scopes, &source_map, node.file_id, offset)
186+
}
187+
};
188+
let resolver = resolver_for_scope(db, def, scope);
155189
SourceAnalyzer {
156190
resolver,
157-
body_or_sig: Some(BodyOrSig::Sig { def, store, source_map }),
191+
body_or_sig: Some(BodyOrSig::Sig { def, store, source_map, generics, infer }),
158192
file_id,
159193
}
160194
}
@@ -197,17 +231,8 @@ impl<'db> SourceAnalyzer<'db> {
197231

198232
fn infer(&self) -> Option<&InferenceResult> {
199233
self.body_or_sig.as_ref().and_then(|it| match it {
200-
BodyOrSig::Sig { .. } => None,
201234
BodyOrSig::VariantFields { .. } => None,
202-
BodyOrSig::Body { infer, .. } => infer.as_deref(),
203-
})
204-
}
205-
206-
fn body(&self) -> Option<&Body> {
207-
self.body_or_sig.as_ref().and_then(|it| match it {
208-
BodyOrSig::Sig { .. } => None,
209-
BodyOrSig::VariantFields { .. } => None,
210-
BodyOrSig::Body { body, .. } => Some(&**body),
235+
BodyOrSig::Sig { infer, .. } | BodyOrSig::Body { infer, .. } => infer.as_deref(),
211236
})
212237
}
213238

@@ -232,11 +257,13 @@ impl<'db> SourceAnalyzer<'db> {
232257
}
233258

234259
fn trait_environment(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> {
235-
self.param_and(
236-
self.body_()
237-
.map(|(def, ..)| def)
238-
.map_or_else(ParamEnv::empty, |def| db.trait_environment_for_body(def)),
239-
)
260+
self.param_and(self.body_or_sig.as_ref().map_or_else(ParamEnv::empty, |body_or_sig| {
261+
match *body_or_sig {
262+
BodyOrSig::Body { def, .. } => db.trait_environment_for_body(def),
263+
BodyOrSig::VariantFields { .. } => ParamEnv::empty(),
264+
BodyOrSig::Sig { def, .. } => db.trait_environment(def),
265+
}
266+
}))
240267
}
241268

242269
pub(crate) fn expr_id(&self, expr: ast::Expr) -> Option<ExprOrPatId> {
@@ -371,7 +398,10 @@ impl<'db> SourceAnalyzer<'db> {
371398
db: &'db dyn HirDatabase,
372399
_param: &ast::SelfParam,
373400
) -> Option<Type<'db>> {
374-
let binding = self.body()?.self_param?;
401+
let binding = match self.body_or_sig.as_ref()? {
402+
BodyOrSig::Sig { .. } | BodyOrSig::VariantFields { .. } => return None,
403+
BodyOrSig::Body { body, .. } => body.self_param?,
404+
};
375405
let ty = self.infer()?.binding_ty(binding);
376406
Some(Type::new_with_resolver(db, &self.resolver, ty))
377407
}
@@ -1526,7 +1556,7 @@ impl<'db> SourceAnalyzer<'db> {
15261556
fn scope_for(
15271557
db: &dyn HirDatabase,
15281558
scopes: &ExprScopes,
1529-
source_map: &BodySourceMap,
1559+
source_map: &ExpressionStoreSourceMap,
15301560
node: InFile<&SyntaxNode>,
15311561
) -> Option<ScopeId> {
15321562
node.ancestors_with_macros(db)
@@ -1545,7 +1575,7 @@ fn scope_for(
15451575
fn scope_for_offset(
15461576
db: &dyn HirDatabase,
15471577
scopes: &ExprScopes,
1548-
source_map: &BodySourceMap,
1578+
source_map: &ExpressionStoreSourceMap,
15491579
from_file: HirFileId,
15501580
offset: TextSize,
15511581
) -> Option<ScopeId> {
@@ -1579,7 +1609,7 @@ fn scope_for_offset(
15791609
fn adjust(
15801610
db: &dyn HirDatabase,
15811611
scopes: &ExprScopes,
1582-
source_map: &BodySourceMap,
1612+
source_map: &ExpressionStoreSourceMap,
15831613
expr_range: TextRange,
15841614
from_file: HirFileId,
15851615
offset: TextSize,

crates/ide/src/syntax_highlighting/test_data/highlight_general.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
<span class="keyword control">loop</span> <span class="brace">{</span><span class="brace">}</span>
106106
<span class="brace">}</span>
107107

108-
<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle">&lt;</span><span class="keyword const">const</span> <span class="const_param const declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">usize</span> <span class="brace">{</span>
108+
<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle">&lt;</span><span class="keyword const">const</span> <span class="const_param const declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">usize</span> <span class="keyword">where</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="const_param const">FOO</span><span class="bracket">]</span><span class="colon">:</span> <span class="trait default_library library">Sized</span> <span class="brace">{</span>
109109
<span class="function">const_param</span><span class="operator">::</span><span class="angle">&lt;</span><span class="brace">{</span> <span class="const_param const">FOO</span> <span class="brace">}</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
110110
<span class="const_param const">FOO</span>
111111
<span class="brace">}</span>

crates/ide/src/syntax_highlighting/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ fn never() -> ! {
210210
loop {}
211211
}
212212
213-
fn const_param<const FOO: usize>() -> usize {
213+
fn const_param<const FOO: usize>() -> usize where [(); FOO]: Sized {
214214
const_param::<{ FOO }>();
215215
FOO
216216
}

0 commit comments

Comments
 (0)