Skip to content

Commit ec56c7e

Browse files
bors[bot]Veykril
andauthored
Merge #11915
11915: fix: Attempt to resolve paths in const arguments heuristically in IDE layer r=Veykril a=Veykril While we don't support const args in type inference yet, we can at least make use of the fallback path resolution to resolve paths in const args in the IDE layer to enable some features for them. bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents f4e4a3a + 4a14233 commit ec56c7e

File tree

4 files changed

+51
-41
lines changed

4 files changed

+51
-41
lines changed

crates/hir/src/source_analyzer.rs

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -299,45 +299,53 @@ impl SourceAnalyzer {
299299
let parent = || parent.clone();
300300

301301
let mut prefer_value_ns = false;
302-
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
303-
let expr_id = self.expr_id(db, &path_expr.into())?;
304-
let infer = self.infer.as_ref()?;
305-
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
306-
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
307-
}
308-
if let Some(VariantId::EnumVariantId(variant)) =
309-
infer.variant_resolution_for_expr(expr_id)
310-
{
311-
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
312-
}
313-
prefer_value_ns = true;
314-
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
315-
let pat_id = self.pat_id(&path_pat.into())?;
316-
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
317-
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
318-
}
319-
if let Some(VariantId::EnumVariantId(variant)) =
320-
self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
321-
{
322-
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
323-
}
324-
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
325-
let expr_id = self.expr_id(db, &rec_lit.into())?;
326-
if let Some(VariantId::EnumVariantId(variant)) =
327-
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
328-
{
329-
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
330-
}
331-
}
332-
333-
let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
334-
let tuple_struct_pat = || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
335-
if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
336-
let pat_id = self.pat_id(&pat)?;
337-
let variant_res_for_pat = self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
338-
if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
339-
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
302+
let resolved = (|| {
303+
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
304+
let expr_id = self.expr_id(db, &path_expr.into())?;
305+
let infer = self.infer.as_ref()?;
306+
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
307+
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
308+
}
309+
if let Some(VariantId::EnumVariantId(variant)) =
310+
infer.variant_resolution_for_expr(expr_id)
311+
{
312+
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
313+
}
314+
prefer_value_ns = true;
315+
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
316+
let pat_id = self.pat_id(&path_pat.into())?;
317+
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
318+
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
319+
}
320+
if let Some(VariantId::EnumVariantId(variant)) =
321+
self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
322+
{
323+
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
324+
}
325+
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
326+
let expr_id = self.expr_id(db, &rec_lit.into())?;
327+
if let Some(VariantId::EnumVariantId(variant)) =
328+
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
329+
{
330+
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
331+
}
332+
} else {
333+
let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
334+
let tuple_struct_pat =
335+
|| parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
336+
if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
337+
let pat_id = self.pat_id(&pat)?;
338+
let variant_res_for_pat =
339+
self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
340+
if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
341+
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
342+
}
343+
}
340344
}
345+
None
346+
})();
347+
if let resolved @ Some(_) = resolved {
348+
return resolved;
341349
}
342350

343351
// This must be a normal source file rather than macro file.

crates/hir_def/src/item_tree/lower.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,13 @@ impl<'a> Ctx<'a> {
295295
let mut pat = param.pat();
296296
// FIXME: This really shouldn't be here, in fact FunctionData/ItemTree's function shouldn't know about
297297
// pattern names at all
298-
let name = loop {
298+
let name = 'name: loop {
299299
match pat {
300300
Some(ast::Pat::RefPat(ref_pat)) => pat = ref_pat.pat(),
301301
Some(ast::Pat::IdentPat(ident)) => {
302-
break ident.name().map(|it| it.as_name())
302+
break 'name ident.name().map(|it| it.as_name())
303303
}
304-
_ => break None,
304+
_ => break 'name None,
305305
}
306306
};
307307
self.data().params.alloc(Param::Normal(name, ty))

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
<span class="brace">}</span>
119119

120120
<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle">&lt;</span><span class="keyword">const</span> <span class="const_param 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>
121+
<span class="function">const_param</span><span class="operator">::</span><span class="angle">&lt;</span><span class="brace">{</span> <span class="const_param">FOO</span> <span class="brace">}</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
121122
<span class="const_param">FOO</span>
122123
<span class="brace">}</span>
123124

crates/ide/src/syntax_highlighting/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ fn never() -> ! {
172172
}
173173
174174
fn const_param<const FOO: usize>() -> usize {
175+
const_param::<{ FOO }>();
175176
FOO
176177
}
177178

0 commit comments

Comments
 (0)