Repository: rust-lang/rust-analyzer
Pull request #18890 (2025-01-09 08:39:47)

minor: Fixup macro error kinds


Patch:
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index a0c4c125db..2c664029f6 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -188,6 +188,8 @@ impl fmt::Display for RenderedExpandError {
 
 impl RenderedExpandError {
     const GENERAL_KIND: &str = "macro-error";
+    const DISABLED: &str = "proc-macro-disabled";
+    const ATTR_EXP_DISABLED: &str = "attribute-expansion-disabled";
 }
 
 impl ExpandErrorKind {
@@ -196,12 +198,12 @@ impl ExpandErrorKind {
             ExpandErrorKind::ProcMacroAttrExpansionDisabled => RenderedExpandError {
                 message: "procedural attribute macro expansion is disabled".to_owned(),
                 error: false,
-                kind: "proc-macros-disabled",
+                kind: RenderedExpandError::ATTR_EXP_DISABLED,
             },
             ExpandErrorKind::MacroDisabled => RenderedExpandError {
                 message: "proc-macro is explicitly disabled".to_owned(),
                 error: false,
-                kind: "proc-macro-disabled",
+                kind: RenderedExpandError::DISABLED,
             },
             &ExpandErrorKind::MissingProcMacroExpander(def_crate) => {
                 match db.proc_macros().get_error_for_crate(def_crate) {
diff --git a/crates/ide-assists/src/handlers/add_turbo_fish.rs b/crates/ide-assists/src/handlers/add_turbo_fish.rs
index 04d63f5bc8..62700ab180 100644
--- a/crates/ide-assists/src/handlers/add_turbo_fish.rs
+++ b/crates/ide-assists/src/handlers/add_turbo_fish.rs
@@ -189,7 +189,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 /// This will create a turbofish generic arg list corresponding to the number of arguments
 fn get_fish_head(make: &SyntaxFactory, number_of_arguments: usize) -> ast::GenericArgList {
     let args = (0..number_of_arguments).map(|_| make::type_arg(make::ty_placeholder()).into());
-    make.generic_arg_list(args, true)
+    make.turbofish_generic_arg_list(args)
 }
 
 #[cfg(test)]
diff --git a/crates/ide-assists/src/handlers/unwrap_return_type.rs b/crates/ide-assists/src/handlers/unwrap_return_type.rs
index f647b531b7..64d5e2c9b8 100644
--- a/crates/ide-assists/src/handlers/unwrap_return_type.rs
+++ b/crates/ide-assists/src/handlers/unwrap_return_type.rs
@@ -1,11 +1,11 @@
-use either::Either;
 use ide_db::{
     famous_defs::FamousDefs,
     syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
 };
+use itertools::Itertools;
 use syntax::{
-    ast::{self, syntax_factory::SyntaxFactory, HasArgList, HasGenericArgs},
-    match_ast, AstNode, NodeOrToken, SyntaxKind,
+    ast::{self, Expr, HasGenericArgs},
+    match_ast, AstNode, NodeOrToken, SyntaxKind, TextRange,
 };
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -39,11 +39,11 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
     let parent = ret_type.syntax().parent()?;
-    let body_expr = match_ast! {
+    let body = match_ast! {
         match parent {
-            ast::Fn(func) => func.body()?.into(),
+            ast::Fn(func) => func.body()?,
             ast::ClosureExpr(closure) => match closure.body()? {
-                ast::Expr::BlockExpr(block) => block.into(),
+                Expr::BlockExpr(block) => block,
                 // closures require a block when a return type is specified
                 _ => return None,
             },
@@ -65,110 +65,72 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) ->
     let happy_type = extract_wrapped_type(type_ref)?;
 
     acc.add(kind.assist_id(), kind.label(), type_ref.syntax().text_range(), |builder| {
-        let mut editor = builder.make_editor(&parent);
-        let make = SyntaxFactory::new();
+        let body = ast::Expr::BlockExpr(body);
 
         let mut exprs_to_unwrap = Vec::new();
         let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_unwrap, e);
-        walk_expr(&body_expr, &mut |expr| {
-            if let ast::Expr::ReturnExpr(ret_expr) = expr {
+        walk_expr(&body, &mut |expr| {
+            if let Expr::ReturnExpr(ret_expr) = expr {
                 if let Some(ret_expr_arg) = &ret_expr.expr() {
                     for_each_tail_expr(ret_expr_arg, tail_cb);
                 }
             }
         });
-        for_each_tail_expr(&body_expr, tail_cb);
+        for_each_tail_expr(&body, tail_cb);
 
         let is_unit_type = is_unit_type(&happy_type);
         if is_unit_type {
+            let mut text_range = ret_type.syntax().text_range();
+
             if let Some(NodeOrToken::Token(token)) = ret_type.syntax().next_sibling_or_token() {
                 if token.kind() == SyntaxKind::WHITESPACE {
-                    editor.delete(token);
+                    text_range = TextRange::new(text_range.start(), token.text_range().end());
                 }
             }
 
-            editor.delete(ret_type.syntax());
+            builder.delete(text_range);
         } else {
-            editor.replace(type_ref.syntax(), happy_type.syntax());
+            builder.replace(type_ref.syntax().text_range(), happy_type.syntax().text());
         }
 
-        let mut final_placeholder = None;
-        for tail_expr in exprs_to_unwrap {
-            match &tail_expr {
-                ast::Expr::CallExpr(call_expr) => {
-                    let ast::Expr::PathExpr(path_expr) = call_expr.expr().unwrap() else {
-                        continue;
-                    };
-
-                    let path_str = path_expr.path().unwrap().to_string();
-                    let needs_replacing = match kind {
-                        UnwrapperKind::Option => path_str == "Some",
-                        UnwrapperKind::Result => path_str == "Ok" || path_str == "Err",
-                    };
-
-                    if !needs_replacing {
-                        continue;
-                    }
+        for ret_expr_arg in exprs_to_unwrap {
+            let ret_expr_str = ret_expr_arg.to_string();
+
+            let needs_replacing = match kind {
+                UnwrapperKind::Option => ret_expr_str.starts_with("Some("),
+                UnwrapperKind::Result => {
+                    ret_expr_str.starts_with("Ok(") || ret_expr_str.starts_with("Err(")
+                }
+            };
 
-                    let arg_list = call_expr.arg_list().unwrap();
+            if needs_replacing {
+                let arg_list = ret_expr_arg.syntax().children().find_map(ast::ArgList::cast);
+                if let Some(arg_list) = arg_list {
                     if is_unit_type {
-                        let tail_parent = tail_expr
-                            .syntax()
-                            .parent()
-                            .and_then(Either::<ast::ReturnExpr, ast::StmtList>::cast)
-                            .unwrap();
-                        match tail_parent {
-                            Either::Left(ret_expr) => {
-                                editor.replace(ret_expr.syntax(), make.expr_return(None).syntax())
-                            }
-                            Either::Right(stmt_list) => {
-                                let new_block = if stmt_list.statements().next().is_none() {
-                                    make.expr_empty_block()
-                                } else {
-                                    make.block_expr(stmt_list.statements(), None)
-                                };
-                                editor.replace(
-                                    stmt_list.syntax(),
-                                    new_block.stmt_list().unwrap().syntax(),
+                        match ret_expr_arg.syntax().prev_sibling_or_token() {
+                            // Useful to delete the entire line without leaving trailing whitespaces
+                            Some(whitespace) => {
+                                let new_range = TextRange::new(
+                                    whitespace.text_range().start(),
+                                    ret_expr_arg.syntax().text_range().end(),
                                 );
+                                builder.delete(new_range);
+                            }
+                            None => {
+                                builder.delete(ret_expr_arg.syntax().text_range());
                             }
                         }
-                    } else if let Some(first_arg) = arg_list.args().next() {
-                        editor.replace(tail_expr.syntax(), first_arg.syntax());
-                    }
-                }
-                ast::Expr::PathExpr(path_expr) => {
-                    let UnwrapperKind::Option = kind else {
-                        continue;
-                    };
-
-                    if path_expr.path().unwrap().to_string() != "None" {
-                        continue;
-                    }
-
-                    let new_tail_expr = make.expr_unit();
-                    editor.replace(path_expr.syntax(), new_tail_expr.syntax());
-                    if let Some(cap) = ctx.config.snippet_cap {
-                        editor.add_annotation(
-                            new_tail_expr.syntax(),
-                            builder.make_placeholder_snippet(cap),
+                    } else {
+                        builder.replace(
+                            ret_expr_arg.syntax().text_range(),
+                            arg_list.args().join(", "),
                         );
-
-                        final_placeholder = Some(new_tail_expr);
                     }
                 }
-                _ => (),
+            } else if matches!(kind, UnwrapperKind::Option if ret_expr_str == "None") {
+                builder.replace(ret_expr_arg.syntax().text_range(), "()");
             }
         }
-
-        if let Some(cap) = ctx.config.snippet_cap {
-            if let Some(final_placeholder) = final_placeholder {
-                editor.add_annotation(final_placeholder.syntax(), builder.make_tabstop_after(cap));
-            }
-        }
-
-        editor.add_mappings(make.finish_with_mappings());
-        builder.add_file_edits(ctx.file_id(), editor);
     })
 }
 
@@ -206,12 +168,12 @@ impl UnwrapperKind {
 
 fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
     match e {
-        ast::Expr::BreakExpr(break_expr) => {
+        Expr::BreakExpr(break_expr) => {
             if let Some(break_expr_arg) = break_expr.expr() {
                 for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(acc, e))
             }
         }
-        ast::Expr::ReturnExpr(_) => {
+        Expr::ReturnExpr(_) => {
             // all return expressions have already been handled by the walk loop
         }
         e => acc.push(e.clone()),
@@ -276,7 +238,8 @@ fn foo() -> Option<()$0> {
 }
 "#,
             r#"
-fn foo() {}
+fn foo() {
+}
 "#,
             "Unwrap Option return type",
         );
@@ -291,33 +254,7 @@ fn foo() -> Option<()$0>{
 }
 "#,
             r#"
-fn foo() {}
-"#,
-            "Unwrap Option return type",
-        );
-    }
-
-    #[test]
-    fn unwrap_option_return_type_none() {
-        check_assist_by_label(
-            unwrap_return_type,
-            r#"
-//- minicore: option
-fn foo() -> Option<i3$02> {
-    if true {
-        Some(42)
-    } else {
-        None
-    }
-}
-"#,
-            r#"
-fn foo() -> i32 {
-    if true {
-        42
-    } else {
-        ${1:()}$0
-    }
+fn foo() {
 }
 "#,
             "Unwrap Option return type",
@@ -325,16 +262,12 @@ fn foo() -> i32 {
     }
 
     #[test]
-    fn unwrap_option_return_type_multi_none() {
+    fn unwrap_option_return_type_none() {
         check_assist_by_label(
             unwrap_return_type,
             r#"
 //- minicore: option
 fn foo() -> Option<i3$02> {
-    if false {
-        return None;
-    }
-
     if true {
         Some(42)
     } else {
@@ -344,14 +277,10 @@ fn foo() -> Option<i3$02> {
 "#,
             r#"
 fn foo() -> i32 {
-    if false {
-        return ${1:()};
-    }
-
     if true {
         42
     } else {
-        ${2:()}$0
+        ()
     }
 }
 "#,
@@ -1333,7 +1262,8 @@ fn foo() -> Result<(), Box<dyn Error$0>> {
 }
 "#,
             r#"
-fn foo() {}
+fn foo() {
+}
 "#,
             "Unwrap Result return type",
         );
@@ -1348,7 +1278,8 @@ fn foo() -> Result<(), Box<dyn Error$0>>{
 }
 "#,
             r#"
-fn foo() {}
+fn foo() {
+}
 "#,
             "Unwrap Result return type",
         );
diff --git a/crates/ide-assists/src/handlers/wrap_return_type.rs b/crates/ide-assists/src/handlers/wrap_return_type.rs
index 0b145dcb06..658600cd2d 100644
--- a/crates/ide-assists/src/handlers/wrap_return_type.rs
+++ b/crates/ide-assists/src/handlers/wrap_return_type.rs
@@ -6,9 +6,10 @@ use ide_db::{
     famous_defs::FamousDefs,
     syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
 };
+use itertools::Itertools;
 use syntax::{
-    ast::{self, syntax_factory::SyntaxFactory, Expr, HasGenericArgs, HasGenericParams},
-    match_ast, AstNode,
+    ast::{self, make, Expr, HasGenericParams},
+    match_ast, ted, AstNode, ToSmolStr,
 };
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -42,11 +43,11 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
     let parent = ret_type.syntax().parent()?;
-    let body_expr = match_ast! {
+    let body = match_ast! {
         match parent {
-            ast::Fn(func) => func.body()?.into(),
+            ast::Fn(func) => func.body()?,
             ast::ClosureExpr(closure) => match closure.body()? {
-                Expr::BlockExpr(block) => block.into(),
+                Expr::BlockExpr(block) => block,
                 // closures require a block when a return type is specified
                 _ => return None,
             },
@@ -74,65 +75,56 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
             kind.assist_id(),
             kind.label(),
             type_ref.syntax().text_range(),
-            |builder| {
-                let mut editor = builder.make_editor(&parent);
-                let make = SyntaxFactory::new();
-                let alias = wrapper_alias(ctx, &make, &core_wrapper, type_ref, kind.symbol());
-                let new_return_ty = alias.unwrap_or_else(|| match kind {
-                    WrapperKind::Option => make.ty_option(type_ref.clone()),
-                    WrapperKind::Result => make.ty_result(type_ref.clone(), make.ty_infer().into()),
-                });
+            |edit| {
+                let alias = wrapper_alias(ctx, &core_wrapper, type_ref, kind.symbol());
+                let new_return_ty =
+                    alias.unwrap_or_else(|| kind.wrap_type(type_ref)).clone_for_update();
+
+                let body = edit.make_mut(ast::Expr::BlockExpr(body.clone()));
 
                 let mut exprs_to_wrap = Vec::new();
                 let tail_cb = &mut |e: &_| tail_cb_impl(&mut exprs_to_wrap, e);
-                walk_expr(&body_expr, &mut |expr| {
+                walk_expr(&body, &mut |expr| {
                     if let Expr::ReturnExpr(ret_expr) = expr {
                         if let Some(ret_expr_arg) = &ret_expr.expr() {
                             for_each_tail_expr(ret_expr_arg, tail_cb);
                         }
                     }
                 });
-                for_each_tail_expr(&body_expr, tail_cb);
+                for_each_tail_expr(&body, tail_cb);
 
                 for ret_expr_arg in exprs_to_wrap {
-                    let happy_wrapped = make.expr_call(
-                        make.expr_path(make.ident_path(kind.happy_ident())),
-                        make.arg_list(iter::once(ret_expr_arg.clone())),
-                    );
-                    editor.replace(ret_expr_arg.syntax(), happy_wrapped.syntax());
+                    let happy_wrapped = make::expr_call(
+                        make::expr_path(make::ext::ident_path(kind.happy_ident())),
+                        make::arg_list(iter::once(ret_expr_arg.clone())),
+                    )
+                    .clone_for_update();
+                    ted::replace(ret_expr_arg.syntax(), happy_wrapped.syntax());
                 }
 
-                editor.replace(type_ref.syntax(), new_return_ty.syntax());
+                let old_return_ty = edit.make_mut(type_ref.clone());
+                ted::replace(old_return_ty.syntax(), new_return_ty.syntax());
 
                 if let WrapperKind::Result = kind {
                     // Add a placeholder snippet at the first generic argument that doesn't equal the return type.
                     // This is normally the error type, but that may not be the case when we inserted a type alias.
-                    let args = new_return_ty
-                        .path()
-                        .unwrap()
-                        .segment()
-                        .unwrap()
-                        .generic_arg_list()
-                        .unwrap();
-                    let error_type_arg = args.generic_args().find(|arg| match arg {
-                        ast::GenericArg::TypeArg(_) => {
-                            arg.syntax().text() != type_ref.syntax().text()
-                        }
-                        ast::GenericArg::LifetimeArg(_) => false,
-                        _ => true,
+                    let args =
+                        new_return_ty.syntax().descendants().find_map(ast::GenericArgList::cast);
+                    let error_type_arg = args.and_then(|list| {
+                        list.generic_args().find(|arg| match arg {
+                            ast::GenericArg::TypeArg(_) => {
+                                arg.syntax().text() != type_ref.syntax().text()
+                            }
+                            ast::GenericArg::LifetimeArg(_) => false,
+                            _ => true,
+                        })
                     });
                     if let Some(error_type_arg) = error_type_arg {
                         if let Some(cap) = ctx.config.snippet_cap {
-                            editor.add_annotation(
-                                error_type_arg.syntax(),
-                                builder.make_placeholder_snippet(cap),
-                            );
+                            edit.add_placeholder_snippet(cap, error_type_arg);
                         }
                     }
                 }
-
-                editor.add_mappings(make.finish_with_mappings());
-                builder.add_file_edits(ctx.file_id(), editor);
             },
         );
     }
@@ -184,16 +176,22 @@ impl WrapperKind {
             WrapperKind::Result => hir::sym::Result.clone(),
         }
     }
+
+    fn wrap_type(&self, type_ref: &ast::Type) -> ast::Type {
+        match self {
+            WrapperKind::Option => make::ext::ty_option(type_ref.clone()),
+            WrapperKind::Result => make::ext::ty_result(type_ref.clone(), make::ty_placeholder()),
+        }
+    }
 }
 
 // Try to find an wrapper type alias in the current scope (shadowing the default).
 fn wrapper_alias(
     ctx: &AssistContext<'_>,
-    make: &SyntaxFactory,
     core_wrapper: &hir::Enum,
     ret_type: &ast::Type,
     wrapper: hir::Symbol,
-) -> Option<ast::PathType> {
+) -> Option<ast::Type> {
     let wrapper_path = hir::ModPath::from_segments(
         hir::PathKind::Plain,
         iter::once(hir::Name::new_symbol_root(wrapper)),
@@ -209,28 +207,25 @@ fn wrapper_alias(
         })
         .find_map(|alias| {
             let mut inserted_ret_type = false;
-            let generic_args =
-                alias.source(ctx.db())?.value.generic_param_list()?.generic_params().map(|param| {
-                    match param {
-                        // Replace the very first type parameter with the function's return type.
-                        ast::GenericParam::TypeParam(_) if !inserted_ret_type => {
-                            inserted_ret_type = true;
-                            make.type_arg(ret_type.clone()).into()
-                        }
-                        ast::GenericParam::LifetimeParam(_) => {
-                            make.lifetime_arg(make.lifetime("'_")).into()
-                        }
-                        _ => make.type_arg(make.ty_infer().into()).into(),
+            let generic_params = alias
+                .source(ctx.db())?
+                .value
+                .generic_param_list()?
+                .generic_params()
+                .map(|param| match param {
+                    // Replace the very first type parameter with the functions return type.
+                    ast::GenericParam::TypeParam(_) if !inserted_ret_type => {
+                        inserted_ret_type = true;
+                        ret_type.to_smolstr()
                     }
-                });
+                    ast::GenericParam::LifetimeParam(_) => make::lifetime("'_").to_smolstr(),
+                    _ => make::ty_placeholder().to_smolstr(),
+                })
+                .join(", ");
 
             let name = alias.name(ctx.db());
-            let generic_arg_list = make.generic_arg_list(generic_args, false);
-            let path = make.path_unqualified(
-                make.path_segment_generics(make.name_ref(name.as_str()), generic_arg_list),
-            );
-
-            Some(make.ty_path(path))
+            let name = name.as_str();
+            Some(make::ty(&format!("{name}<{generic_params}>")))
         })
     })
 }
diff --git a/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/crates/ide-assists/src/utils/gen_trait_fn_body.rs
index 7a9bdfe1ec..a9a889acc2 100644
--- a/crates/ide-assists/src/utils/gen_trait_fn_body.rs
+++ b/crates/ide-assists/src/utils/gen_trait_fn_body.rs
@@ -599,7 +599,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>)
         let variant_name =
             make::path_pat(make::ext::path_from_idents(["core", "cmp", "Ordering", "Equal"])?);
         let lhs = make::tuple_struct_pat(make::ext::path_from_idents(["Some"])?, [variant_name]);
-        arms.push(make::match_arm(lhs.into(), None, make::expr_empty_block().into()));
+        arms.push(make::match_arm(lhs.into(), None, make::expr_empty_block()));
 
         arms.push(make::match_arm(
             make::ident_pat(false, false, make::name("ord")).into(),
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index 8d44dbab60..26074672ba 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -214,13 +214,25 @@ fn complete_methods(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check_edit, check_no_kw, check_with_private_editable};
+    use crate::tests::{
+        check_edit, completion_list_no_kw, completion_list_no_kw_with_private_editable,
+    };
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_no_kw(ra_fixture);
+        expect.assert_eq(&actual);
+    }
+
+    fn check_with_private_editable(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_no_kw_with_private_editable(ra_fixture);
+        expect.assert_eq(&actual);
+    }
 
     #[test]
     fn test_struct_field_and_method_completion() {
-        check_no_kw(
+        check(
             r#"
 struct S { foo: u32 }
 impl S {
@@ -237,7 +249,7 @@ fn foo(s: S) { s.$0 }
 
     #[test]
     fn no_unstable_method_on_stable() {
-        check_no_kw(
+        check(
             r#"
 //- /main.rs crate:main deps:std
 fn foo(s: std::S) { s.$0 }
@@ -254,7 +266,7 @@ impl S {
 
     #[test]
     fn unstable_method_on_nightly() {
-        check_no_kw(
+        check(
             r#"
 //- toolchain:nightly
 //- /main.rs crate:main deps:std
@@ -274,7 +286,7 @@ impl S {
 
     #[test]
     fn test_struct_field_completion_self() {
-        check_no_kw(
+        check(
             r#"
 struct S { the_field: (u32,) }
 impl S {
@@ -290,7 +302,7 @@ impl S {
 
     #[test]
     fn test_struct_field_completion_autoderef() {
-        check_no_kw(
+        check(
             r#"
 struct A { the_field: (u32, i32) }
 impl A {
@@ -306,7 +318,7 @@ impl A {
 
     #[test]
     fn test_no_struct_field_completion_for_method_call() {
-        check_no_kw(
+        check(
             r#"
 struct A { the_field: u32 }
 fn foo(a: A) { a.$0() }
@@ -317,7 +329,7 @@ fn foo(a: A) { a.$0() }
 
     #[test]
     fn test_visibility_filtering() {
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib new_source_root:local
 pub mod m {
@@ -336,7 +348,7 @@ fn foo(a: lib::m::A) { a.$0 }
             "#]],
         );
 
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib new_source_root:library
 pub mod m {
@@ -355,7 +367,7 @@ fn foo(a: lib::m::A) { a.$0 }
             "#]],
         );
 
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib new_source_root:library
 pub mod m {
@@ -372,7 +384,7 @@ fn foo(a: lib::m::A) { a.$0 }
             "#]],
         );
 
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib new_source_root:local
 pub struct A {}
@@ -390,7 +402,7 @@ fn foo(a: lib::A) { a.$0 }
                 me pub_method() fn(&self)
             "#]],
         );
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib new_source_root:library
 pub struct A {}
@@ -512,7 +524,7 @@ fn foo(a: lib::A) { a.$0 }
 
     #[test]
     fn test_local_impls() {
-        check_no_kw(
+        check(
             r#"
 pub struct A {}
 mod m {
@@ -541,7 +553,7 @@ fn foo(a: A) {
 
     #[test]
     fn test_doc_hidden_filtering() {
-        check_no_kw(
+        check(
             r#"
 //- /lib.rs crate:lib deps:dep
 fn foo(a: dep::A) { a.$0 }
@@ -568,7 +580,7 @@ impl A {
 
     #[test]
     fn test_union_field_completion() {
-        check_no_kw(
+        check(
             r#"
 union U { field: u8, other: u16 }
 fn foo(u: U) { u.$0 }
@@ -582,7 +594,7 @@ fn foo(u: U) { u.$0 }
 
     #[test]
     fn test_method_completion_only_fitting_impls() {
-        check_no_kw(
+        check(
             r#"
 struct A<T> {}
 impl A<u32> {
@@ -601,7 +613,7 @@ fn foo(a: A<u32>) { a.$0 }
 
     #[test]
     fn test_trait_method_completion() {
-        check_no_kw(
+        check(
             r#"
 struct A {}
 trait Trait { fn the_method(&self); }
@@ -631,7 +643,7 @@ fn foo(a: A) { a.the_method();$0 }
 
     #[test]
     fn test_trait_method_completion_deduplicated() {
-        check_no_kw(
+        check(
             r"
 struct A {}
 trait Trait { fn the_method(&self); }
@@ -646,7 +658,7 @@ fn foo(a: &A) { a.$0 }
 
     #[test]
     fn completes_trait_method_from_other_module() {
-        check_no_kw(
+        check(
             r"
 struct A {}
 mod m {
@@ -664,7 +676,7 @@ fn foo(a: A) { a.$0 }
 
     #[test]
     fn test_no_non_self_method() {
-        check_no_kw(
+        check(
             r#"
 struct A {}
 impl A {
@@ -680,7 +692,7 @@ fn foo(a: A) {
 
     #[test]
     fn test_tuple_field_completion() {
-        check_no_kw(
+        check(
             r#"
 fn foo() {
    let b = (0, 3.14);
@@ -696,7 +708,7 @@ fn foo() {
 
     #[test]
     fn test_tuple_struct_field_completion() {
-        check_no_kw(
+        check(
             r#"
 struct S(i32, f64);
 fn foo() {
@@ -713,7 +725,7 @@ fn foo() {
 
     #[test]
     fn test_tuple_field_inference() {
-        check_no_kw(
+        check(
             r#"
 pub struct S;
 impl S { pub fn blah(&self) {} }
@@ -735,7 +747,7 @@ impl T {
 
     #[test]
     fn test_field_no_same_name() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 struct A { field: u8 }
@@ -758,7 +770,7 @@ fn test(a: A) {
 
     #[test]
     fn test_tuple_field_no_same_index() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 struct A(u8);
@@ -781,7 +793,7 @@ fn test(a: A) {
 
     #[test]
     fn test_tuple_struct_deref_to_tuple_no_same_index() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 struct A(u8);
@@ -803,7 +815,7 @@ fn test(a: A) {
 
     #[test]
     fn test_completion_works_in_consts() {
-        check_no_kw(
+        check(
             r#"
 struct A { the_field: u32 }
 const X: u32 = {
@@ -818,7 +830,7 @@ const X: u32 = {
 
     #[test]
     fn works_in_simple_macro_1() {
-        check_no_kw(
+        check(
             r#"
 macro_rules! m { ($e:expr) => { $e } }
 struct A { the_field: u32 }
@@ -835,7 +847,7 @@ fn foo(a: A) {
     #[test]
     fn works_in_simple_macro_2() {
         // this doesn't work yet because the macro doesn't expand without the token -- maybe it can be fixed with better recovery
-        check_no_kw(
+        check(
             r#"
 macro_rules! m { ($e:expr) => { $e } }
 struct A { the_field: u32 }
@@ -851,7 +863,7 @@ fn foo(a: A) {
 
     #[test]
     fn works_in_simple_macro_recursive_1() {
-        check_no_kw(
+        check(
             r#"
 macro_rules! m { ($e:expr) => { $e } }
 struct A { the_field: u32 }
@@ -867,7 +879,7 @@ fn foo(a: A) {
 
     #[test]
     fn macro_expansion_resilient() {
-        check_no_kw(
+        check(
             r#"
 macro_rules! d {
     () => {};
@@ -893,7 +905,7 @@ fn foo(a: A) {
 
     #[test]
     fn test_method_completion_issue_3547() {
-        check_no_kw(
+        check(
             r#"
 struct HashSet<T> {}
 impl<T> HashSet<T> {
@@ -912,7 +924,7 @@ fn foo() {
 
     #[test]
     fn completes_method_call_when_receiver_is_a_macro_call() {
-        check_no_kw(
+        check(
             r#"
 struct S;
 impl S { fn foo(&self) {} }
@@ -927,7 +939,7 @@ fn main() { make_s!().f$0; }
 
     #[test]
     fn completes_after_macro_call_in_submodule() {
-        check_no_kw(
+        check(
             r#"
 macro_rules! empty {
     () => {};
@@ -955,7 +967,7 @@ mod foo {
 
     #[test]
     fn issue_8931() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: fn
 struct S;
@@ -982,7 +994,7 @@ impl S {
 
     #[test]
     fn completes_bare_fields_and_methods_in_methods() {
-        check_no_kw(
+        check(
             r#"
 struct Foo { field: i32 }
 
@@ -996,7 +1008,7 @@ impl Foo { fn foo(&self) { $0 } }"#,
                 bt u32              u32
             "#]],
         );
-        check_no_kw(
+        check(
             r#"
 struct Foo(i32);
 
@@ -1014,7 +1026,7 @@ impl Foo { fn foo(&mut self) { $0 } }"#,
 
     #[test]
     fn macro_completion_after_dot() {
-        check_no_kw(
+        check(
             r#"
 macro_rules! m {
     ($e:expr) => { $e };
@@ -1039,7 +1051,7 @@ fn f() {
 
     #[test]
     fn completes_method_call_when_receiver_type_has_errors_issue_10297() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: iterator, sized
 struct Vec<T>;
@@ -1090,7 +1102,7 @@ fn main() {
 
     #[test]
     fn issue_12484() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: sized
 trait SizeUser {
@@ -1112,7 +1124,7 @@ fn test(thing: impl Encrypt) {
 
     #[test]
     fn only_consider_same_type_once() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 struct A(u8);
@@ -1138,7 +1150,7 @@ fn test(a: A) {
 
     #[test]
     fn no_inference_var_in_completion() {
-        check_no_kw(
+        check(
             r#"
 struct S<T>(T);
 fn test(s: S<Unknown>) {
@@ -1153,7 +1165,7 @@ fn test(s: S<Unknown>) {
 
     #[test]
     fn assoc_impl_1() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 fn main() {
@@ -1194,7 +1206,7 @@ impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> {
 
     #[test]
     fn assoc_impl_2() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: deref
 fn main() {
@@ -1230,7 +1242,7 @@ impl<B: Bar, F: core::ops::Deref<Target = B>> Foo<F> {
 
     #[test]
     fn test_struct_function_field_completion() {
-        check_no_kw(
+        check(
             r#"
 struct S { va_field: u32, fn_field: fn() }
 fn foo() { S { va_field: 0, fn_field: || {} }.fi$0() }
@@ -1255,7 +1267,7 @@ fn foo() { (S { va_field: 0, fn_field: || {} }.fn_field)() }
 
     #[test]
     fn test_tuple_function_field_completion() {
-        check_no_kw(
+        check(
             r#"
 struct B(u32, fn())
 fn foo() {
@@ -1289,7 +1301,7 @@ fn foo() {
 
     #[test]
     fn test_fn_field_dot_access_method_has_parens_false() {
-        check_no_kw(
+        check(
             r#"
 struct Foo { baz: fn() }
 impl Foo {
diff --git a/crates/ide-completion/src/completions/extern_abi.rs b/crates/ide-completion/src/completions/extern_abi.rs
index 7c2cc2a6c1..bcfda928c4 100644
--- a/crates/ide-completion/src/completions/extern_abi.rs
+++ b/crates/ide-completion/src/completions/extern_abi.rs
@@ -65,13 +65,18 @@ pub(crate) fn complete_extern_abi(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check_edit, check_no_kw};
+    use crate::tests::{check_edit, completion_list_no_kw};
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_no_kw(ra_fixture);
+        expect.assert_eq(&actual);
+    }
 
     #[test]
     fn only_completes_in_string_literals() {
-        check_no_kw(
+        check(
             r#"
 $0 fn foo {}
 "#,
@@ -81,7 +86,7 @@ $0 fn foo {}
 
     #[test]
     fn requires_extern_prefix() {
-        check_no_kw(
+        check(
             r#"
 "$0" fn foo {}
 "#,
@@ -91,7 +96,7 @@ $0 fn foo {}
 
     #[test]
     fn works() {
-        check_no_kw(
+        check(
             r#"
 extern "$0" fn foo {}
 "#,
diff --git a/crates/ide-completion/src/completions/format_string.rs b/crates/ide-completion/src/completions/format_string.rs
index dcd40c3412..a87c60c694 100644
--- a/crates/ide-completion/src/completions/format_string.rs
+++ b/crates/ide-completion/src/completions/format_string.rs
@@ -61,13 +61,18 @@ pub(crate) fn format_string(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check_edit, check_no_kw};
+    use crate::tests::{check_edit, completion_list_no_kw};
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_no_kw(ra_fixture);
+        expect.assert_eq(&actual);
+    }
 
     #[test]
     fn works_when_wrapped() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: fmt
 macro_rules! print {
@@ -84,7 +89,7 @@ fn main() {
 
     #[test]
     fn no_completion_without_brace() {
-        check_no_kw(
+        check(
             r#"
 //- minicore: fmt
 fn main() {
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index 6d1945c453..80d72b460f 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -514,13 +514,18 @@ fn function_declaration(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check_edit, check_no_kw};
+    use crate::tests::{check_edit, completion_list_no_kw};
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_no_kw(ra_fixture);
+        expect.assert_eq(&actual)
+    }
 
     #[test]
     fn no_completion_inside_fn() {
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(); fn test2(); }
 struct T;
@@ -539,7 +544,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(); fn test2(); }
 struct T;
@@ -553,7 +558,7 @@ impl Test for T {
             expect![[""]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(); fn test2(); }
 struct T;
@@ -568,7 +573,7 @@ impl Test for T {
         );
 
         // https://github.com/rust-lang/rust-analyzer/pull/5976#issuecomment-692332191
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(); fn test2(); }
 struct T;
@@ -582,7 +587,7 @@ impl Test for T {
             expect![[r#""#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(_: i32); fn test2(); }
 struct T;
@@ -601,7 +606,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { fn test(_: fn()); fn test2(); }
 struct T;
@@ -619,7 +624,7 @@ impl Test for T {
 
     #[test]
     fn no_completion_inside_const() {
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: fn(); const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -631,7 +636,7 @@ impl Test for T {
             expect![[r#""#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -648,7 +653,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -665,7 +670,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -684,7 +689,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -698,7 +703,7 @@ impl Test for T {
             expect![[""]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); }
 struct T;
@@ -715,7 +720,7 @@ impl Test for T {
 
     #[test]
     fn no_completion_inside_type() {
-        check_no_kw(
+        check(
             r"
 trait Test { type Test; type Test2; fn test(); }
 struct T;
@@ -732,7 +737,7 @@ impl Test for T {
             "#]],
         );
 
-        check_no_kw(
+        check(
             r"
 trait Test { type Test; type Test2; fn test(); }
 struct T;
@@ -1258,7 +1263,7 @@ impl Foo<u32> for Bar {
 
     #[test]
     fn works_directly_in_impl() {
-        check_no_kw(
+        check(
             r#"
 trait Tr {
     fn required();
@@ -1272,7 +1277,7 @@ impl Tr for () {
             fn fn required()
         "#]],
         );
-        check_no_kw(
+        check(
             r#"
 trait Tr {
     fn provided() {}
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs
index 6541ee502d..4700ed6c1a 100644
--- a/crates/ide-completion/src/completions/keyword.rs
+++ b/crates/ide-completion/src/completions/keyword.rs
@@ -32,9 +32,14 @@ pub(crate) fn complete_for_and_where(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check, check_edit};
+    use crate::tests::{check_edit, completion_list};
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual)
+    }
 
     #[test]
     fn test_else_edit_after_if() {
diff --git a/crates/ide-completion/src/completions/lifetime.rs b/crates/ide-completion/src/completions/lifetime.rs
index 53a62fe49c..0692446381 100644
--- a/crates/ide-completion/src/completions/lifetime.rs
+++ b/crates/ide-completion/src/completions/lifetime.rs
@@ -59,9 +59,14 @@ pub(crate) fn complete_label(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::{check, check_edit};
+    use crate::tests::{check_edit, completion_list};
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual);
+    }
 
     #[test]
     fn check_lifetime_edit() {
diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs
index bafe329420..f12f011a6b 100644
--- a/crates/ide-completion/src/completions/mod_.rs
+++ b/crates/ide-completion/src/completions/mod_.rs
@@ -159,9 +159,14 @@ fn module_chain_to_containing_module_file(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
-    use crate::tests::check;
+    use crate::tests::completion_list;
+
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual);
+    }
 
     #[test]
     fn lib_module_completion() {
diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs
index 67ea05e002..5bdc320d57 100644
--- a/crates/ide-completion/src/completions/postfix.rs
+++ b/crates/ide-completion/src/completions/postfix.rs
@@ -401,13 +401,18 @@ fn add_custom_postfix_completions(
 
 #[cfg(test)]
 mod tests {
-    use expect_test::expect;
+    use expect_test::{expect, Expect};
 
     use crate::{
-        tests::{check, check_edit, check_edit_with_config, TEST_CONFIG},
+        tests::{check_edit, check_edit_with_config, completion_list, TEST_CONFIG},
         CompletionConfig, Snippet,
     };
 
+    fn check(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual)
+    }
+
     #[test]
     fn postfix_completion_works_for_trivial_path_expression() {
         check(
diff --git a/crates/ide-diagnostics/src/handlers/macro_error.rs b/crates/ide-diagnostics/src/handlers/macro_error.rs
index e177b72e4d..edf656ed04 100644
--- a/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -4,13 +4,13 @@ use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, Severity};
 //
 // This diagnostic is shown for macro expansion errors.
 
-// Diagnostic: proc-macros-disabled
+// Diagnostic: attribute-expansion-disabled
 //
-// This diagnostic is shown for proc macros where proc macros have been disabled.
+// This diagnostic is shown for attribute proc macros when attribute expansions have been disabled.
 
 // Diagnostic: proc-macro-disabled
 //
-// This diagnostic is shown for proc macros that has been specifically disabled via `rust-analyzer.procMacro.ignored`.
+// This diagnostic is shown for proc macros that have been specifically disabled via `rust-analyzer.procMacro.ignored`.
 pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic {
     // Use more accurate position if available.
     let display_range = ctx.resolve_precise_location(&d.node, d.precise_location);
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index dca231604f..a920fe4f35 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -558,8 +558,8 @@ pub fn expr_const_value(text: &str) -> ast::ConstArg {
     ast_from_text(&format!("trait Foo<const N: usize = {text}> {{}}"))
 }
 
-pub fn expr_empty_block() -> ast::BlockExpr {
-    ast_from_text("const C: () = {};")
+pub fn expr_empty_block() -> ast::Expr {
+    expr_from_text("{}")
 }
 pub fn expr_path(path: ast::Path) -> ast::Expr {
     expr_from_text(&path.to_string())
diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs
index 572622db54..d62c01ba76 100644
--- a/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -1,9 +1,6 @@
 //! Wrappers over [`make`] constructors
 use crate::{
-    ast::{
-        self, make, HasArgList, HasGenericArgs, HasGenericParams, HasName, HasTypeBounds,
-        HasVisibility,
-    },
+    ast::{self, make, HasGenericArgs, HasGenericParams, HasName, HasTypeBounds, HasVisibility},
     syntax_editor::SyntaxMappingBuilder,
     AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken,
 };
@@ -19,10 +16,6 @@ impl SyntaxFactory {
         make::name_ref(name).clone_for_update()
     }
 
-    pub fn lifetime(&self, text: &str) -> ast::Lifetime {
-        make::lifetime(text).clone_for_update()
-    }
-
     pub fn ty(&self, text: &str) -> ast::Type {
         make::ty(text).clone_for_update()
     }
@@ -35,20 +28,6 @@ impl SyntaxFactory {
         ast
     }
 
-    pub fn ty_path(&self, path: ast::Path) -> ast::PathType {
-        let ast::Type::PathType(ast) = make::ty_path(path.clone()).clone_for_update() else {
-            unreachable!()
-        };
-
-        if let Some(mut mapping) = self.mappings() {
-            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
-            builder.finish(&mut mapping);
-        }
-
-        ast
-    }
-
     pub fn type_param(
         &self,
         name: ast::Name,
@@ -211,7 +190,7 @@ impl SyntaxFactory {
     }
 
     pub fn expr_empty_block(&self) -> ast::BlockExpr {
-        make::expr_empty_block().clone_for_update()
+        ast::BlockExpr { syntax: make::expr_empty_block().syntax().clone_for_update() }
     }
 
     pub fn expr_tuple(&self, fields: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr {
@@ -274,37 +253,6 @@ impl SyntaxFactory {
         ast
     }
 
-    pub fn expr_call(&self, expr: ast::Expr, arg_list: ast::ArgList) -> ast::CallExpr {
-        // FIXME: `make::expr_call`` should return a `CallExpr`, not just an `Expr`
-        let ast::Expr::CallExpr(ast) =
-            make::expr_call(expr.clone(), arg_list.clone()).clone_for_update()
-        else {
-            unreachable!()
-        };
-
-        if let Some(mut mapping) = self.mappings() {
-            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone());
-            builder.map_node(arg_list.syntax().clone(), ast.arg_list().unwrap().syntax().clone());
-            builder.finish(&mut mapping);
-        }
-
-        ast
-    }
-
-    pub fn arg_list(&self, args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
-        let (args, input) = iterator_input(args);
-        let ast = make::arg_list(args).clone_for_update();
-
-        if let Some(mut mapping) = self.mappings() {
-            let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone());
-            builder.map_children(input.into_iter(), ast.args().map(|it| it.syntax().clone()));
-            builder.finish(&mut mapping);
-        }
-
-        ast
-    }
-
     pub fn expr_ref(&self, expr: ast::Expr, exclusive: bool) -> ast::Expr {
         let ast::Expr::RefExpr(ast) = make::expr_ref(expr.clone(), exclusive).clone_for_update()
         else {
@@ -480,30 +428,6 @@ impl SyntaxFactory {
         ast
     }
 
-    pub fn type_arg(&self, ty: ast::Type) -> ast::TypeArg {
-        let ast = make::type_arg(ty.clone()).clone_for_update();
-
-        if let Some(mut mapping) = self.mappings() {
-            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
-            builder.finish(&mut mapping);
-        }
-
-        ast
-    }
-
-    pub fn lifetime_arg(&self, lifetime: ast::Lifetime) -> ast::LifetimeArg {
-        let ast = make::lifetime_arg(lifetime.clone()).clone_for_update();
-
-        if let Some(mut mapping) = self.mappings() {
-            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_node(lifetime.syntax().clone(), ast.lifetime().unwrap().syntax().clone());
-            builder.finish(&mut mapping);
-        }
-
-        ast
-    }
-
     pub fn item_const(
         &self,
         visibility: Option<ast::Visibility>,
@@ -571,17 +495,12 @@ impl SyntaxFactory {
         ast
     }
 
-    pub fn generic_arg_list(
+    pub fn turbofish_generic_arg_list(
         &self,
         generic_args: impl IntoIterator<Item = ast::GenericArg>,
-        is_turbo: bool,
     ) -> ast::GenericArgList {
         let (generic_args, input) = iterator_input(generic_args);
-        let ast = if is_turbo {
-            make::turbofish_generic_arg_list(generic_args).clone_for_update()
-        } else {
-            make::generic_arg_list(generic_args).clone_for_update()
-        };
+        let ast = make::turbofish_generic_arg_list(generic_args.clone()).clone_for_update();
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
@@ -834,31 +753,12 @@ impl SyntaxFactory {
 
 // `ext` constructors
 impl SyntaxFactory {
-    pub fn ident_path(&self, ident: &str) -> ast::Path {
-        self.path_unqualified(self.path_segment(self.name_ref(ident)))
-    }
-
     pub fn expr_unit(&self) -> ast::Expr {
         self.expr_tuple([]).into()
     }
 
-    pub fn ty_option(&self, t: ast::Type) -> ast::PathType {
-        let generic_arg_list = self.generic_arg_list([self.type_arg(t).into()], false);
-        let path = self.path_unqualified(
-            self.path_segment_generics(self.name_ref("Option"), generic_arg_list),
-        );
-
-        self.ty_path(path)
-    }
-
-    pub fn ty_result(&self, t: ast::Type, e: ast::Type) -> ast::PathType {
-        let generic_arg_list =
-            self.generic_arg_list([self.type_arg(t).into(), self.type_arg(e).into()], false);
-        let path = self.path_unqualified(
-            self.path_segment_generics(self.name_ref("Result"), generic_arg_list),
-        );
-
-        self.ty_path(path)
+    pub fn ident_path(&self, ident: &str) -> ast::Path {
+        self.path_unqualified(self.path_segment(self.name_ref(ident)))
     }
 }
 


Test patch:
diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs
index 71d143a2b7..1815f34053 100644
--- a/crates/ide-completion/src/tests.rs
+++ b/crates/ide-completion/src/tests.rs
@@ -253,34 +253,11 @@ pub(crate) fn check_edit_with_config(
     assert_eq_text!(&ra_fixture_after, &actual)
 }
 
-pub(crate) fn check(ra_fixture: &str, expect: Expect) {
+fn check_empty(ra_fixture: &str, expect: Expect) {
     let actual = completion_list(ra_fixture);
     expect.assert_eq(&actual);
 }
 
-pub(crate) fn check_with_base_items(ra_fixture: &str, expect: Expect) {
-    check(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"), expect)
-}
-
-pub(crate) fn check_no_kw(ra_fixture: &str, expect: Expect) {
-    let actual = completion_list_no_kw(ra_fixture);
-    expect.assert_eq(&actual)
-}
-
-pub(crate) fn check_with_private_editable(ra_fixture: &str, expect: Expect) {
-    let actual = completion_list_no_kw_with_private_editable(ra_fixture);
-    expect.assert_eq(&actual);
-}
-
-pub(crate) fn check_with_trigger_character(
-    ra_fixture: &str,
-    trigger_character: Option<char>,
-    expect: Expect,
-) {
-    let actual = completion_list_with_trigger_character(ra_fixture, trigger_character);
-    expect.assert_eq(&actual)
-}
-
 pub(crate) fn get_all_items(
     config: CompletionConfig<'_>,
     code: &str,
diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs
index 32d3b50f23..ebf3582057 100644
--- a/crates/ide-completion/src/tests/attribute.rs
+++ b/crates/ide-completion/src/tests/attribute.rs
@@ -1,7 +1,12 @@
 //! Completion tests for attributes.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_edit};
+use crate::tests::{check_edit, completion_list};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual);
+}
 
 #[test]
 fn derive_helpers() {
@@ -783,9 +788,14 @@ mod cfg {
 mod derive {
     use super::*;
 
+    fn check_derive(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual);
+    }
+
     #[test]
     fn no_completion_for_incorrect_derive() {
-        check(
+        check_derive(
             r#"
 //- minicore: derive, copy, clone, ord, eq, default, fmt
 #[derive{$0)] struct Test;
@@ -796,7 +806,7 @@ mod derive {
 
     #[test]
     fn empty_derive() {
-        check(
+        check_derive(
             r#"
 //- minicore: derive, copy, clone, ord, eq, default, fmt
 #[derive($0)] struct Test;
@@ -818,7 +828,7 @@ mod derive {
 
     #[test]
     fn derive_with_input_before() {
-        check(
+        check_derive(
             r#"
 //- minicore: derive, copy, clone, ord, eq, default, fmt
 #[derive(serde::Serialize, PartialEq, $0)] struct Test;
@@ -839,7 +849,7 @@ mod derive {
 
     #[test]
     fn derive_with_input_after() {
-        check(
+        check_derive(
             r#"
 //- minicore: derive, copy, clone, ord, eq, default, fmt
 #[derive($0 serde::Serialize, PartialEq)] struct Test;
@@ -860,7 +870,7 @@ mod derive {
 
     #[test]
     fn derive_with_existing_derives() {
-        check(
+        check_derive(
             r#"
 //- minicore: derive, copy, clone, ord, eq, default, fmt
 #[derive(PartialEq, Eq, Or$0)] struct Test;
@@ -880,7 +890,7 @@ mod derive {
 
     #[test]
     fn derive_flyimport() {
-        check(
+        check_derive(
             r#"
 //- proc_macros: derive_identity
 //- minicore: derive
@@ -894,7 +904,7 @@ mod derive {
                 kw self::
             "#]],
         );
-        check(
+        check_derive(
             r#"
 //- proc_macros: derive_identity
 //- minicore: derive
@@ -930,7 +940,7 @@ use proc_macros::DeriveIdentity;
 
     #[test]
     fn qualified() {
-        check(
+        check_derive(
             r#"
 //- proc_macros: derive_identity
 //- minicore: derive, copy, clone
@@ -940,7 +950,7 @@ use proc_macros::DeriveIdentity;
                 de DeriveIdentity proc_macro DeriveIdentity
             "#]],
         );
-        check(
+        check_derive(
             r#"
 //- proc_macros: derive_identity
 //- minicore: derive, copy, clone
@@ -1046,14 +1056,19 @@ mod lint {
 mod repr {
     use super::*;
 
+    fn check_repr(ra_fixture: &str, expect: Expect) {
+        let actual = completion_list(ra_fixture);
+        expect.assert_eq(&actual);
+    }
+
     #[test]
     fn no_completion_for_incorrect_repr() {
-        check(r#"#[repr{$0)] struct Test;"#, expect![[]])
+        check_repr(r#"#[repr{$0)] struct Test;"#, expect![[]])
     }
 
     #[test]
     fn empty() {
-        check(
+        check_repr(
             r#"#[repr($0)] struct Test;"#,
             expect![[r#"
                 ba C
@@ -1078,12 +1093,12 @@ mod repr {
 
     #[test]
     fn transparent() {
-        check(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]);
+        check_repr(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]);
     }
 
     #[test]
     fn align() {
-        check(
+        check_repr(
             r#"#[repr(align(1), $0)] struct Test;"#,
             expect![[r#"
                 ba C
@@ -1106,7 +1121,7 @@ mod repr {
 
     #[test]
     fn packed() {
-        check(
+        check_repr(
             r#"#[repr(packed, $0)] struct Test;"#,
             expect![[r#"
                 ba C
@@ -1129,7 +1144,7 @@ mod repr {
 
     #[test]
     fn c() {
-        check(
+        check_repr(
             r#"#[repr(C, $0)] struct Test;"#,
             expect![[r#"
                 ba align($0)
@@ -1152,7 +1167,7 @@ mod repr {
 
     #[test]
     fn prim() {
-        check(
+        check_repr(
             r#"#[repr(usize, $0)] struct Test;"#,
             expect![[r#"
                 ba C
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
index 3cc7fc9d92..3046614868 100644
--- a/crates/ide-completion/src/tests/expression.rs
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -4,12 +4,17 @@ use expect_test::{expect, Expect};
 use crate::{
     config::AutoImportExclusionType,
     tests::{
-        check, check_edit, check_with_base_items, completion_list_with_config, BASE_ITEMS_FIXTURE,
+        check_edit, check_empty, completion_list, completion_list_with_config, BASE_ITEMS_FIXTURE,
         TEST_CONFIG,
     },
     CompletionConfig,
 };
 
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
+
 fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Expect) {
     let actual = completion_list_with_config(
         config,
@@ -23,7 +28,7 @@ fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Exp
 #[test]
 fn complete_literal_struct_with_a_private_field() {
     // `FooDesc.bar` is private, the completion should not be triggered.
-    check_with_base_items(
+    check(
         r#"
 mod _69latrick {
     pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, bar: bool }
@@ -74,7 +79,7 @@ fn baz() {
 
 #[test]
 fn completes_various_bindings() {
-    check(
+    check_empty(
         r#"
 fn func(param0 @ (param1, param2): (i32, i32)) {
     let letlocal = 92;
@@ -120,7 +125,7 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
 
 #[test]
 fn completes_all_the_things_in_fn_body() {
-    check_with_base_items(
+    check(
         r#"
 use non_existent::Unresolved;
 mod qualified { pub enum Enum { Variant } }
@@ -186,7 +191,7 @@ impl Unit {
             ?? Unresolved
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 use non_existent::Unresolved;
 mod qualified { pub enum Enum { Variant } }
@@ -219,7 +224,7 @@ impl Unit {
 
 #[test]
 fn complete_in_block() {
-    check(
+    check_empty(
         r#"
     fn foo() {
         if true {
@@ -268,7 +273,7 @@ fn complete_in_block() {
 
 #[test]
 fn complete_after_if_expr() {
-    check(
+    check_empty(
         r#"
     fn foo() {
         if true {}
@@ -316,7 +321,7 @@ fn complete_after_if_expr() {
 
 #[test]
 fn complete_in_match_arm() {
-    check(
+    check_empty(
         r#"
     fn foo() {
         match () {
@@ -346,7 +351,7 @@ fn complete_in_match_arm() {
 
 #[test]
 fn completes_in_loop_ctx() {
-    check(
+    check_empty(
         r"fn my() { loop { $0 } }",
         expect![[r#"
             fn my()   fn()
@@ -385,7 +390,7 @@ fn completes_in_loop_ctx() {
             sn ppd
         "#]],
     );
-    check(
+    check_empty(
         r"fn my() { loop { foo.$0 } }",
         expect![[r#"
             sn box  Box::new(expr)
@@ -410,7 +415,7 @@ fn completes_in_loop_ctx() {
 
 #[test]
 fn completes_in_let_initializer() {
-    check(
+    check_empty(
         r#"fn main() { let _ = $0 }"#,
         expect![[r#"
             fn main() fn()
@@ -434,7 +439,7 @@ fn completes_in_let_initializer() {
 
 #[test]
 fn struct_initializer_field_expr() {
-    check(
+    check_empty(
         r#"
 struct Foo {
     pub f: i32,
@@ -470,7 +475,7 @@ fn foo() {
 fn shadowing_shows_single_completion() {
     cov_mark::check!(shadowing_shows_single_completion);
 
-    check(
+    check_empty(
         r#"
 fn foo() {
     let bar = 92;
@@ -503,7 +508,7 @@ fn foo() {
 
 #[test]
 fn in_macro_expr_frag() {
-    check(
+    check_empty(
         r#"
 macro_rules! m { ($e:expr) => { $e } }
 fn quux(x: i32) {
@@ -530,7 +535,7 @@ fn quux(x: i32) {
             kw while let
         "#]],
     );
-    check(
+    check_empty(
         r"
 macro_rules! m { ($e:expr) => { $e } }
 fn quux(x: i32) {
@@ -557,7 +562,7 @@ fn quux(x: i32) {
             kw while let
         "#]],
     );
-    check(
+    check_empty(
         r#"
 macro_rules! m { ($e:expr) => { $e } }
 fn quux(x: i32) {
@@ -590,7 +595,7 @@ fn quux(x: i32) {
 
 #[test]
 fn enum_qualified() {
-    check_with_base_items(
+    check(
         r#"
 impl Enum {
     type AssocType = ();
@@ -614,7 +619,7 @@ fn func() {
 
 #[test]
 fn ty_qualified_no_drop() {
-    check(
+    check_empty(
         r#"
 //- minicore: drop
 struct Foo;
@@ -631,7 +636,7 @@ fn func() {
 
 #[test]
 fn with_parens() {
-    check(
+    check_empty(
         r#"
 enum Enum {
     Variant()
@@ -652,7 +657,7 @@ fn func() {
 
 #[test]
 fn detail_impl_trait_in_return_position() {
-    check(
+    check_empty(
         r"
 //- minicore: sized
 trait Trait<T> {}
@@ -671,7 +676,7 @@ fn main() {
 
 #[test]
 fn detail_async_fn() {
-    check(
+    check_empty(
         r#"
 //- minicore: future, sized
 trait Trait<T> {}
@@ -692,7 +697,7 @@ fn main() {
 
 #[test]
 fn detail_impl_trait_in_argument_position() {
-    check(
+    check_empty(
         r"
 //- minicore: sized
 trait Trait<T> {}
@@ -712,7 +717,7 @@ fn main() {
 
 #[test]
 fn complete_record_expr_path() {
-    check_with_base_items(
+    check(
         r#"
 struct Zulu;
 impl Zulu {
@@ -733,7 +738,7 @@ fn main() {
 
 #[test]
 fn variant_with_struct() {
-    check(
+    check_empty(
         r#"
 pub struct YoloVariant {
     pub f: usize
@@ -808,7 +813,7 @@ fn return_value_no_block() {
 
 #[test]
 fn else_completion_after_if() {
-    check(
+    check_empty(
         r#"
 fn foo() { if foo {} $0 }
 "#,
@@ -849,7 +854,7 @@ fn foo() { if foo {} $0 }
             sn ppd
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { if foo {} el$0 }
 "#,
@@ -890,7 +895,7 @@ fn foo() { if foo {} el$0 }
             sn ppd
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { bar(if foo {} $0) }
 "#,
@@ -914,7 +919,7 @@ fn foo() { bar(if foo {} $0) }
             kw while let
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { bar(if foo {} el$0) }
 "#,
@@ -938,7 +943,7 @@ fn foo() { bar(if foo {} el$0) }
             kw while let
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { if foo {} $0 let x = 92; }
 "#,
@@ -979,7 +984,7 @@ fn foo() { if foo {} $0 let x = 92; }
             sn ppd
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { if foo {} el$0 let x = 92; }
 "#,
@@ -1020,7 +1025,7 @@ fn foo() { if foo {} el$0 let x = 92; }
             sn ppd
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() { if foo {} el$0 { let x = 92; } }
 "#,
@@ -1065,7 +1070,7 @@ fn foo() { if foo {} el$0 { let x = 92; } }
 
 #[test]
 fn expr_no_unstable_item_on_stable() {
-    check(
+    check_empty(
         r#"
 //- /main.rs crate:main deps:std
 use std::*;
@@ -1116,7 +1121,7 @@ pub struct UnstableThisShouldNotBeListed;
 
 #[test]
 fn expr_unstable_item_on_nightly() {
-    check(
+    check_empty(
         r#"
 //- toolchain:nightly
 //- /main.rs crate:main deps:std
@@ -1169,7 +1174,7 @@ pub struct UnstableButWeAreOnNightlyAnyway;
 
 #[test]
 fn inside_format_args_completions_work() {
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1195,7 +1200,7 @@ fn main() {
             sn unsafe    unsafe {}
         "#]],
     );
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1225,7 +1230,7 @@ fn main() {
 
 #[test]
 fn inside_faulty_format_args_completions_work() {
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1251,7 +1256,7 @@ fn main() {
             sn unsafe    unsafe {}
         "#]],
     );
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1277,7 +1282,7 @@ fn main() {
             sn unsafe    unsafe {}
         "#]],
     );
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1303,7 +1308,7 @@ fn main() {
             sn unsafe    unsafe {}
         "#]],
     );
-    check(
+    check_empty(
         r#"
 //- minicore: fmt
 struct Foo;
@@ -1335,7 +1340,7 @@ fn main() {
 
 #[test]
 fn macro_that_ignores_completion_marker() {
-    check_with_base_items(
+    check(
         r#"
 macro_rules! helper {
     ($v:ident) => {};
@@ -1783,7 +1788,7 @@ fn foo<T: ExcludedTrait>() {
 
 #[test]
 fn hide_ragennew_synthetic_identifiers() {
-    check(
+    check_empty(
         r#"
 //- minicore: iterator
 fn bar() {
diff --git a/crates/ide-completion/src/tests/fn_param.rs b/crates/ide-completion/src/tests/fn_param.rs
index 451ce07c74..4a89f874e1 100644
--- a/crates/ide-completion/src/tests/fn_param.rs
+++ b/crates/ide-completion/src/tests/fn_param.rs
@@ -1,6 +1,16 @@
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_with_trigger_character};
+use crate::tests::{completion_list, completion_list_with_trigger_character};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual);
+}
+
+fn check_with_trigger_character(ra_fixture: &str, trigger_character: char, expect: Expect) {
+    let actual = completion_list_with_trigger_character(ra_fixture, Some(trigger_character));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn only_param() {
@@ -114,7 +124,7 @@ fn trigger_by_l_paren() {
         r#"
 fn foo($0)
 "#,
-        Some('('),
+        '(',
         expect![[]],
     )
 }
diff --git a/crates/ide-completion/src/tests/item.rs b/crates/ide-completion/src/tests/item.rs
index bea6d60769..79561a0419 100644
--- a/crates/ide-completion/src/tests/item.rs
+++ b/crates/ide-completion/src/tests/item.rs
@@ -2,13 +2,20 @@
 //!
 //! Except for use items which are tested in [super::use_tree] and mod declarations with are tested
 //! in [crate::completions::mod_].
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check_edit, check_with_base_items};
+use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+
+use super::check_edit;
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn target_type_or_trait_in_impl_block() {
-    check_with_base_items(
+    check(
         r#"
 impl Tra$0
 "#,
@@ -30,7 +37,7 @@ impl Tra$0
 
 #[test]
 fn target_type_in_trait_impl_block() {
-    check_with_base_items(
+    check(
         r#"
 impl Trait for Str$0
 "#,
@@ -52,7 +59,7 @@ impl Trait for Str$0
 
 #[test]
 fn after_trait_name_in_trait_def() {
-    check_with_base_items(
+    check(
         r"trait A $0",
         expect![[r#"
             kw where
@@ -62,21 +69,21 @@ fn after_trait_name_in_trait_def() {
 
 #[test]
 fn after_target_name_in_impl() {
-    check_with_base_items(
+    check(
         r"impl Trait $0",
         expect![[r#"
             kw for
             kw where
         "#]],
     );
-    check_with_base_items(
+    check(
         r"impl Trait f$0",
         expect![[r#"
             kw for
             kw where
         "#]],
     );
-    check_with_base_items(
+    check(
         r"impl Trait for Type $0",
         expect![[r#"
             kw where
@@ -86,44 +93,44 @@ fn after_target_name_in_impl() {
 
 #[test]
 fn completes_where() {
-    check_with_base_items(
+    check(
         r"struct Struct $0",
         expect![[r#"
         kw where
     "#]],
     );
-    check_with_base_items(
+    check(
         r"struct Struct $0 {}",
         expect![[r#"
         kw where
     "#]],
     );
     // FIXME: This shouldn't be completed here
-    check_with_base_items(
+    check(
         r"struct Struct $0 ()",
         expect![[r#"
         kw where
     "#]],
     );
-    check_with_base_items(
+    check(
         r"fn func() $0",
         expect![[r#"
         kw where
     "#]],
     );
-    check_with_base_items(
+    check(
         r"enum Enum $0",
         expect![[r#"
         kw where
     "#]],
     );
-    check_with_base_items(
+    check(
         r"enum Enum $0 {}",
         expect![[r#"
         kw where
     "#]],
     );
-    check_with_base_items(
+    check(
         r"trait Trait $0 {}",
         expect![[r#"
         kw where
@@ -133,7 +140,7 @@ fn completes_where() {
 
 #[test]
 fn before_record_field() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo {
     $0
@@ -237,7 +244,7 @@ impl Copy for S where $0
 
 #[test]
 fn test_is_not_considered_macro() {
-    check_with_base_items(
+    check(
         r#"
 #[rustc_builtin]
 pub macro test($item:item) {
diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs
index 841c42123a..d3d52dc6df 100644
--- a/crates/ide-completion/src/tests/item_list.rs
+++ b/crates/ide-completion/src/tests/item_list.rs
@@ -1,11 +1,16 @@
 //! Completion tests for item list position.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_edit, check_with_base_items};
+use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn in_mod_item_list() {
-    check_with_base_items(
+    check(
         r#"mod tests { $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -38,7 +43,7 @@ fn in_mod_item_list() {
 
 #[test]
 fn in_source_file_item_list() {
-    check_with_base_items(
+    check(
         r#"$0"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -71,7 +76,7 @@ fn in_source_file_item_list() {
 
 #[test]
 fn in_item_list_after_attr() {
-    check_with_base_items(
+    check(
         r#"#[attr] $0"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -104,7 +109,7 @@ fn in_item_list_after_attr() {
 
 #[test]
 fn in_qualified_path() {
-    check_with_base_items(
+    check(
         r#"crate::$0"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -115,7 +120,7 @@ fn in_qualified_path() {
 
 #[test]
 fn after_unsafe_token() {
-    check_with_base_items(
+    check(
         r#"unsafe $0"#,
         expect![[r#"
             kw async
@@ -129,7 +134,7 @@ fn after_unsafe_token() {
 
 #[test]
 fn after_async_token() {
-    check_with_base_items(
+    check(
         r#"async $0"#,
         expect![[r#"
             kw fn
@@ -140,7 +145,7 @@ fn after_async_token() {
 
 #[test]
 fn after_visibility() {
-    check_with_base_items(
+    check(
         r#"pub $0"#,
         expect![[r#"
             kw async
@@ -162,7 +167,7 @@ fn after_visibility() {
 
 #[test]
 fn after_visibility_unsafe() {
-    check_with_base_items(
+    check(
         r#"pub unsafe $0"#,
         expect![[r#"
             kw async
@@ -174,7 +179,7 @@ fn after_visibility_unsafe() {
 
 #[test]
 fn in_impl_assoc_item_list() {
-    check_with_base_items(
+    check(
         r#"impl Struct { $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -194,7 +199,7 @@ fn in_impl_assoc_item_list() {
 
 #[test]
 fn in_impl_assoc_item_list_after_attr() {
-    check_with_base_items(
+    check(
         r#"impl Struct { #[attr] $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -214,7 +219,7 @@ fn in_impl_assoc_item_list_after_attr() {
 
 #[test]
 fn in_trait_assoc_item_list() {
-    check_with_base_items(
+    check(
         r"trait Foo { $0 }",
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -232,7 +237,7 @@ fn in_trait_assoc_item_list() {
 
 #[test]
 fn in_trait_assoc_fn_missing_body() {
-    check_with_base_items(
+    check(
         r#"trait Foo { fn function(); $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -250,7 +255,7 @@ fn in_trait_assoc_fn_missing_body() {
 
 #[test]
 fn in_trait_assoc_const_missing_body() {
-    check_with_base_items(
+    check(
         r#"trait Foo { const CONST: (); $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -268,7 +273,7 @@ fn in_trait_assoc_const_missing_body() {
 
 #[test]
 fn in_trait_assoc_type_aliases_missing_ty() {
-    check_with_base_items(
+    check(
         r#"trait Foo { type Type; $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -286,7 +291,7 @@ fn in_trait_assoc_type_aliases_missing_ty() {
 
 #[test]
 fn in_trait_impl_assoc_item_list() {
-    check_with_base_items(
+    check(
         r#"
 trait Test {
     type Type0;
@@ -321,7 +326,7 @@ impl Test for () {
 
 #[test]
 fn in_trait_impl_no_unstable_item_on_stable() {
-    check(
+    check_empty(
         r#"
 trait Test {
     #[unstable]
@@ -345,7 +350,7 @@ impl Test for () {
 
 #[test]
 fn in_trait_impl_unstable_item_on_nightly() {
-    check(
+    check_empty(
         r#"
 //- toolchain:nightly
 trait Test {
@@ -373,7 +378,7 @@ impl Test for () {
 
 #[test]
 fn after_unit_struct() {
-    check_with_base_items(
+    check(
         r#"struct S; f$0"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -495,7 +500,7 @@ type O = $0;
 #[test]
 fn inside_extern_blocks() {
     // Should suggest `fn`, `static`, `unsafe`
-    check_with_base_items(
+    check(
         r#"extern { $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -512,7 +517,7 @@ fn inside_extern_blocks() {
     );
 
     // Should suggest `fn`, `static`, `safe`, `unsafe`
-    check_with_base_items(
+    check(
         r#"unsafe extern { $0 }"#,
         expect![[r#"
             ma makro!(…) macro_rules! makro
@@ -529,7 +534,7 @@ fn inside_extern_blocks() {
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"unsafe extern { pub safe $0 }"#,
         expect![[r#"
             kw fn
@@ -537,7 +542,7 @@ fn inside_extern_blocks() {
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"unsafe extern { pub unsafe $0 }"#,
         expect![[r#"
             kw fn
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index 9ec27252fd..2f1f555e52 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -1,11 +1,16 @@
 //! Completion tests for pattern position.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_edit, check_with_base_items};
+use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn wildcard() {
-    check_with_base_items(
+    check(
         r#"
 fn quux() {
     let _$0
@@ -17,7 +22,7 @@ fn quux() {
 
 #[test]
 fn ident_rebind_pat() {
-    check(
+    check_empty(
         r#"
 fn quux() {
     let en$0 @ x
@@ -32,7 +37,7 @@ fn quux() {
 
 #[test]
 fn ident_ref_pat() {
-    check(
+    check_empty(
         r#"
 fn quux() {
     let ref en$0
@@ -42,7 +47,7 @@ fn quux() {
             kw mut
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn quux() {
     let ref en$0 @ x
@@ -56,7 +61,7 @@ fn quux() {
 
 #[test]
 fn ident_ref_mut_pat() {
-    check(
+    check_empty(
         r#"
 fn quux() {
     let ref mut en$0
@@ -64,7 +69,7 @@ fn quux() {
 "#,
         expect![[r#""#]],
     );
-    check(
+    check_empty(
         r#"
 fn quux() {
     let ref mut en$0 @ x
@@ -76,7 +81,7 @@ fn quux() {
 
 #[test]
 fn ref_pat() {
-    check(
+    check_empty(
         r#"
 fn quux() {
     let &en$0
@@ -86,7 +91,7 @@ fn quux() {
             kw mut
         "#]],
     );
-    check(
+    check_empty(
         r#"
 fn quux() {
     let &mut en$0
@@ -94,7 +99,7 @@ fn quux() {
 "#,
         expect![[r#""#]],
     );
-    check(
+    check_empty(
         r#"
 fn foo() {
     for &$0 in () {}
@@ -108,7 +113,7 @@ fn foo() {
 
 #[test]
 fn refutable() {
-    check_with_base_items(
+    check(
         r#"
 fn foo() {
     if let a$0
@@ -134,7 +139,7 @@ fn foo() {
 
 #[test]
 fn irrefutable() {
-    check_with_base_items(
+    check(
         r#"
 enum SingleVariantEnum {
     Variant
@@ -163,7 +168,7 @@ fn foo() {
 
 #[test]
 fn in_param() {
-    check_with_base_items(
+    check(
         r#"
 fn foo(a$0) {
 }
@@ -180,7 +185,7 @@ fn foo(a$0) {
             kw ref
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 fn foo(a$0: Tuple) {
 }
@@ -202,7 +207,7 @@ fn foo(a$0: Tuple) {
 
 #[test]
 fn only_fn_like_macros() {
-    check(
+    check_empty(
         r#"
 macro_rules! m { ($e:expr) => { $e } }
 
@@ -223,7 +228,7 @@ fn foo() {
 
 #[test]
 fn in_simple_macro_call() {
-    check(
+    check_empty(
         r#"
 macro_rules! m { ($e:expr) => { $e } }
 enum E { X }
@@ -244,7 +249,7 @@ fn foo() {
 
 #[test]
 fn omits_private_fields_pat() {
-    check(
+    check_empty(
         r#"
 mod foo {
     pub struct Record { pub field: i32, _field: i32 }
@@ -272,7 +277,7 @@ fn outer() {
 
 #[test]
 fn completes_self_pats() {
-    check(
+    check_empty(
         r#"
 struct Foo(i32);
 impl Foo {
@@ -296,7 +301,7 @@ impl Foo {
 
 #[test]
 fn enum_qualified() {
-    check_with_base_items(
+    check(
         r#"
 impl Enum {
     type AssocType = ();
@@ -318,7 +323,7 @@ fn func() {
 
 #[test]
 fn completes_in_record_field_pat() {
-    check(
+    check_empty(
         r#"
 struct Foo { bar: Bar }
 struct Bar(u32);
@@ -337,7 +342,7 @@ fn outer(Foo { bar: $0 }: Foo) {}
 
 #[test]
 fn skips_in_record_field_pat_name() {
-    check(
+    check_empty(
         r#"
 struct Foo { bar: Bar }
 struct Bar(u32);
@@ -352,7 +357,7 @@ fn outer(Foo { bar$0 }: Foo) {}
 
 #[test]
 fn completes_in_record_field_pat_with_generic_type_alias() {
-    check(
+    check_empty(
         r#"
 type Wrap<T> = T;
 
@@ -381,7 +386,7 @@ fn main() {
 
 #[test]
 fn completes_in_fn_param() {
-    check(
+    check_empty(
         r#"
 struct Foo { bar: Bar }
 struct Bar(u32);
@@ -400,7 +405,7 @@ fn foo($0) {}
 
 #[test]
 fn completes_in_closure_param() {
-    check(
+    check_empty(
         r#"
 struct Foo { bar: Bar }
 struct Bar(u32);
@@ -421,7 +426,7 @@ fn foo() {
 
 #[test]
 fn completes_no_delims_if_existing() {
-    check(
+    check_empty(
         r#"
 struct Bar(u32);
 fn foo() {
@@ -436,7 +441,7 @@ fn foo() {
             kw self::
         "#]],
     );
-    check(
+    check_empty(
         r#"
 struct Foo { bar: u32 }
 fn foo() {
@@ -451,7 +456,7 @@ fn foo() {
             kw self::
         "#]],
     );
-    check(
+    check_empty(
         r#"
 enum Enum {
     TupleVariant(u32)
@@ -466,7 +471,7 @@ fn foo() {
             bn TupleVariant TupleVariant
         "#]],
     );
-    check(
+    check_empty(
         r#"
 enum Enum {
     RecordVariant { field: u32 }
@@ -514,7 +519,7 @@ fn foo() {
 #[test]
 fn completes_enum_variant_pat_escape() {
     cov_mark::check!(enum_variant_pattern_path);
-    check(
+    check_empty(
         r#"
 enum Enum {
     A,
@@ -539,7 +544,7 @@ fn foo() {
         "#]],
     );
 
-    check(
+    check_empty(
         r#"
 enum Enum {
     A,
@@ -564,7 +569,7 @@ fn foo() {
 
 #[test]
 fn completes_associated_const() {
-    check(
+    check_empty(
         r#"
 #[derive(PartialEq, Eq)]
 struct Ty(u8);
@@ -585,7 +590,7 @@ fn f(t: Ty) {
         "#]],
     );
 
-    check(
+    check_empty(
         r#"
 enum MyEnum {}
 
@@ -607,7 +612,7 @@ fn f(e: MyEnum) {
         "#]],
     );
 
-    check(
+    check_empty(
         r#"
 union U {
     i: i32,
@@ -632,7 +637,7 @@ fn f(u: U) {
         "#]],
     );
 
-    check(
+    check_empty(
         r#"
 #![rustc_coherence_is_core]
 #[lang = "u32"]
@@ -654,7 +659,7 @@ fn f(v: u32) {
 
 #[test]
 fn in_method_param() {
-    check(
+    check_empty(
         r#"
 struct Ty(u8);
 
@@ -675,7 +680,7 @@ impl Ty {
             kw ref
         "#]],
     );
-    check(
+    check_empty(
         r#"
 struct Ty(u8);
 
@@ -696,7 +701,7 @@ impl Ty {
             kw ref
         "#]],
     );
-    check(
+    check_empty(
         r#"
 struct Ty(u8);
 
@@ -717,7 +722,7 @@ impl Ty {
             kw ref
         "#]],
     );
-    check(
+    check_empty(
         r#"
 struct Ty(u8);
 
@@ -738,7 +743,7 @@ impl Ty {
 
 #[test]
 fn through_alias() {
-    check(
+    check_empty(
         r#"
 enum Enum<T> {
     Unit,
@@ -765,7 +770,7 @@ fn f(x: EnumAlias<u8>) {
 
 #[test]
 fn pat_no_unstable_item_on_stable() {
-    check(
+    check_empty(
         r#"
 //- /main.rs crate:main deps:std
 use std::*;
@@ -790,7 +795,7 @@ pub enum Enum {
 
 #[test]
 fn pat_unstable_item_on_nightly() {
-    check(
+    check_empty(
         r#"
 //- toolchain:nightly
 //- /main.rs crate:main deps:std
@@ -903,7 +908,7 @@ fn foo() {
     );
 
     // Do not suggest reserved keywords
-    check(
+    check_empty(
         r#"
 struct Struct;
 
@@ -921,7 +926,7 @@ fn foo() {
 
 #[test]
 fn private_item_in_module_in_function_body() {
-    check(
+    check_empty(
         r#"
 fn main() {
     mod foo {
diff --git a/crates/ide-completion/src/tests/predicate.rs b/crates/ide-completion/src/tests/predicate.rs
index 65036f6a22..c1926359ef 100644
--- a/crates/ide-completion/src/tests/predicate.rs
+++ b/crates/ide-completion/src/tests/predicate.rs
@@ -1,12 +1,17 @@
 //! Completion tests for predicates and bounds.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_with_base_items};
+use crate::tests::{check_empty, completion_list, BASE_ITEMS_FIXTURE};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn predicate_start() {
     // FIXME: `for` kw
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> where $0 {}
 "#,
@@ -29,7 +34,7 @@ struct Foo<'lt, T, const C: usize> where $0 {}
 
 #[test]
 fn bound_for_type_pred() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> where T: $0 {}
 "#,
@@ -47,7 +52,7 @@ struct Foo<'lt, T, const C: usize> where T: $0 {}
 fn bound_for_lifetime_pred() {
     // FIXME: should only show lifetimes here, that is we shouldn't get any completions here when not typing
     // a `'`
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
 "#,
@@ -63,7 +68,7 @@ struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
 
 #[test]
 fn bound_for_for_pred() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
 "#,
@@ -79,7 +84,7 @@ struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
 
 #[test]
 fn param_list_for_for_pred() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
 "#,
@@ -102,7 +107,7 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
 
 #[test]
 fn pred_on_fn_in_impl() {
-    check_with_base_items(
+    check(
         r#"
 impl Record {
     fn method(self) where $0 {}
@@ -127,7 +132,7 @@ impl Record {
 
 #[test]
 fn pred_no_unstable_item_on_stable() {
-    check(
+    check_empty(
         r#"
 //- /main.rs crate:main deps:std
 use std::*;
@@ -146,7 +151,7 @@ pub trait Trait {}
 
 #[test]
 fn pred_unstable_item_on_nightly() {
-    check(
+    check_empty(
         r#"
 //- toolchain:nightly
 //- /main.rs crate:main deps:std
diff --git a/crates/ide-completion/src/tests/proc_macros.rs b/crates/ide-completion/src/tests/proc_macros.rs
index 6b1dfe366c..afc286b6fb 100644
--- a/crates/ide-completion/src/tests/proc_macros.rs
+++ b/crates/ide-completion/src/tests/proc_macros.rs
@@ -1,7 +1,12 @@
 //! Completion tests for expressions.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::check;
+use crate::tests::completion_list;
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn complete_dot_in_attr() {
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index a1013b8654..a9c9f604e0 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -1,9 +1,14 @@
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::check;
+use crate::tests::completion_list;
 
 use super::check_edit;
 
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual);
+}
+
 #[test]
 fn without_default_impl() {
     check(
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
index 2b05184bdb..6cfb2231a9 100644
--- a/crates/ide-completion/src/tests/special.rs
+++ b/crates/ide-completion/src/tests/special.rs
@@ -5,12 +5,32 @@ use ide_db::SymbolKind;
 
 use crate::{
     tests::{
-        check, check_edit, check_no_kw, check_with_trigger_character, do_completion_with_config,
-        TEST_CONFIG,
+        check_edit, completion_list, completion_list_no_kw, completion_list_with_trigger_character,
     },
     CompletionItemKind,
 };
 
+use super::{do_completion_with_config, TEST_CONFIG};
+
+fn check_no_kw(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list_no_kw(ra_fixture);
+    expect.assert_eq(&actual)
+}
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual)
+}
+
+pub(crate) fn check_with_trigger_character(
+    ra_fixture: &str,
+    trigger_character: Option<char>,
+    expect: Expect,
+) {
+    let actual = completion_list_with_trigger_character(ra_fixture, trigger_character);
+    expect.assert_eq(&actual)
+}
+
 #[test]
 fn completes_if_prefix_is_keyword() {
     check_edit(
diff --git a/crates/ide-completion/src/tests/type_pos.rs b/crates/ide-completion/src/tests/type_pos.rs
index c7e2d05825..9ea262bcc5 100644
--- a/crates/ide-completion/src/tests/type_pos.rs
+++ b/crates/ide-completion/src/tests/type_pos.rs
@@ -1,11 +1,16 @@
 //! Completion tests for type position.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_with_base_items};
+use crate::tests::{check_empty, completion_list, BASE_ITEMS_FIXTURE};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}"));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn record_field_ty() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize> {
     f: $0
@@ -32,7 +37,7 @@ struct Foo<'lt, T, const C: usize> {
 
 #[test]
 fn tuple_struct_field() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<'lt, T, const C: usize>(f$0);
 "#,
@@ -60,7 +65,7 @@ struct Foo<'lt, T, const C: usize>(f$0);
 
 #[test]
 fn fn_return_type() {
-    check_with_base_items(
+    check(
         r#"
 fn x<'lt, T, const C: usize>() -> $0
 "#,
@@ -83,7 +88,7 @@ fn x<'lt, T, const C: usize>() -> $0
 
 #[test]
 fn fn_return_type_no_local_items() {
-    check_with_base_items(
+    check(
         r#"
 fn foo() -> B$0 {
     struct Bar;
@@ -113,7 +118,7 @@ fn foo() -> B$0 {
 
 #[test]
 fn inferred_type_const() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<T>(T);
 const FOO: $0 = Foo(2);
@@ -138,7 +143,7 @@ const FOO: $0 = Foo(2);
 
 #[test]
 fn inferred_type_closure_param() {
-    check_with_base_items(
+    check(
         r#"
 fn f1(f: fn(i32) -> i32) {}
 fn f2() {
@@ -164,7 +169,7 @@ fn f2() {
 
 #[test]
 fn inferred_type_closure_return() {
-    check_with_base_items(
+    check(
         r#"
 fn f1(f: fn(u64) -> u64) {}
 fn f2() {
@@ -192,7 +197,7 @@ fn f2() {
 
 #[test]
 fn inferred_type_fn_return() {
-    check_with_base_items(
+    check(
         r#"
 fn f2(x: u64) -> $0 {
     x + 5
@@ -217,7 +222,7 @@ fn f2(x: u64) -> $0 {
 
 #[test]
 fn inferred_type_fn_param() {
-    check_with_base_items(
+    check(
         r#"
 fn f1(x: i32) {}
 fn f2(x: $0) {
@@ -243,7 +248,7 @@ fn f2(x: $0) {
 
 #[test]
 fn inferred_type_not_in_the_scope() {
-    check_with_base_items(
+    check(
         r#"
 mod a {
     pub struct Foo<T>(T);
@@ -277,7 +282,7 @@ fn foo<'lt, T, const C: usize>() {
 
 #[test]
 fn inferred_type_let() {
-    check_with_base_items(
+    check(
         r#"
 struct Foo<T>(T);
 fn foo<'lt, T, const C: usize>() {
@@ -306,7 +311,7 @@ fn foo<'lt, T, const C: usize>() {
 
 #[test]
 fn body_type_pos() {
-    check_with_base_items(
+    check(
         r#"
 fn foo<'lt, T, const C: usize>() {
     let local = ();
@@ -328,7 +333,7 @@ fn foo<'lt, T, const C: usize>() {
             kw self::
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 fn foo<'lt, T, const C: usize>() {
     let local = ();
@@ -351,7 +356,7 @@ fn foo<'lt, T, const C: usize>() {
 #[test]
 fn completes_types_and_const_in_arg_list() {
     cov_mark::check!(complete_assoc_type_in_generics_list);
-    check_with_base_items(
+    check(
         r#"
 trait Trait1 {
     type Super;
@@ -367,7 +372,7 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
             ta Super =  (as Trait1) type Super
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 trait Trait1 {
     type Super;
@@ -395,7 +400,7 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
             kw self::
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 trait Trait2<T> {
     type Foo;
@@ -419,7 +424,7 @@ fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {}
 
 #[test]
 fn no_assoc_completion_outside_type_bounds() {
-    check_with_base_items(
+    check(
         r#"
 struct S;
 trait Tr<T> {
@@ -449,7 +454,7 @@ impl Tr<$0
 
 #[test]
 fn enum_qualified() {
-    check_with_base_items(
+    check(
         r#"
 impl Enum {
     type AssocType = ();
@@ -466,7 +471,7 @@ fn func(_: Enum::$0) {}
 
 #[test]
 fn completes_type_parameter_or_associated_type() {
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U> {
     type Item1;
@@ -491,7 +496,7 @@ fn f(t: impl MyTrait<u$0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U> {
     type Item1;
@@ -516,7 +521,7 @@ fn f(t: impl MyTrait<u8, u$0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U> {
     type Item1;
@@ -534,7 +539,7 @@ fn f(t: impl MyTrait<u8, u8, I$0
 
 #[test]
 fn completes_type_parameter_or_associated_type_with_default_value() {
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U = u8> {
     type Item1;
@@ -559,7 +564,7 @@ fn f(t: impl MyTrait<u$0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U = u8> {
     type Item1;
@@ -586,7 +591,7 @@ fn f(t: impl MyTrait<u8, u$0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait<T, U = u8> {
     type Item1;
@@ -604,7 +609,7 @@ fn f(t: impl MyTrait<u8, u8, I$0
 
 #[test]
 fn completes_types_after_associated_type() {
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait {
     type Item1;
@@ -629,7 +634,7 @@ fn f(t: impl MyTrait<Item1 = $0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait {
     type Item1;
@@ -654,7 +659,7 @@ fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
         "#]],
     );
 
-    check_with_base_items(
+    check(
         r#"
 trait MyTrait {
     const C: usize;
@@ -673,7 +678,7 @@ fn f(t: impl MyTrait<C = $0
 
 #[test]
 fn type_pos_no_unstable_type_on_stable() {
-    check(
+    check_empty(
         r#"
 //- /main.rs crate:main deps:std
 use std::*;
@@ -697,7 +702,7 @@ pub struct S;
 
 #[test]
 fn type_pos_unstable_type_on_nightly() {
-    check(
+    check_empty(
         r#"
 //- toolchain:nightly
 //- /main.rs crate:main deps:std
@@ -724,7 +729,7 @@ pub struct S;
 #[test]
 fn completes_const_and_type_generics_separately() {
     // Function generic params
-    check_with_base_items(
+    check(
         r#"
     struct Foo;
     const X: usize = 0;
@@ -751,7 +756,7 @@ fn completes_const_and_type_generics_separately() {
     // FIXME: This should probably also suggest completions for types, at least those that have
     // associated constants usable in this position. For example, a user could be typing
     // `foo::<_, { usize::MAX }>()`, but we currently don't suggest `usize` in constant position.
-    check_with_base_items(
+    check(
         r#"
     struct Foo;
     const X: usize = 0;
@@ -770,7 +775,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Method generic params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo;
@@ -794,7 +799,7 @@ fn completes_const_and_type_generics_separately() {
             kw self::
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo;
@@ -813,7 +818,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Associated type generic params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo;
@@ -838,7 +843,7 @@ fn completes_const_and_type_generics_separately() {
             kw self::
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo;
@@ -857,7 +862,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Type generic params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo<T, const N: usize>(T);
@@ -875,7 +880,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Type alias generic params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     struct Foo<T, const N: usize>(T);
@@ -894,7 +899,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Enum variant params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     enum Foo<T, const N: usize> { A(T), B }
@@ -912,7 +917,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Trait params
-    check_with_base_items(
+    check(
         r#"
     const X: usize = 0;
     trait Foo<T, const N: usize> {}
@@ -928,7 +933,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Trait alias params
-    check_with_base_items(
+    check(
         r#"
     #![feature(trait_alias)]
     const X: usize = 0;
@@ -946,7 +951,7 @@ fn completes_const_and_type_generics_separately() {
     );
 
     // Omitted lifetime params
-    check_with_base_items(
+    check(
         r#"
 struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
 fn foo<'a>() { S::<F$0, _>; }
@@ -959,7 +964,7 @@ fn foo<'a>() { S::<F$0, _>; }
         "#]],
     );
     // Explicit lifetime params
-    check_with_base_items(
+    check(
         r#"
 struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
 fn foo<'a>() { S::<'static, 'static, F$0, _>; }
@@ -971,7 +976,7 @@ fn foo<'a>() { S::<'static, 'static, F$0, _>; }
             kw self::
         "#]],
     );
-    check_with_base_items(
+    check(
         r#"
 struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
 fn foo<'a>() { S::<'static, F$0, _, _>; }
@@ -987,7 +992,7 @@ fn foo<'a>() { S::<'static, F$0, _, _>; }
 
 #[test]
 fn complete_traits_on_impl_trait_block() {
-    check_with_base_items(
+    check(
         r#"
 trait Foo {}
 
@@ -1007,7 +1012,7 @@ impl $0 for Bar { }
 
 #[test]
 fn complete_traits_with_path_on_impl_trait_block() {
-    check_with_base_items(
+    check(
         r#"
 mod outer {
     pub trait Foo {}
diff --git a/crates/ide-completion/src/tests/use_tree.rs b/crates/ide-completion/src/tests/use_tree.rs
index 04b3a47a64..2ea2e4e4c9 100644
--- a/crates/ide-completion/src/tests/use_tree.rs
+++ b/crates/ide-completion/src/tests/use_tree.rs
@@ -1,7 +1,12 @@
 //! Completion tests for use trees.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::check;
+use crate::tests::completion_list;
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn use_tree_completion() {
diff --git a/crates/ide-completion/src/tests/visibility.rs b/crates/ide-completion/src/tests/visibility.rs
index 4b5a0ac1c2..c18d6e66dd 100644
--- a/crates/ide-completion/src/tests/visibility.rs
+++ b/crates/ide-completion/src/tests/visibility.rs
@@ -1,7 +1,17 @@
 //! Completion tests for visibility modifiers.
-use expect_test::expect;
+use expect_test::{expect, Expect};
 
-use crate::tests::{check, check_with_trigger_character};
+use crate::tests::{completion_list, completion_list_with_trigger_character};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let actual = completion_list(ra_fixture);
+    expect.assert_eq(&actual)
+}
+
+fn check_with_trigger_character(ra_fixture: &str, trigger_character: char, expect: Expect) {
+    let actual = completion_list_with_trigger_character(ra_fixture, Some(trigger_character));
+    expect.assert_eq(&actual)
+}
 
 #[test]
 fn empty_pub() {
@@ -10,7 +20,7 @@ fn empty_pub() {
         r#"
 pub($0)
 "#,
-        Some('('),
+        '(',
         expect![[r#"
             kw crate
             kw in