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:
bors[bot] 2020-05-20 11:03:18 +00:00 committed by GitHub
commit e3373629cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 184 additions and 293 deletions

View file

@ -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), }

View file

@ -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#"

View file

@ -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 = ();}] }",

View file

@ -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<|> {

View file

@ -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"

View file

@ -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,
" "

View file

@ -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;

View file

@ -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
];

View file

@ -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();

View file

@ -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() {

View file

@ -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#"

View file

@ -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;

View file

@ -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
);

View file

@ -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);
} }
} }

View file

@ -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) => {

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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#"

View file

@ -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

View file

@ -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)
} }

View file

@ -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()

View file

@ -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;

View file

@ -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();
} }

View file

@ -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;

View file

@ -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);

View file

@ -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
);

View file

@ -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) {

View file

@ -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 }

View file

@ -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

View file

@ -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() {

View file

@ -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#"

View file

@ -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 {

View file

@ -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, ); }"#,

View file

@ -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());
} }

View file

@ -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#"

View file

@ -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"

View file

@ -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

View file

@ -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;

View file

@ -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
);

View file

@ -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

View file

@ -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;

View file

@ -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 {

View file

@ -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(&macro_call) { if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
return Some(NameRefClass::Definition(Definition::Macro(macro_def))); return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
} }

View file

@ -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;

View file

@ -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
];

View file

@ -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;
} }

View file

@ -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,

View file

@ -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,