mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
fix: Attempt to resolve paths in const arguments heuristically
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.
This commit is contained in:
parent
7959c24876
commit
4a1423337f
@ -299,45 +299,53 @@ impl SourceAnalyzer {
|
|||||||
let parent = || parent.clone();
|
let parent = || parent.clone();
|
||||||
|
|
||||||
let mut prefer_value_ns = false;
|
let mut prefer_value_ns = false;
|
||||||
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
|
let resolved = (|| {
|
||||||
let expr_id = self.expr_id(db, &path_expr.into())?;
|
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
|
||||||
let infer = self.infer.as_ref()?;
|
let expr_id = self.expr_id(db, &path_expr.into())?;
|
||||||
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
|
let infer = self.infer.as_ref()?;
|
||||||
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
|
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
|
||||||
}
|
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
|
||||||
if let Some(VariantId::EnumVariantId(variant)) =
|
}
|
||||||
infer.variant_resolution_for_expr(expr_id)
|
if let Some(VariantId::EnumVariantId(variant)) =
|
||||||
{
|
infer.variant_resolution_for_expr(expr_id)
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
{
|
||||||
}
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
prefer_value_ns = true;
|
}
|
||||||
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
|
prefer_value_ns = true;
|
||||||
let pat_id = self.pat_id(&path_pat.into())?;
|
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
|
||||||
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
|
let pat_id = self.pat_id(&path_pat.into())?;
|
||||||
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
|
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
|
||||||
}
|
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
|
||||||
if let Some(VariantId::EnumVariantId(variant)) =
|
}
|
||||||
self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
|
if let Some(VariantId::EnumVariantId(variant)) =
|
||||||
{
|
self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
{
|
||||||
}
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
|
}
|
||||||
let expr_id = self.expr_id(db, &rec_lit.into())?;
|
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
|
||||||
if let Some(VariantId::EnumVariantId(variant)) =
|
let expr_id = self.expr_id(db, &rec_lit.into())?;
|
||||||
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
|
if let Some(VariantId::EnumVariantId(variant)) =
|
||||||
{
|
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
{
|
||||||
}
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
|
let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
|
||||||
let tuple_struct_pat = || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
|
let tuple_struct_pat =
|
||||||
if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
|
|| parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
|
||||||
let pat_id = self.pat_id(&pat)?;
|
if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
|
||||||
let variant_res_for_pat = self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
|
let pat_id = self.pat_id(&pat)?;
|
||||||
if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
|
let variant_res_for_pat =
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
|
||||||
|
if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
|
||||||
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
None
|
||||||
|
})();
|
||||||
|
if let resolved @ Some(_) = resolved {
|
||||||
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This must be a normal source file rather than macro file.
|
// This must be a normal source file rather than macro file.
|
||||||
|
@ -295,13 +295,13 @@ impl<'a> Ctx<'a> {
|
|||||||
let mut pat = param.pat();
|
let mut pat = param.pat();
|
||||||
// FIXME: This really shouldn't be here, in fact FunctionData/ItemTree's function shouldn't know about
|
// FIXME: This really shouldn't be here, in fact FunctionData/ItemTree's function shouldn't know about
|
||||||
// pattern names at all
|
// pattern names at all
|
||||||
let name = loop {
|
let name = 'name: loop {
|
||||||
match pat {
|
match pat {
|
||||||
Some(ast::Pat::RefPat(ref_pat)) => pat = ref_pat.pat(),
|
Some(ast::Pat::RefPat(ref_pat)) => pat = ref_pat.pat(),
|
||||||
Some(ast::Pat::IdentPat(ident)) => {
|
Some(ast::Pat::IdentPat(ident)) => {
|
||||||
break ident.name().map(|it| it.as_name())
|
break 'name ident.name().map(|it| it.as_name())
|
||||||
}
|
}
|
||||||
_ => break None,
|
_ => break 'name None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.data().params.alloc(Param::Normal(name, ty))
|
self.data().params.alloc(Param::Normal(name, ty))
|
||||||
|
@ -118,6 +118,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
<span class="brace">}</span>
|
<span class="brace">}</span>
|
||||||
|
|
||||||
<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle"><</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">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="brace">{</span>
|
<span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle"><</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">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="brace">{</span>
|
||||||
|
<span class="function">const_param</span><span class="operator">::</span><span class="angle"><</span><span class="brace">{</span> <span class="const_param">FOO</span> <span class="brace">}</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
||||||
<span class="const_param">FOO</span>
|
<span class="const_param">FOO</span>
|
||||||
<span class="brace">}</span>
|
<span class="brace">}</span>
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ fn never() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn const_param<const FOO: usize>() -> usize {
|
fn const_param<const FOO: usize>() -> usize {
|
||||||
|
const_param::<{ FOO }>();
|
||||||
FOO
|
FOO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user