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 @@ pub(crate) fn resolve_path( 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 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option> 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 }