mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Merge #4520
4520: Marks 2.0 r=matklad a=matklad The main benefit here is that we no longer need to declare marks. The main drawback is that this is ~~glorious~~ horrible. WDYT? Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
e3373629cd
49 changed files with 184 additions and 293 deletions
|
@ -1,6 +1,6 @@
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::ast::{self, AstNode, NameOwner};
|
use ra_syntax::ast::{self, AstNode, NameOwner};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) ->
|
||||||
};
|
};
|
||||||
|
|
||||||
if existing_from_impl(&ctx.sema, &variant).is_some() {
|
if existing_from_impl(&ctx.sema, &variant).is_some() {
|
||||||
tested_by!(test_add_from_impl_already_exists);
|
mark::hit!(test_add_from_impl_already_exists);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ fn existing_from_impl(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ impl From<foo::bar::baz::Boo> for A {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_from_impl_already_exists() {
|
fn test_add_from_impl_already_exists() {
|
||||||
covers!(test_add_from_impl_already_exists);
|
mark::check!(test_add_from_impl_already_exists);
|
||||||
check_not_applicable(
|
check_not_applicable(
|
||||||
r#"
|
r#"
|
||||||
enum A { <|>One(u32), }
|
enum A { <|>One(u32), }
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass};
|
use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass};
|
||||||
use ra_syntax::{ast, AstNode, SyntaxKind, T};
|
use ra_syntax::{ast, AstNode, SyntaxKind, T};
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assist_context::{AssistContext, Assists},
|
assist_context::{AssistContext, Assists},
|
||||||
AssistId,
|
AssistId,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
|
||||||
|
|
||||||
// Assist: add_turbo_fish
|
// Assist: add_turbo_fish
|
||||||
//
|
//
|
||||||
|
@ -28,7 +28,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
||||||
let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?;
|
let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?;
|
||||||
let next_token = ident.next_token()?;
|
let next_token = ident.next_token()?;
|
||||||
if next_token.kind() == T![::] {
|
if next_token.kind() == T![::] {
|
||||||
tested_by!(add_turbo_fish_one_fish_is_enough);
|
mark::hit!(add_turbo_fish_one_fish_is_enough);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let name_ref = ast::NameRef::cast(ident.parent())?;
|
let name_ref = ast::NameRef::cast(ident.parent())?;
|
||||||
|
@ -42,7 +42,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
||||||
};
|
};
|
||||||
let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
|
let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
|
||||||
if generics.is_empty() {
|
if generics.is_empty() {
|
||||||
tested_by!(add_turbo_fish_non_generic);
|
mark::hit!(add_turbo_fish_non_generic);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| {
|
acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| {
|
||||||
|
@ -58,7 +58,7 @@ mod tests {
|
||||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_turbo_fish_function() {
|
fn add_turbo_fish_function() {
|
||||||
|
@ -106,7 +106,7 @@ fn main() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_turbo_fish_one_fish_is_enough() {
|
fn add_turbo_fish_one_fish_is_enough() {
|
||||||
covers!(add_turbo_fish_one_fish_is_enough);
|
mark::check!(add_turbo_fish_one_fish_is_enough);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
add_turbo_fish,
|
add_turbo_fish,
|
||||||
r#"
|
r#"
|
||||||
|
@ -120,7 +120,7 @@ fn main() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_turbo_fish_non_generic() {
|
fn add_turbo_fish_non_generic() {
|
||||||
covers!(add_turbo_fish_non_generic);
|
mark::check!(add_turbo_fish_non_generic);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
add_turbo_fish,
|
add_turbo_fish,
|
||||||
r#"
|
r#"
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
|
use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{AssistContext, AssistId, Assists};
|
use crate::{AssistContext, AssistId, Assists};
|
||||||
use ra_db::FileId;
|
use ra_db::FileId;
|
||||||
|
@ -55,7 +55,7 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||||
} else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
|
} else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
|
||||||
let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
|
let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
|
||||||
if field.name()? != field_name {
|
if field.name()? != field_name {
|
||||||
tested_by!(change_visibility_field_false_positive);
|
mark::hit!(change_visibility_field_false_positive);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if field.visibility().is_some() {
|
if field.visibility().is_some() {
|
||||||
|
@ -255,7 +255,7 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn change_visibility_field_false_positive() {
|
fn change_visibility_field_false_positive() {
|
||||||
covers!(change_visibility_field_false_positive);
|
mark::check!(change_visibility_field_false_positive);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
change_visibility,
|
change_visibility,
|
||||||
r"struct S { field: [(); { let <|>x = ();}] }",
|
r"struct S { field: [(); { let <|>x = ();}] }",
|
||||||
|
|
|
@ -4,7 +4,7 @@ use hir::{Adt, HasSource, ModuleDef, Semantics};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
|
use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
|
if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
|
||||||
// Match `Some` variant first.
|
// Match `Some` variant first.
|
||||||
tested_by!(option_order);
|
mark::hit!(option_order);
|
||||||
variants.reverse()
|
variants.reverse()
|
||||||
}
|
}
|
||||||
variants
|
variants
|
||||||
|
@ -174,13 +174,14 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tests::{check_assist, check_assist_not_applicable, check_assist_target},
|
tests::{check_assist, check_assist_not_applicable, check_assist_target},
|
||||||
utils::FamousDefs,
|
utils::FamousDefs,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fill_match_arms;
|
use super::fill_match_arms;
|
||||||
use test_utils::covers;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn all_match_arms_provided() {
|
fn all_match_arms_provided() {
|
||||||
|
@ -750,7 +751,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn option_order() {
|
fn option_order() {
|
||||||
covers!(option_order);
|
mark::check!(option_order);
|
||||||
let before = r#"
|
let before = r#"
|
||||||
fn foo(opt: Option<i32>) {
|
fn foo(opt: Option<i32>) {
|
||||||
match opt<|> {
|
match opt<|> {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode, AstToken},
|
ast::{self, AstNode, AstToken},
|
||||||
TextRange,
|
TextRange,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assist_context::{AssistContext, Assists},
|
assist_context::{AssistContext, Assists},
|
||||||
|
@ -33,11 +33,11 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if bind_pat.mut_token().is_some() {
|
if bind_pat.mut_token().is_some() {
|
||||||
tested_by!(test_not_inline_mut_variable);
|
mark::hit!(test_not_inline_mut_variable);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) {
|
if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) {
|
||||||
tested_by!(not_applicable_outside_of_bind_pat);
|
mark::hit!(not_applicable_outside_of_bind_pat);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let initializer_expr = let_stmt.initializer()?;
|
let initializer_expr = let_stmt.initializer()?;
|
||||||
|
@ -46,7 +46,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
|
||||||
let def = Definition::Local(def);
|
let def = Definition::Local(def);
|
||||||
let refs = def.find_usages(ctx.db, None);
|
let refs = def.find_usages(ctx.db, None);
|
||||||
if refs.is_empty() {
|
if refs.is_empty() {
|
||||||
tested_by!(test_not_applicable_if_variable_unused);
|
mark::hit!(test_not_applicable_if_variable_unused);
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ fn foo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_not_inline_mut_variable() {
|
fn test_not_inline_mut_variable() {
|
||||||
covers!(test_not_inline_mut_variable);
|
mark::check!(test_not_inline_mut_variable);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
inline_local_variable,
|
inline_local_variable,
|
||||||
r"
|
r"
|
||||||
|
@ -663,7 +663,7 @@ fn foo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_not_applicable_if_variable_unused() {
|
fn test_not_applicable_if_variable_unused() {
|
||||||
covers!(test_not_applicable_if_variable_unused);
|
mark::check!(test_not_applicable_if_variable_unused);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
inline_local_variable,
|
inline_local_variable,
|
||||||
r"
|
r"
|
||||||
|
@ -676,7 +676,7 @@ fn foo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn not_applicable_outside_of_bind_pat() {
|
fn not_applicable_outside_of_bind_pat() {
|
||||||
covers!(not_applicable_outside_of_bind_pat);
|
mark::check!(not_applicable_outside_of_bind_pat);
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
inline_local_variable,
|
inline_local_variable,
|
||||||
r"
|
r"
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||||
SyntaxNode, TextSize,
|
SyntaxNode, TextSize,
|
||||||
};
|
};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{AssistContext, AssistId, Assists};
|
use crate::{AssistContext, AssistId, Assists};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti
|
||||||
}
|
}
|
||||||
let node = ctx.covering_element();
|
let node = ctx.covering_element();
|
||||||
if node.kind() == COMMENT {
|
if node.kind() == COMMENT {
|
||||||
tested_by!(introduce_var_in_comment_is_not_applicable);
|
mark::hit!(introduce_var_in_comment_is_not_applicable);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let expr = node.ancestors().find_map(valid_target_expr)?;
|
let expr = node.ancestors().find_map(valid_target_expr)?;
|
||||||
|
@ -61,7 +61,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
if is_full_stmt {
|
if is_full_stmt {
|
||||||
tested_by!(test_introduce_var_expr_stmt);
|
mark::hit!(test_introduce_var_expr_stmt);
|
||||||
if full_stmt.unwrap().semicolon_token().is_none() {
|
if full_stmt.unwrap().semicolon_token().is_none() {
|
||||||
buf.push_str(";");
|
buf.push_str(";");
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
|
||||||
expr.syntax().ancestors().find_map(|node| {
|
expr.syntax().ancestors().find_map(|node| {
|
||||||
if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) {
|
if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) {
|
||||||
if expr.syntax() == &node {
|
if expr.syntax() == &node {
|
||||||
tested_by!(test_introduce_var_last_expr);
|
mark::hit!(test_introduce_var_last_expr);
|
||||||
return Some((node, false));
|
return Some((node, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
||||||
|
|
||||||
|
@ -158,13 +158,13 @@ fn foo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn introduce_var_in_comment_is_not_applicable() {
|
fn introduce_var_in_comment_is_not_applicable() {
|
||||||
covers!(introduce_var_in_comment_is_not_applicable);
|
mark::check!(introduce_var_in_comment_is_not_applicable);
|
||||||
check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }");
|
check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_introduce_var_expr_stmt() {
|
fn test_introduce_var_expr_stmt() {
|
||||||
covers!(test_introduce_var_expr_stmt);
|
mark::check!(test_introduce_var_expr_stmt);
|
||||||
check_assist(
|
check_assist(
|
||||||
introduce_variable,
|
introduce_variable,
|
||||||
"
|
"
|
||||||
|
@ -209,7 +209,7 @@ fn foo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_introduce_var_last_expr() {
|
fn test_introduce_var_last_expr() {
|
||||||
covers!(test_introduce_var_last_expr);
|
mark::check!(test_introduce_var_last_expr);
|
||||||
check_assist(
|
check_assist(
|
||||||
introduce_variable,
|
introduce_variable,
|
||||||
"
|
"
|
||||||
|
|
|
@ -12,7 +12,6 @@ macro_rules! eprintln {
|
||||||
|
|
||||||
mod assist_config;
|
mod assist_config;
|
||||||
mod assist_context;
|
mod assist_context;
|
||||||
mod marks;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
//! See test_utils/src/marks.rs
|
|
||||||
|
|
||||||
test_utils::marks![
|
|
||||||
option_order
|
|
||||||
introduce_var_in_comment_is_not_applicable
|
|
||||||
test_introduce_var_expr_stmt
|
|
||||||
test_introduce_var_last_expr
|
|
||||||
not_applicable_outside_of_bind_pat
|
|
||||||
test_not_inline_mut_variable
|
|
||||||
test_not_applicable_if_variable_unused
|
|
||||||
change_visibility_field_false_positive
|
|
||||||
test_add_from_impl_already_exists
|
|
||||||
add_turbo_fish_one_fish_is_enough
|
|
||||||
add_turbo_fish_non_generic
|
|
||||||
];
|
|
|
@ -15,7 +15,7 @@ use ra_syntax::{
|
||||||
},
|
},
|
||||||
AstNode, AstPtr,
|
AstNode, AstPtr,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
adt::StructKind,
|
adt::StructKind,
|
||||||
|
@ -226,7 +226,7 @@ impl ExprCollector<'_> {
|
||||||
None => self.collect_expr_opt(condition.expr()),
|
None => self.collect_expr_opt(condition.expr()),
|
||||||
// if let -- desugar to match
|
// if let -- desugar to match
|
||||||
Some(pat) => {
|
Some(pat) => {
|
||||||
tested_by!(infer_resolve_while_let);
|
mark::hit!(infer_resolve_while_let);
|
||||||
let pat = self.collect_pat(pat);
|
let pat = self.collect_pat(pat);
|
||||||
let match_expr = self.collect_expr_opt(condition.expr());
|
let match_expr = self.collect_expr_opt(condition.expr());
|
||||||
let placeholder_pat = self.missing_pat();
|
let placeholder_pat = self.missing_pat();
|
||||||
|
|
|
@ -174,7 +174,7 @@ mod tests {
|
||||||
use hir_expand::{name::AsName, InFile};
|
use hir_expand::{name::AsName, InFile};
|
||||||
use ra_db::{fixture::WithFixture, FileId, SourceDatabase};
|
use ra_db::{fixture::WithFixture, FileId, SourceDatabase};
|
||||||
use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
|
use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
|
||||||
use test_utils::{assert_eq_text, covers, extract_offset};
|
use test_utils::{assert_eq_text, extract_offset, mark};
|
||||||
|
|
||||||
use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId};
|
use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId};
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_let_desugaring() {
|
fn while_let_desugaring() {
|
||||||
covers!(infer_resolve_while_let);
|
mark::check!(infer_resolve_while_let);
|
||||||
do_check_local_name(
|
do_check_local_name(
|
||||||
r#"
|
r#"
|
||||||
fn test() {
|
fn test() {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use hir_expand::name::{known, AsName, Name};
|
use hir_expand::name::{known, AsName, Name};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
|
@ -164,17 +164,19 @@ fn find_path_inner(
|
||||||
|
|
||||||
fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath {
|
fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath {
|
||||||
if old_path.starts_with_std() && new_path.can_start_with_std() {
|
if old_path.starts_with_std() && new_path.can_start_with_std() {
|
||||||
tested_by!(prefer_std_paths);
|
|
||||||
if prefer_no_std {
|
if prefer_no_std {
|
||||||
|
mark::hit!(prefer_no_std_paths);
|
||||||
new_path
|
new_path
|
||||||
} else {
|
} else {
|
||||||
|
mark::hit!(prefer_std_paths);
|
||||||
old_path
|
old_path
|
||||||
}
|
}
|
||||||
} else if new_path.starts_with_std() && old_path.can_start_with_std() {
|
} else if new_path.starts_with_std() && old_path.can_start_with_std() {
|
||||||
tested_by!(prefer_std_paths);
|
|
||||||
if prefer_no_std {
|
if prefer_no_std {
|
||||||
|
mark::hit!(prefer_no_std_paths);
|
||||||
old_path
|
old_path
|
||||||
} else {
|
} else {
|
||||||
|
mark::hit!(prefer_std_paths);
|
||||||
new_path
|
new_path
|
||||||
}
|
}
|
||||||
} else if new_path.len() < old_path.len() {
|
} else if new_path.len() < old_path.len() {
|
||||||
|
@ -251,12 +253,14 @@ pub(crate) fn importable_locations_of_query(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
use crate::test_db::TestDB;
|
|
||||||
use hir_expand::hygiene::Hygiene;
|
use hir_expand::hygiene::Hygiene;
|
||||||
use ra_db::fixture::WithFixture;
|
use ra_db::fixture::WithFixture;
|
||||||
use ra_syntax::ast::AstNode;
|
use ra_syntax::ast::AstNode;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
|
use crate::test_db::TestDB;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
/// `code` needs to contain a cursor marker; checks that `find_path` for the
|
/// `code` needs to contain a cursor marker; checks that `find_path` for the
|
||||||
/// item the `path` refers to returns that same path when called from the
|
/// item the `path` refers to returns that same path when called from the
|
||||||
|
@ -511,7 +515,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefer_std_paths_over_alloc() {
|
fn prefer_std_paths_over_alloc() {
|
||||||
covers!(prefer_std_paths);
|
mark::check!(prefer_std_paths);
|
||||||
let code = r#"
|
let code = r#"
|
||||||
//- /main.rs crate:main deps:alloc,std
|
//- /main.rs crate:main deps:alloc,std
|
||||||
<|>
|
<|>
|
||||||
|
@ -529,33 +533,9 @@ mod tests {
|
||||||
check_found_path(code, "std::sync::Arc");
|
check_found_path(code, "std::sync::Arc");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn prefer_alloc_paths_over_std() {
|
|
||||||
covers!(prefer_std_paths);
|
|
||||||
let code = r#"
|
|
||||||
//- /main.rs crate:main deps:alloc,std
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /std.rs crate:std deps:alloc
|
|
||||||
|
|
||||||
pub mod sync {
|
|
||||||
pub use alloc::sync::Arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- /zzz.rs crate:alloc
|
|
||||||
|
|
||||||
pub mod sync {
|
|
||||||
pub struct Arc;
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
check_found_path(code, "alloc::sync::Arc");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefer_core_paths_over_std() {
|
fn prefer_core_paths_over_std() {
|
||||||
covers!(prefer_std_paths);
|
mark::check!(prefer_no_std_paths);
|
||||||
let code = r#"
|
let code = r#"
|
||||||
//- /main.rs crate:main deps:core,std
|
//- /main.rs crate:main deps:core,std
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -577,6 +557,29 @@ mod tests {
|
||||||
check_found_path(code, "core::fmt::Error");
|
check_found_path(code, "core::fmt::Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prefer_alloc_paths_over_std() {
|
||||||
|
let code = r#"
|
||||||
|
//- /main.rs crate:main deps:alloc,std
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
<|>
|
||||||
|
|
||||||
|
//- /std.rs crate:std deps:alloc
|
||||||
|
|
||||||
|
pub mod sync {
|
||||||
|
pub use alloc::sync::Arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /zzz.rs crate:alloc
|
||||||
|
|
||||||
|
pub mod sync {
|
||||||
|
pub struct Arc;
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
check_found_path(code, "alloc::sync::Arc");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefer_shorter_paths_if_not_alloc() {
|
fn prefer_shorter_paths_if_not_alloc() {
|
||||||
let code = r#"
|
let code = r#"
|
||||||
|
|
|
@ -46,8 +46,6 @@ pub mod find_path;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db;
|
mod test_db;
|
||||||
#[cfg(test)]
|
|
||||||
mod marks;
|
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
//! See test_utils/src/marks.rs
|
|
||||||
|
|
||||||
test_utils::marks!(
|
|
||||||
bogus_paths
|
|
||||||
name_res_works_for_broken_modules
|
|
||||||
can_import_enum_variant
|
|
||||||
glob_enum
|
|
||||||
glob_enum_group
|
|
||||||
glob_across_crates
|
|
||||||
std_prelude
|
|
||||||
macro_rules_from_other_crates_are_visible_with_macro_use
|
|
||||||
prelude_is_macro_use
|
|
||||||
macro_dollar_crate_self
|
|
||||||
macro_dollar_crate_other
|
|
||||||
infer_resolve_while_let
|
|
||||||
prefer_std_paths
|
|
||||||
);
|
|
|
@ -14,7 +14,7 @@ use ra_cfg::CfgOptions;
|
||||||
use ra_db::{CrateId, FileId, ProcMacroId};
|
use ra_db::{CrateId, FileId, ProcMacroId};
|
||||||
use ra_syntax::ast;
|
use ra_syntax::ast;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::Attrs,
|
attr::Attrs,
|
||||||
|
@ -302,7 +302,7 @@ impl DefCollector<'_> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ModuleDefId::ModuleId(m)) = res.take_types() {
|
if let Some(ModuleDefId::ModuleId(m)) = res.take_types() {
|
||||||
tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
||||||
self.import_all_macros_exported(current_module_id, m.krate);
|
self.import_all_macros_exported(current_module_id, m.krate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,10 +412,10 @@ impl DefCollector<'_> {
|
||||||
match def.take_types() {
|
match def.take_types() {
|
||||||
Some(ModuleDefId::ModuleId(m)) => {
|
Some(ModuleDefId::ModuleId(m)) => {
|
||||||
if import.is_prelude {
|
if import.is_prelude {
|
||||||
tested_by!(std_prelude);
|
mark::hit!(std_prelude);
|
||||||
self.def_map.prelude = Some(m);
|
self.def_map.prelude = Some(m);
|
||||||
} else if m.krate != self.def_map.krate {
|
} else if m.krate != self.def_map.krate {
|
||||||
tested_by!(glob_across_crates);
|
mark::hit!(glob_across_crates);
|
||||||
// glob import from other crate => we can just import everything once
|
// glob import from other crate => we can just import everything once
|
||||||
let item_map = self.db.crate_def_map(m.krate);
|
let item_map = self.db.crate_def_map(m.krate);
|
||||||
let scope = &item_map[m.local_id].scope;
|
let scope = &item_map[m.local_id].scope;
|
||||||
|
@ -461,7 +461,7 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => {
|
Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => {
|
||||||
tested_by!(glob_enum);
|
mark::hit!(glob_enum);
|
||||||
// glob import from enum => just import all the variants
|
// glob import from enum => just import all the variants
|
||||||
|
|
||||||
// XXX: urgh, so this works by accident! Here, we look at
|
// XXX: urgh, so this works by accident! Here, we look at
|
||||||
|
@ -510,7 +510,7 @@ impl DefCollector<'_> {
|
||||||
|
|
||||||
self.update(module_id, &[(name, def)], vis);
|
self.update(module_id, &[(name, def)], vis);
|
||||||
}
|
}
|
||||||
None => tested_by!(bogus_paths),
|
None => mark::hit!(bogus_paths),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -683,7 +683,7 @@ impl ModCollector<'_, '_> {
|
||||||
// Prelude module is always considered to be `#[macro_use]`.
|
// Prelude module is always considered to be `#[macro_use]`.
|
||||||
if let Some(prelude_module) = self.def_collector.def_map.prelude {
|
if let Some(prelude_module) = self.def_collector.def_map.prelude {
|
||||||
if prelude_module.krate != self.def_collector.def_map.krate {
|
if prelude_module.krate != self.def_collector.def_map.krate {
|
||||||
tested_by!(prelude_is_macro_use);
|
mark::hit!(prelude_is_macro_use);
|
||||||
self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate);
|
self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use std::iter::successors;
|
||||||
|
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use ra_db::Edition;
|
use ra_db::Edition;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
|
@ -108,7 +108,7 @@ impl CrateDefMap {
|
||||||
let mut curr_per_ns: PerNs = match path.kind {
|
let mut curr_per_ns: PerNs = match path.kind {
|
||||||
PathKind::DollarCrate(krate) => {
|
PathKind::DollarCrate(krate) => {
|
||||||
if krate == self.krate {
|
if krate == self.krate {
|
||||||
tested_by!(macro_dollar_crate_self);
|
mark::hit!(macro_dollar_crate_self);
|
||||||
PerNs::types(
|
PerNs::types(
|
||||||
ModuleId { krate: self.krate, local_id: self.root }.into(),
|
ModuleId { krate: self.krate, local_id: self.root }.into(),
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
|
@ -116,7 +116,7 @@ impl CrateDefMap {
|
||||||
} else {
|
} else {
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
let module = ModuleId { krate, local_id: def_map.root };
|
let module = ModuleId { krate, local_id: def_map.root };
|
||||||
tested_by!(macro_dollar_crate_other);
|
mark::hit!(macro_dollar_crate_other);
|
||||||
PerNs::types(module.into(), Visibility::Public)
|
PerNs::types(module.into(), Visibility::Public)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ impl CrateDefMap {
|
||||||
}
|
}
|
||||||
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
ModuleDefId::AdtId(AdtId::EnumId(e)) => {
|
||||||
// enum variant
|
// enum variant
|
||||||
tested_by!(can_import_enum_variant);
|
mark::hit!(can_import_enum_variant);
|
||||||
let enum_data = db.enum_data(e);
|
let enum_data = db.enum_data(e);
|
||||||
match enum_data.variant(&segment) {
|
match enum_data.variant(&segment) {
|
||||||
Some(local_id) => {
|
Some(local_id) => {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use ra_syntax::{
|
||||||
ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
|
ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
|
||||||
AstNode,
|
AstNode,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::Attrs,
|
attr::Attrs,
|
||||||
|
@ -346,7 +346,7 @@ impl RawItemsCollector {
|
||||||
self.push_item(current_module, attrs, RawItemKind::Module(item));
|
self.push_item(current_module, attrs, RawItemKind::Module(item));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tested_by!(name_res_works_for_broken_modules);
|
mark::hit!(name_res_works_for_broken_modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) {
|
fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
use ra_db::{fixture::WithFixture, SourceDatabase};
|
use ra_db::{fixture::WithFixture, SourceDatabase};
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
|
use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ fn crate_def_map_fn_mod_same_name() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bogus_paths() {
|
fn bogus_paths() {
|
||||||
covers!(bogus_paths);
|
mark::check!(bogus_paths);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -247,7 +247,7 @@ fn re_exports() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn std_prelude() {
|
fn std_prelude() {
|
||||||
covers!(std_prelude);
|
mark::check!(std_prelude);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /main.rs crate:main deps:test_crate
|
//- /main.rs crate:main deps:test_crate
|
||||||
|
@ -271,7 +271,7 @@ fn std_prelude() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_import_enum_variant() {
|
fn can_import_enum_variant() {
|
||||||
covers!(can_import_enum_variant);
|
mark::check!(can_import_enum_variant);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -152,7 +152,7 @@ fn glob_privacy_2() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_across_crates() {
|
fn glob_across_crates() {
|
||||||
covers!(glob_across_crates);
|
mark::check!(glob_across_crates);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r"
|
r"
|
||||||
//- /main.rs crate:main deps:test_crate
|
//- /main.rs crate:main deps:test_crate
|
||||||
|
@ -171,7 +171,6 @@ fn glob_across_crates() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_privacy_across_crates() {
|
fn glob_privacy_across_crates() {
|
||||||
covers!(glob_across_crates);
|
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r"
|
r"
|
||||||
//- /main.rs crate:main deps:test_crate
|
//- /main.rs crate:main deps:test_crate
|
||||||
|
@ -191,7 +190,7 @@ fn glob_privacy_across_crates() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_enum() {
|
fn glob_enum() {
|
||||||
covers!(glob_enum);
|
mark::check!(glob_enum);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -212,7 +211,7 @@ fn glob_enum() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_enum_group() {
|
fn glob_enum_group() {
|
||||||
covers!(glob_enum_group);
|
mark::check!(glob_enum_group);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r"
|
r"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -212,7 +212,7 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
||||||
covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /main.rs crate:main deps:foo
|
//- /main.rs crate:main deps:foo
|
||||||
|
@ -262,7 +262,7 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prelude_is_macro_use() {
|
fn prelude_is_macro_use() {
|
||||||
covers!(prelude_is_macro_use);
|
mark::check!(prelude_is_macro_use);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /main.rs crate:main deps:foo
|
//- /main.rs crate:main deps:foo
|
||||||
|
@ -544,8 +544,7 @@ fn path_qualified_macros() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_dollar_crate_is_correct_in_item() {
|
fn macro_dollar_crate_is_correct_in_item() {
|
||||||
covers!(macro_dollar_crate_self);
|
mark::check!(macro_dollar_crate_self);
|
||||||
covers!(macro_dollar_crate_other);
|
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /main.rs crate:main deps:foo
|
//- /main.rs crate:main deps:foo
|
||||||
|
@ -603,7 +602,7 @@ fn macro_dollar_crate_is_correct_in_item() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_dollar_crate_is_correct_in_indirect_deps() {
|
fn macro_dollar_crate_is_correct_in_indirect_deps() {
|
||||||
covers!(macro_dollar_crate_other);
|
mark::check!(macro_dollar_crate_other);
|
||||||
// From std
|
// From std
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r#"
|
r#"
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn name_res_works_for_broken_modules() {
|
fn name_res_works_for_broken_modules() {
|
||||||
covers!(name_res_works_for_broken_modules);
|
mark::check!(name_res_works_for_broken_modules);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r"
|
r"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::iter;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{hygiene::Hygiene, name::AsName};
|
use hir_expand::{hygiene::Hygiene, name::AsName};
|
||||||
use ra_syntax::ast::{self, NameOwner};
|
use ra_syntax::ast::{self, NameOwner};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::path::{ImportAlias, ModPath, PathKind};
|
use crate::path::{ImportAlias, ModPath, PathKind};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ pub(crate) fn lower_use_tree(
|
||||||
// FIXME: report errors somewhere
|
// FIXME: report errors somewhere
|
||||||
// We get here if we do
|
// We get here if we do
|
||||||
} else if is_glob {
|
} else if is_glob {
|
||||||
tested_by!(glob_enum_group);
|
mark::hit!(glob_enum_group);
|
||||||
if let Some(prefix) = prefix {
|
if let Some(prefix) = prefix {
|
||||||
cb(prefix, &tree, is_glob, None)
|
cb(prefix, &tree, is_glob, None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! See: https://doc.rust-lang.org/nomicon/coercions.html
|
//! See: https://doc.rust-lang.org/nomicon/coercions.html
|
||||||
|
|
||||||
use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
|
use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor};
|
use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor};
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
ty1.clone()
|
ty1.clone()
|
||||||
} else {
|
} else {
|
||||||
if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) {
|
if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) {
|
||||||
tested_by!(coerce_fn_reification);
|
mark::hit!(coerce_fn_reification);
|
||||||
// Special case: two function types. Try to coerce both to
|
// Special case: two function types. Try to coerce both to
|
||||||
// pointers to have a chance at getting a match. See
|
// pointers to have a chance at getting a match. See
|
||||||
// https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
|
// https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
let ptr_ty2 = Ty::fn_ptr(sig2);
|
let ptr_ty2 = Ty::fn_ptr(sig2);
|
||||||
self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
|
self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
|
||||||
} else {
|
} else {
|
||||||
tested_by!(coerce_merge_fail_fallback);
|
mark::hit!(coerce_merge_fail_fallback);
|
||||||
// For incompatible types, we use the latter one as result
|
// For incompatible types, we use the latter one as result
|
||||||
// to be better recovery for `if` without `else`.
|
// to be better recovery for `if` without `else`.
|
||||||
ty2.clone()
|
ty2.clone()
|
||||||
|
|
|
@ -10,7 +10,7 @@ use hir_def::{
|
||||||
FieldId,
|
FieldId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use super::{BindingMode, Expectation, InferenceContext};
|
use super::{BindingMode, Expectation, InferenceContext};
|
||||||
use crate::{utils::variant_data, Substs, Ty, TypeCtor};
|
use crate::{utils::variant_data, Substs, Ty, TypeCtor};
|
||||||
|
@ -111,7 +111,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Pat::Ref { .. } = &body[pat] {
|
} else if let Pat::Ref { .. } = &body[pat] {
|
||||||
tested_by!(match_ergonomics_ref);
|
mark::hit!(match_ergonomics_ref);
|
||||||
// When you encounter a `&pat` pattern, reset to Move.
|
// When you encounter a `&pat` pattern, reset to Move.
|
||||||
// This is so that `w` is by value: `let (_, &w) = &(1, &2);`
|
// This is so that `w` is by value: `let (_, &w) = &(1, &2);`
|
||||||
default_bm = BindingMode::Move;
|
default_bm = BindingMode::Move;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
|
use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
|
||||||
|
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use super::{InferenceContext, Obligation};
|
use super::{InferenceContext, Obligation};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -313,7 +313,7 @@ impl InferenceTable {
|
||||||
// more than once
|
// more than once
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
tested_by!(type_var_resolves_to_int_var);
|
mark::hit!(type_var_resolves_to_int_var);
|
||||||
}
|
}
|
||||||
match &*ty {
|
match &*ty {
|
||||||
Ty::Infer(tv) => {
|
Ty::Infer(tv) => {
|
||||||
|
@ -342,7 +342,7 @@ impl InferenceTable {
|
||||||
Ty::Infer(tv) => {
|
Ty::Infer(tv) => {
|
||||||
let inner = tv.to_inner();
|
let inner = tv.to_inner();
|
||||||
if tv_stack.contains(&inner) {
|
if tv_stack.contains(&inner) {
|
||||||
tested_by!(type_var_cycles_resolve_as_possible);
|
mark::hit!(type_var_cycles_resolve_as_possible);
|
||||||
// recursive type
|
// recursive type
|
||||||
return tv.fallback_value();
|
return tv.fallback_value();
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ impl InferenceTable {
|
||||||
Ty::Infer(tv) => {
|
Ty::Infer(tv) => {
|
||||||
let inner = tv.to_inner();
|
let inner = tv.to_inner();
|
||||||
if tv_stack.contains(&inner) {
|
if tv_stack.contains(&inner) {
|
||||||
tested_by!(type_var_cycles_resolve_completely);
|
mark::hit!(type_var_cycles_resolve_completely);
|
||||||
// recursive type
|
// recursive type
|
||||||
return tv.fallback_value();
|
return tv.fallback_value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ pub mod expr;
|
||||||
mod tests;
|
mod tests;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db;
|
mod test_db;
|
||||||
mod marks;
|
|
||||||
mod _match;
|
mod _match;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
|
@ -812,7 +812,7 @@ impl TraitEnvironment {
|
||||||
// add `Self: Trait<T1, T2, ...>` to the environment in trait
|
// add `Self: Trait<T1, T2, ...>` to the environment in trait
|
||||||
// function default implementations (and hypothetical code
|
// function default implementations (and hypothetical code
|
||||||
// inside consts or type aliases)
|
// inside consts or type aliases)
|
||||||
test_utils::tested_by!(trait_self_implements_self);
|
test_utils::mark::hit!(trait_self_implements_self);
|
||||||
let substs = Substs::type_params(db, trait_id);
|
let substs = Substs::type_params(db, trait_id);
|
||||||
let trait_ref = TraitRef { trait_: trait_id, substs };
|
let trait_ref = TraitRef { trait_: trait_id, substs };
|
||||||
let pred = GenericPredicate::Implemented(trait_ref);
|
let pred = GenericPredicate::Implemented(trait_ref);
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
//! See test_utils/src/marks.rs
|
|
||||||
|
|
||||||
test_utils::marks!(
|
|
||||||
type_var_cycles_resolve_completely
|
|
||||||
type_var_cycles_resolve_as_possible
|
|
||||||
type_var_resolves_to_int_var
|
|
||||||
impl_self_type_match_without_receiver
|
|
||||||
match_ergonomics_ref
|
|
||||||
coerce_merge_fail_fallback
|
|
||||||
coerce_fn_reification
|
|
||||||
trait_self_implements_self
|
|
||||||
);
|
|
|
@ -469,7 +469,7 @@ fn iterate_inherent_methods<T>(
|
||||||
// already happens in `is_valid_candidate` above; if not, we
|
// already happens in `is_valid_candidate` above; if not, we
|
||||||
// check it here
|
// check it here
|
||||||
if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() {
|
if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() {
|
||||||
test_utils::tested_by!(impl_self_type_match_without_receiver);
|
test_utils::mark::hit!(impl_self_type_match_without_receiver);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(result) = callback(&self_ty.value, item) {
|
if let Some(result) = callback(&self_ty.value, item) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::infer_with_mismatches;
|
use super::infer_with_mismatches;
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
// Infer with some common definitions and impls.
|
// Infer with some common definitions and impls.
|
||||||
fn infer(source: &str) -> String {
|
fn infer(source: &str) -> String {
|
||||||
|
@ -339,7 +339,7 @@ fn test(i: i32) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coerce_merge_one_by_one1() {
|
fn coerce_merge_one_by_one1() {
|
||||||
covers!(coerce_merge_fail_fallback);
|
mark::check!(coerce_merge_fail_fallback);
|
||||||
|
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
|
@ -547,7 +547,7 @@ fn test() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coerce_fn_items_in_match_arms() {
|
fn coerce_fn_items_in_match_arms() {
|
||||||
covers!(coerce_fn_reification);
|
mark::check!(coerce_fn_reification);
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer_with_mismatches(r#"
|
infer_with_mismatches(r#"
|
||||||
fn foo1(x: u32) -> isize { 1 }
|
fn foo1(x: u32) -> isize { 1 }
|
||||||
|
|
|
@ -984,7 +984,7 @@ fn test() { S2.into()<|>; }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn method_resolution_overloaded_method() {
|
fn method_resolution_overloaded_method() {
|
||||||
test_utils::covers!(impl_self_type_match_without_receiver);
|
test_utils::mark::check!(impl_self_type_match_without_receiver);
|
||||||
let t = type_at(
|
let t = type_at(
|
||||||
r#"
|
r#"
|
||||||
//- main.rs
|
//- main.rs
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use super::{infer, infer_with_mismatches};
|
use super::{infer, infer_with_mismatches};
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ fn test() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_pattern_match_ergonomics_ref() {
|
fn infer_pattern_match_ergonomics_ref() {
|
||||||
covers!(match_ergonomics_ref);
|
mark::check!(match_ergonomics_ref);
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
fn test() {
|
fn test() {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
use test_utils::covers;
|
use ra_db::fixture::WithFixture;
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
|
use crate::test_db::TestDB;
|
||||||
|
|
||||||
use super::infer;
|
use super::infer;
|
||||||
use crate::test_db::TestDB;
|
|
||||||
use ra_db::fixture::WithFixture;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bug_484() {
|
fn bug_484() {
|
||||||
|
@ -89,8 +90,8 @@ fn quux() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recursive_vars() {
|
fn recursive_vars() {
|
||||||
covers!(type_var_cycles_resolve_completely);
|
mark::check!(type_var_cycles_resolve_completely);
|
||||||
covers!(type_var_cycles_resolve_as_possible);
|
mark::check!(type_var_cycles_resolve_as_possible);
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
fn test() {
|
fn test() {
|
||||||
|
@ -112,8 +113,6 @@ fn test() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recursive_vars_2() {
|
fn recursive_vars_2() {
|
||||||
covers!(type_var_cycles_resolve_completely);
|
|
||||||
covers!(type_var_cycles_resolve_as_possible);
|
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
fn test() {
|
fn test() {
|
||||||
|
@ -170,7 +169,7 @@ fn write() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_std_crash_2() {
|
fn infer_std_crash_2() {
|
||||||
covers!(type_var_resolves_to_int_var);
|
mark::check!(type_var_resolves_to_int_var);
|
||||||
// caused "equating two type variables, ...", taken from std
|
// caused "equating two type variables, ...", taken from std
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
|
|
||||||
use ra_db::fixture::WithFixture;
|
use ra_db::fixture::WithFixture;
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
|
use crate::test_db::TestDB;
|
||||||
|
|
||||||
use super::{infer, infer_with_mismatches, type_at, type_at_pos};
|
use super::{infer, infer_with_mismatches, type_at, type_at_pos};
|
||||||
use crate::test_db::TestDB;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_await() {
|
fn infer_await() {
|
||||||
|
@ -301,7 +302,7 @@ fn test() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_default_method_self_bound_implements_trait() {
|
fn trait_default_method_self_bound_implements_trait() {
|
||||||
test_utils::covers!(trait_self_implements_self);
|
mark::check!(trait_self_implements_self);
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
trait Trait {
|
trait Trait {
|
||||||
|
@ -324,7 +325,6 @@ trait Trait {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_default_method_self_bound_implements_super_trait() {
|
fn trait_default_method_self_bound_implements_super_trait() {
|
||||||
test_utils::covers!(trait_self_implements_self);
|
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
trait SuperTrait {
|
trait SuperTrait {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
||||||
ast::{self, ArgListOwner},
|
ast::{self, ArgListOwner},
|
||||||
match_ast, AstNode, SyntaxNode, SyntaxToken,
|
match_ast, AstNode, SyntaxNode, SyntaxToken,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{CallInfo, FilePosition, FunctionSignature};
|
use crate::{CallInfo, FilePosition, FunctionSignature};
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op
|
||||||
|
|
||||||
let arg_list_range = arg_list.syntax().text_range();
|
let arg_list_range = arg_list.syntax().text_range();
|
||||||
if !arg_list_range.contains_inclusive(token.text_range().start()) {
|
if !arg_list_range.contains_inclusive(token.text_range().start()) {
|
||||||
tested_by!(call_info_bad_offset);
|
mark::hit!(call_info_bad_offset);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ impl CallInfo {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::mock_analysis::single_file_with_position;
|
use crate::mock_analysis::single_file_with_position;
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ By default this method stops actor's `Context`."#
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_info_bad_offset() {
|
fn call_info_bad_offset() {
|
||||||
covers!(call_info_bad_offset);
|
mark::check!(call_info_bad_offset);
|
||||||
let (analysis, position) = single_file_with_position(
|
let (analysis, position) = single_file_with_position(
|
||||||
r#"fn foo(x: u32, y: u32) -> u32 {x + y}
|
r#"fn foo(x: u32, y: u32) -> u32 {x + y}
|
||||||
fn bar() { foo <|> (3, ); }"#,
|
fn bar() { foo <|> (3, ); }"#,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use hir::{Adt, HasVisibility, PathResolution, ScopeDef};
|
use hir::{Adt, HasVisibility, PathResolution, ScopeDef};
|
||||||
use ra_syntax::AstNode;
|
use ra_syntax::AstNode;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::completion::{CompletionContext, Completions};
|
use crate::completion::{CompletionContext, Completions};
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
||||||
if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
|
if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
|
||||||
if name_ref.syntax().text() == name.to_string().as_str() {
|
if name_ref.syntax().text() == name.to_string().as_str() {
|
||||||
// for `use self::foo<|>`, don't suggest `foo` as a completion
|
// for `use self::foo<|>`, don't suggest `foo` as a completion
|
||||||
tested_by!(dont_complete_current_use);
|
mark::hit!(dont_complete_current_use);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
|
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
|
||||||
use insta::assert_debug_snapshot;
|
use insta::assert_debug_snapshot;
|
||||||
|
@ -158,7 +158,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dont_complete_current_use() {
|
fn dont_complete_current_use() {
|
||||||
covers!(dont_complete_current_use);
|
mark::check!(dont_complete_current_use);
|
||||||
let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference);
|
let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference);
|
||||||
assert!(completions.is_empty());
|
assert!(completions.is_empty());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Completion of names from the current scope, e.g. locals and imported items.
|
//! Completion of names from the current scope, e.g. locals and imported items.
|
||||||
|
|
||||||
use hir::ScopeDef;
|
use hir::ScopeDef;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::completion::{CompletionContext, Completions};
|
use crate::completion::{CompletionContext, Completions};
|
||||||
use hir::{Adt, ModuleDef, Type};
|
use hir::{Adt, ModuleDef, Type};
|
||||||
|
@ -30,7 +30,7 @@ pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
if ctx.use_item_syntax.is_some() {
|
if ctx.use_item_syntax.is_some() {
|
||||||
if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
|
if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
|
||||||
if name_ref.syntax().text() == name.to_string().as_str() {
|
if name_ref.syntax().text() == name.to_string().as_str() {
|
||||||
tested_by!(self_fulfilling_completion);
|
mark::hit!(self_fulfilling_completion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use insta::assert_debug_snapshot;
|
use insta::assert_debug_snapshot;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
|
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn self_fulfilling_completion() {
|
fn self_fulfilling_completion() {
|
||||||
covers!(self_fulfilling_completion);
|
mark::check!(self_fulfilling_completion);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r#"
|
r#"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type};
|
use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type};
|
||||||
use ra_syntax::ast::NameOwner;
|
use ra_syntax::ast::NameOwner;
|
||||||
use stdx::SepBy;
|
use stdx::SepBy;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
completion::{
|
completion::{
|
||||||
|
@ -121,7 +121,7 @@ impl Completions {
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if has_non_default_type_params {
|
if has_non_default_type_params {
|
||||||
tested_by!(inserts_angle_brackets_for_generics);
|
mark::hit!(inserts_angle_brackets_for_generics);
|
||||||
completion_item = completion_item
|
completion_item = completion_item
|
||||||
.lookup_by(local_name.clone())
|
.lookup_by(local_name.clone())
|
||||||
.label(format!("{}<…>", local_name))
|
.label(format!("{}<…>", local_name))
|
||||||
|
@ -176,7 +176,7 @@ impl Completions {
|
||||||
}
|
}
|
||||||
None if needs_bang => builder.insert_text(format!("{}!", name)),
|
None if needs_bang => builder.insert_text(format!("{}!", name)),
|
||||||
_ => {
|
_ => {
|
||||||
tested_by!(dont_insert_macro_call_parens_unncessary);
|
mark::hit!(dont_insert_macro_call_parens_unncessary);
|
||||||
builder.insert_text(name)
|
builder.insert_text(name)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -330,14 +330,14 @@ pub(crate) fn compute_score(
|
||||||
// FIXME: this should not fall back to string equality.
|
// FIXME: this should not fall back to string equality.
|
||||||
let ty = &ty.display(ctx.db).to_string();
|
let ty = &ty.display(ctx.db).to_string();
|
||||||
let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
|
let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
|
||||||
tested_by!(test_struct_field_completion_in_record_lit);
|
mark::hit!(test_struct_field_completion_in_record_lit);
|
||||||
let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?;
|
let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?;
|
||||||
(
|
(
|
||||||
struct_field.name(ctx.db).to_string(),
|
struct_field.name(ctx.db).to_string(),
|
||||||
struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
|
struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
|
||||||
)
|
)
|
||||||
} else if let Some(active_parameter) = &ctx.active_parameter {
|
} else if let Some(active_parameter) = &ctx.active_parameter {
|
||||||
tested_by!(test_struct_field_completion_in_func_call);
|
mark::hit!(test_struct_field_completion_in_func_call);
|
||||||
(active_parameter.name.clone(), active_parameter.ty.clone())
|
(active_parameter.name.clone(), active_parameter.ty.clone())
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
|
@ -398,7 +398,7 @@ impl Builder {
|
||||||
None => return self,
|
None => return self,
|
||||||
};
|
};
|
||||||
// If not an import, add parenthesis automatically.
|
// If not an import, add parenthesis automatically.
|
||||||
tested_by!(inserts_parens_for_function_calls);
|
mark::hit!(inserts_parens_for_function_calls);
|
||||||
|
|
||||||
let (snippet, label) = if params.is_empty() {
|
let (snippet, label) = if params.is_empty() {
|
||||||
(format!("{}()$0", name), format!("{}()", name))
|
(format!("{}()$0", name), format!("{}()", name))
|
||||||
|
@ -457,7 +457,7 @@ fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static s
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use insta::assert_debug_snapshot;
|
use insta::assert_debug_snapshot;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::completion::{
|
use crate::completion::{
|
||||||
test_utils::{do_completion, do_completion_with_options},
|
test_utils::{do_completion, do_completion_with_options},
|
||||||
|
@ -607,7 +607,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inserts_parens_for_function_calls() {
|
fn inserts_parens_for_function_calls() {
|
||||||
covers!(inserts_parens_for_function_calls);
|
mark::check!(inserts_parens_for_function_calls);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
@ -992,7 +992,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inserts_angle_brackets_for_generics() {
|
fn inserts_angle_brackets_for_generics() {
|
||||||
covers!(inserts_angle_brackets_for_generics);
|
mark::check!(inserts_angle_brackets_for_generics);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
@ -1115,7 +1115,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dont_insert_macro_call_parens_unncessary() {
|
fn dont_insert_macro_call_parens_unncessary() {
|
||||||
covers!(dont_insert_macro_call_parens_unncessary);
|
mark::check!(dont_insert_macro_call_parens_unncessary);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
@ -1181,7 +1181,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_struct_field_completion_in_func_call() {
|
fn test_struct_field_completion_in_func_call() {
|
||||||
covers!(test_struct_field_completion_in_func_call);
|
mark::check!(test_struct_field_completion_in_func_call);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
@ -1271,7 +1271,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_struct_field_completion_in_record_lit() {
|
fn test_struct_field_completion_in_record_lit() {
|
||||||
covers!(test_struct_field_completion_in_record_lit);
|
mark::check!(test_struct_field_completion_in_record_lit);
|
||||||
assert_debug_snapshot!(
|
assert_debug_snapshot!(
|
||||||
do_reference_completion(
|
do_reference_completion(
|
||||||
r"
|
r"
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub(crate) fn reference_definition(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::{assert_eq_text, covers};
|
use test_utils::assert_eq_text;
|
||||||
|
|
||||||
use crate::mock_analysis::analysis_and_position;
|
use crate::mock_analysis::analysis_and_position;
|
||||||
|
|
||||||
|
@ -208,7 +208,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_macros() {
|
fn goto_def_for_macros() {
|
||||||
covers!(ra_ide_db::goto_def_for_macros);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -225,7 +224,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_macros_from_other_crates() {
|
fn goto_def_for_macros_from_other_crates() {
|
||||||
covers!(ra_ide_db::goto_def_for_macros);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -245,7 +243,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_use_alias() {
|
fn goto_def_for_use_alias() {
|
||||||
covers!(ra_ide_db::goto_def_for_use_alias);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -370,7 +367,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_methods() {
|
fn goto_def_for_methods() {
|
||||||
covers!(ra_ide_db::goto_def_for_methods);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -390,7 +386,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_fields() {
|
fn goto_def_for_fields() {
|
||||||
covers!(ra_ide_db::goto_def_for_fields);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
r"
|
r"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -409,7 +404,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_record_fields() {
|
fn goto_def_for_record_fields() {
|
||||||
covers!(ra_ide_db::goto_def_for_record_fields);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
r"
|
r"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -430,7 +424,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_record_pat_fields() {
|
fn goto_def_for_record_pat_fields() {
|
||||||
covers!(ra_ide_db::goto_def_for_record_field_pats);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
r"
|
r"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -873,7 +866,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_for_field_init_shorthand() {
|
fn goto_def_for_field_init_shorthand() {
|
||||||
covers!(ra_ide_db::goto_def_for_field_init_shorthand);
|
|
||||||
check_goto(
|
check_goto(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -42,8 +42,6 @@ mod inlay_hints;
|
||||||
mod expand_macro;
|
mod expand_macro;
|
||||||
mod ssr;
|
mod ssr;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod marks;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_utils;
|
mod test_utils;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
//! See test_utils/src/marks.rs
|
|
||||||
|
|
||||||
test_utils::marks!(
|
|
||||||
inserts_angle_brackets_for_generics
|
|
||||||
inserts_parens_for_function_calls
|
|
||||||
call_info_bad_offset
|
|
||||||
dont_complete_current_use
|
|
||||||
test_resolve_parent_module_on_module_decl
|
|
||||||
search_filters_by_range
|
|
||||||
dont_insert_macro_call_parens_unncessary
|
|
||||||
self_fulfilling_completion
|
|
||||||
test_struct_field_completion_in_func_call
|
|
||||||
test_struct_field_completion_in_record_lit
|
|
||||||
test_rename_struct_field_for_shorthand
|
|
||||||
test_rename_local_for_field_shorthand
|
|
||||||
);
|
|
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||||
algo::find_node_at_offset,
|
algo::find_node_at_offset,
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::NavigationTarget;
|
use crate::NavigationTarget;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
|
||||||
.item_list()
|
.item_list()
|
||||||
.map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset))
|
.map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset))
|
||||||
{
|
{
|
||||||
tested_by!(test_resolve_parent_module_on_module_decl);
|
mark::hit!(test_resolve_parent_module_on_module_decl);
|
||||||
module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
|
module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use ra_cfg::CfgOptions;
|
use ra_cfg::CfgOptions;
|
||||||
use ra_db::Env;
|
use ra_db::Env;
|
||||||
use test_utils::covers;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mock_analysis::{analysis_and_position, MockAnalysis},
|
mock_analysis::{analysis_and_position, MockAnalysis},
|
||||||
|
@ -81,7 +81,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_resolve_parent_module_on_module_decl() {
|
fn test_resolve_parent_module_on_module_decl() {
|
||||||
covers!(test_resolve_parent_module_on_module_decl);
|
mark::check!(test_resolve_parent_module_on_module_decl);
|
||||||
let (analysis, pos) = analysis_and_position(
|
let (analysis, pos) = analysis_and_position(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
|
|
@ -190,8 +190,6 @@ fn get_struct_def_name_for_struct_literal_search(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use test_utils::covers;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis},
|
mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis},
|
||||||
Declaration, Reference, ReferenceSearchResult, SearchScope,
|
Declaration, Reference, ReferenceSearchResult, SearchScope,
|
||||||
|
@ -301,7 +299,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn search_filters_by_range() {
|
fn search_filters_by_range() {
|
||||||
covers!(ra_ide_db::search_filters_by_range);
|
|
||||||
let code = r#"
|
let code = r#"
|
||||||
fn foo() {
|
fn foo() {
|
||||||
let spam<|> = 92;
|
let spam<|> = 92;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use test_utils::tested_by;
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind,
|
references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind,
|
||||||
|
@ -57,13 +57,13 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil
|
||||||
let file_id = reference.file_range.file_id;
|
let file_id = reference.file_range.file_id;
|
||||||
let range = match reference.kind {
|
let range = match reference.kind {
|
||||||
ReferenceKind::FieldShorthandForField => {
|
ReferenceKind::FieldShorthandForField => {
|
||||||
tested_by!(test_rename_struct_field_for_shorthand);
|
mark::hit!(test_rename_struct_field_for_shorthand);
|
||||||
replacement_text.push_str(new_name);
|
replacement_text.push_str(new_name);
|
||||||
replacement_text.push_str(": ");
|
replacement_text.push_str(": ");
|
||||||
TextRange::new(reference.file_range.range.start(), reference.file_range.range.start())
|
TextRange::new(reference.file_range.range.start(), reference.file_range.range.start())
|
||||||
}
|
}
|
||||||
ReferenceKind::FieldShorthandForLocal => {
|
ReferenceKind::FieldShorthandForLocal => {
|
||||||
tested_by!(test_rename_local_for_field_shorthand);
|
mark::hit!(test_rename_local_for_field_shorthand);
|
||||||
replacement_text.push_str(": ");
|
replacement_text.push_str(": ");
|
||||||
replacement_text.push_str(new_name);
|
replacement_text.push_str(new_name);
|
||||||
TextRange::new(reference.file_range.range.end(), reference.file_range.range.end())
|
TextRange::new(reference.file_range.range.end(), reference.file_range.range.end())
|
||||||
|
@ -260,7 +260,7 @@ fn rename_reference(
|
||||||
mod tests {
|
mod tests {
|
||||||
use insta::assert_debug_snapshot;
|
use insta::assert_debug_snapshot;
|
||||||
use ra_text_edit::TextEditBuilder;
|
use ra_text_edit::TextEditBuilder;
|
||||||
use test_utils::{assert_eq_text, covers};
|
use test_utils::{assert_eq_text, mark};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
|
mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
|
||||||
|
@ -492,7 +492,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rename_struct_field_for_shorthand() {
|
fn test_rename_struct_field_for_shorthand() {
|
||||||
covers!(test_rename_struct_field_for_shorthand);
|
mark::check!(test_rename_struct_field_for_shorthand);
|
||||||
test_rename(
|
test_rename(
|
||||||
r#"
|
r#"
|
||||||
struct Foo {
|
struct Foo {
|
||||||
|
@ -522,7 +522,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rename_local_for_field_shorthand() {
|
fn test_rename_local_for_field_shorthand() {
|
||||||
covers!(test_rename_local_for_field_shorthand);
|
mark::check!(test_rename_local_for_field_shorthand);
|
||||||
test_rename(
|
test_rename(
|
||||||
r#"
|
r#"
|
||||||
struct Foo {
|
struct Foo {
|
||||||
|
|
|
@ -14,7 +14,6 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
match_ast,
|
match_ast,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
|
||||||
|
|
||||||
use crate::RootDatabase;
|
use crate::RootDatabase;
|
||||||
|
|
||||||
|
@ -118,7 +117,6 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
|
||||||
match_ast! {
|
match_ast! {
|
||||||
match parent {
|
match parent {
|
||||||
ast::Alias(it) => {
|
ast::Alias(it) => {
|
||||||
tested_by!(goto_def_for_use_alias; force);
|
|
||||||
let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
|
let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
|
||||||
let path = use_tree.path()?;
|
let path = use_tree.path()?;
|
||||||
let path_segment = path.segment()?;
|
let path_segment = path.segment()?;
|
||||||
|
@ -203,6 +201,8 @@ impl NameRefClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: we don't have unit-tests for this rather important function.
|
||||||
|
// It is primarily exercised via goto definition tests in `ra_ide`.
|
||||||
pub fn classify_name_ref(
|
pub fn classify_name_ref(
|
||||||
sema: &Semantics<RootDatabase>,
|
sema: &Semantics<RootDatabase>,
|
||||||
name_ref: &ast::NameRef,
|
name_ref: &ast::NameRef,
|
||||||
|
@ -212,22 +212,18 @@ pub fn classify_name_ref(
|
||||||
let parent = name_ref.syntax().parent()?;
|
let parent = name_ref.syntax().parent()?;
|
||||||
|
|
||||||
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
||||||
tested_by!(goto_def_for_methods; force);
|
|
||||||
if let Some(func) = sema.resolve_method_call(&method_call) {
|
if let Some(func) = sema.resolve_method_call(&method_call) {
|
||||||
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
|
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
|
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
|
||||||
tested_by!(goto_def_for_fields; force);
|
|
||||||
if let Some(field) = sema.resolve_field(&field_expr) {
|
if let Some(field) = sema.resolve_field(&field_expr) {
|
||||||
return Some(NameRefClass::Definition(Definition::Field(field)));
|
return Some(NameRefClass::Definition(Definition::Field(field)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
|
if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
|
||||||
tested_by!(goto_def_for_record_fields; force);
|
|
||||||
tested_by!(goto_def_for_field_init_shorthand; force);
|
|
||||||
if let Some((field, local)) = sema.resolve_record_field(&record_field) {
|
if let Some((field, local)) = sema.resolve_record_field(&record_field) {
|
||||||
let field = Definition::Field(field);
|
let field = Definition::Field(field);
|
||||||
let res = match local {
|
let res = match local {
|
||||||
|
@ -239,7 +235,6 @@ pub fn classify_name_ref(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
|
if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
|
||||||
tested_by!(goto_def_for_record_field_pats; force);
|
|
||||||
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
|
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
|
||||||
let field = Definition::Field(field);
|
let field = Definition::Field(field);
|
||||||
return Some(NameRefClass::Definition(field));
|
return Some(NameRefClass::Definition(field));
|
||||||
|
@ -247,7 +242,6 @@ pub fn classify_name_ref(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
||||||
tested_by!(goto_def_for_macros; force);
|
|
||||||
if let Some(macro_def) = sema.resolve_macro_call(¯o_call) {
|
if let Some(macro_def) = sema.resolve_macro_call(¯o_call) {
|
||||||
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//!
|
//!
|
||||||
//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
|
//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
|
||||||
|
|
||||||
pub mod marks;
|
|
||||||
pub mod line_index;
|
pub mod line_index;
|
||||||
pub mod line_index_utils;
|
pub mod line_index_utils;
|
||||||
pub mod symbol_index;
|
pub mod symbol_index;
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
//! See test_utils/src/marks.rs
|
|
||||||
|
|
||||||
test_utils::marks![
|
|
||||||
goto_def_for_macros
|
|
||||||
goto_def_for_use_alias
|
|
||||||
goto_def_for_methods
|
|
||||||
goto_def_for_fields
|
|
||||||
goto_def_for_record_fields
|
|
||||||
goto_def_for_field_init_shorthand
|
|
||||||
goto_def_for_record_field_pats
|
|
||||||
search_filters_by_range
|
|
||||||
];
|
|
|
@ -12,7 +12,6 @@ use ra_db::{FileId, FileRange, SourceDatabaseExt};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize};
|
use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use test_utils::tested_by;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
defs::{classify_name_ref, Definition, NameRefClass},
|
defs::{classify_name_ref, Definition, NameRefClass},
|
||||||
|
@ -209,7 +208,6 @@ impl Definition {
|
||||||
for (idx, _) in text.match_indices(pat) {
|
for (idx, _) in text.match_indices(pat) {
|
||||||
let offset: TextSize = idx.try_into().unwrap();
|
let offset: TextSize = idx.try_into().unwrap();
|
||||||
if !search_range.contains_inclusive(offset) {
|
if !search_range.contains_inclusive(offset) {
|
||||||
tested_by!(search_filters_by_range; force);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! * marks (see the eponymous module).
|
//! * marks (see the eponymous module).
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod marks;
|
pub mod mark;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
|
|
|
@ -7,18 +7,18 @@
|
||||||
//! ```
|
//! ```
|
||||||
//! #[test]
|
//! #[test]
|
||||||
//! fn test_foo() {
|
//! fn test_foo() {
|
||||||
//! covers!(test_foo);
|
//! mark::check!(test_foo);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! and in the code under test you write
|
//! and in the code under test you write
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use test_utils::tested_by;
|
//! # use test_utils::mark;
|
||||||
//! # fn some_condition() -> bool { true }
|
//! # fn some_condition() -> bool { true }
|
||||||
//! fn foo() {
|
//! fn foo() {
|
||||||
//! if some_condition() {
|
//! if some_condition() {
|
||||||
//! tested_by!(test_foo);
|
//! mark::hit!(test_foo);
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -29,43 +29,31 @@
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! tested_by {
|
macro_rules! _hit {
|
||||||
($ident:ident; force) => {{
|
|
||||||
{
|
|
||||||
// sic! use call-site crate
|
|
||||||
crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
($ident:ident) => {{
|
($ident:ident) => {{
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
{
|
{
|
||||||
// sic! use call-site crate
|
extern "C" {
|
||||||
crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
#[no_mangle]
|
||||||
|
static $ident: std::sync::atomic::AtomicUsize;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
pub use _hit as hit;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! covers {
|
macro_rules! _check {
|
||||||
// sic! use call-site crate
|
|
||||||
($ident:ident) => {
|
($ident:ident) => {
|
||||||
$crate::covers!(crate::$ident)
|
#[no_mangle]
|
||||||
};
|
static $ident: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
|
||||||
($krate:ident :: $ident:ident) => {
|
let _checker = $crate::mark::MarkChecker::new(&$ident);
|
||||||
let _checker = $crate::marks::MarkChecker::new(&$krate::marks::$ident);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! marks {
|
|
||||||
($($ident:ident)*) => {
|
|
||||||
$(
|
|
||||||
#[allow(bad_style)]
|
|
||||||
pub static $ident: std::sync::atomic::AtomicUsize =
|
|
||||||
std::sync::atomic::AtomicUsize::new(0);
|
|
||||||
)*
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
pub use _check as check;
|
||||||
|
|
||||||
pub struct MarkChecker {
|
pub struct MarkChecker {
|
||||||
mark: &'static AtomicUsize,
|
mark: &'static AtomicUsize,
|
Loading…
Reference in a new issue