diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index e96c4007407..c9eb134e943 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -299,45 +299,53 @@ impl SourceAnalyzer {
let parent = || parent.clone();
let mut prefer_value_ns = false;
- if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
- let expr_id = self.expr_id(db, &path_expr.into())?;
- let infer = self.infer.as_ref()?;
- 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)
- {
- return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
- }
- prefer_value_ns = true;
- } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
- let pat_id = self.pat_id(&path_pat.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)
- {
- 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())?;
- if let Some(VariantId::EnumVariantId(variant)) =
- self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
- {
- return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
- }
- }
-
- 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);
- if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
- let pat_id = self.pat_id(&pat)?;
- let variant_res_for_pat = 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())));
+ let resolved = (|| {
+ if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
+ let expr_id = self.expr_id(db, &path_expr.into())?;
+ let infer = self.infer.as_ref()?;
+ 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)
+ {
+ return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
+ }
+ prefer_value_ns = true;
+ } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
+ let pat_id = self.pat_id(&path_pat.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)
+ {
+ 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())?;
+ if let Some(VariantId::EnumVariantId(variant)) =
+ self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
+ {
+ return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
+ }
+ } else {
+ 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);
+ if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
+ let pat_id = self.pat_id(&pat)?;
+ let variant_res_for_pat =
+ 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.
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 3fa2d9d32cc..d6c5feefa32 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -295,13 +295,13 @@ impl<'a> Ctx<'a> {
let mut pat = param.pat();
// FIXME: This really shouldn't be here, in fact FunctionData/ItemTree's function shouldn't know about
// pattern names at all
- let name = loop {
+ let name = 'name: loop {
match pat {
Some(ast::Pat::RefPat(ref_pat)) => pat = ref_pat.pat(),
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))
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index 1abb6eb8f39..7bb7ddd2804 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -118,6 +118,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
}
fn const_param<const FOO: usize>() -> usize {
+ const_param::<{ FOO }>();
FOO
}
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index d7686695942..e436a0574b5 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -172,6 +172,7 @@ fn never() -> ! {
}
fn const_param() -> usize {
+ const_param::<{ FOO }>();
FOO
}