Repository: rust-lang/rust-analyzer
Pull request #13056 (2022-08-18 18:49:25)

internal: Migrate to using format arg captures in `syntax::make`


Patch:
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs
index c22945c81f..2bebea2fbf 100644
--- a/crates/flycheck/src/lib.rs
+++ b/crates/flycheck/src/lib.rs
@@ -77,13 +77,8 @@ impl FlycheckHandle {
     }
 
     /// Schedule a re-start of the cargo check worker.
-    pub fn restart(&self) {
-        self.sender.send(Restart::Yes).unwrap();
-    }
-
-    /// Stop this cargo check worker.
-    pub fn cancel(&self) {
-        self.sender.send(Restart::No).unwrap();
+    pub fn update(&self) {
+        self.sender.send(Restart).unwrap();
     }
 
     pub fn id(&self) -> usize {
@@ -127,10 +122,7 @@ pub enum Progress {
     DidCancel,
 }
 
-enum Restart {
-    Yes,
-    No,
-}
+struct Restart;
 
 struct FlycheckActor {
     id: usize,
@@ -157,7 +149,6 @@ impl FlycheckActor {
         config: FlycheckConfig,
         workspace_root: AbsPathBuf,
     ) -> FlycheckActor {
-        tracing::info!(%id, ?workspace_root, "Spawning flycheck");
         FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
     }
     fn progress(&self, progress: Progress) {
@@ -173,13 +164,10 @@ impl FlycheckActor {
     fn run(mut self, inbox: Receiver<Restart>) {
         while let Some(event) = self.next_event(&inbox) {
             match event {
-                Event::Restart(Restart::No) => {
-                    self.cancel_check_process();
-                }
-                Event::Restart(Restart::Yes) => {
+                Event::Restart(Restart) => {
                     // Cancel the previously spawned process
                     self.cancel_check_process();
-                    while let Ok(_) = inbox.recv_timeout(Duration::from_millis(50)) {}
+                    while let Ok(Restart) = inbox.recv_timeout(Duration::from_millis(50)) {}
 
                     let command = self.check_command();
                     tracing::debug!(?command, "will restart flycheck");
@@ -235,10 +223,6 @@ impl FlycheckActor {
 
     fn cancel_check_process(&mut self) {
         if let Some(cargo_handle) = self.cargo_handle.take() {
-            tracing::debug!(
-                command = ?self.check_command(),
-                "did  cancel flycheck"
-            );
             cargo_handle.cancel();
             self.progress(Progress::DidCancel);
         }
diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs
index d7586d129b..d0f73ec820 100644
--- a/crates/hir-expand/src/mod_path.rs
+++ b/crates/hir-expand/src/mod_path.rs
@@ -257,7 +257,6 @@ macro_rules! __known_path {
     (core::ops::RangeToInclusive) => {};
     (core::ops::RangeInclusive) => {};
     (core::future::Future) => {};
-    (core::future::IntoFuture) => {};
     (core::ops::Try) => {};
     ($path:path) => {
         compile_error!("Please register your known path in the path module")
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 2b859f7750..a1bb353374 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -266,7 +266,6 @@ pub mod known {
         Try,
         Ok,
         Future,
-        IntoFuture,
         Result,
         Option,
         Output,
@@ -400,7 +399,6 @@ pub mod known {
         future_trait,
         index,
         index_mut,
-        into_future,
         mul_assign,
         mul,
         neg,
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 5df48e5fdc..46eeea0e6f 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -734,7 +734,6 @@ impl<'a> InferenceContext<'a> {
                         let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
                         return (ty, Some(strukt.into()));
                     }
-                    ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
                     _ => return (self.err_ty(), None),
                 },
                 Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
@@ -876,10 +875,7 @@ impl<'a> InferenceContext<'a> {
     }
 
     fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
-        let trait_ = self
-            .resolver
-            .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture])
-            .or_else(|| self.resolve_lang_item(name![future_trait])?.as_trait())?;
+        let trait_ = self.resolve_lang_item(name![future_trait])?.as_trait()?;
         self.db.trait_data(trait_).associated_type_by_name(&name![Output])
     }
 
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index ae115c8c0d..239f66bcb7 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -238,7 +238,18 @@ impl<'a> TyLoweringContext<'a> {
                 })
                 .intern(Interner)
             }
-            TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
+            TypeRef::DynTrait(bounds) => {
+                let self_ty =
+                    TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
+                let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+                    QuantifiedWhereClauses::from_iter(
+                        Interner,
+                        bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
+                    )
+                });
+                let bounds = crate::make_single_type_binders(bounds);
+                TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
+            }
             TypeRef::ImplTrait(bounds) => {
                 match self.impl_trait_mode {
                     ImplTraitLoweringMode::Opaque => {
@@ -457,10 +468,29 @@ impl<'a> TyLoweringContext<'a> {
                         }
                     }
                     0 => {
-                        // Trait object type without dyn; this should be handled in upstream. See
-                        // `lower_path()`.
-                        stdx::never!("unexpected fully resolved trait path");
-                        TyKind::Error.intern(Interner)
+                        let self_ty = Some(
+                            TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
+                                .intern(Interner),
+                        );
+                        let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+                            ctx.lower_trait_ref_from_resolved_path(
+                                trait_,
+                                resolved_segment,
+                                self_ty,
+                            )
+                        });
+                        let dyn_ty = DynTy {
+                            bounds: crate::make_single_type_binders(
+                                QuantifiedWhereClauses::from_iter(
+                                    Interner,
+                                    Some(crate::wrap_empty_binders(WhereClause::Implemented(
+                                        trait_ref,
+                                    ))),
+                                ),
+                            ),
+                            lifetime: static_lifetime(),
+                        };
+                        TyKind::Dyn(dyn_ty).intern(Interner)
                     }
                     _ => {
                         // FIXME report error (ambiguous associated type)
@@ -525,20 +555,11 @@ impl<'a> TyLoweringContext<'a> {
             let (ty, res) = self.lower_ty_ext(type_ref);
             return self.lower_ty_relative_path(ty, res, path.segments());
         }
-
         let (resolution, remaining_index) =
             match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
                 Some(it) => it,
                 None => return (TyKind::Error.intern(Interner), None),
             };
-
-        if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
-            // trait object type without dyn
-            let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
-            let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
-            return (ty, None);
-        }
-
         let (resolved_segment, remaining_segments) = match remaining_index {
             None => (
                 path.segments().last().expect("resolved path has at least one element"),
@@ -966,18 +987,6 @@ impl<'a> TyLoweringContext<'a> {
             })
     }
 
-    fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
-        let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
-        let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
-            QuantifiedWhereClauses::from_iter(
-                Interner,
-                bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
-            )
-        });
-        let bounds = crate::make_single_type_binders(bounds);
-        TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
-    }
-
     fn lower_impl_trait(
         &self,
         bounds: &[Interned<TypeBound>],
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index aa019ca483..3561bdeba7 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2778,32 +2778,20 @@ impl Type {
         self.ty.is_unknown()
     }
 
-    /// Checks that particular type `ty` implements `std::future::IntoFuture` or
-    /// `std::future::Future`.
+    /// Checks that particular type `ty` implements `std::future::Future`.
     /// This function is used in `.await` syntax completion.
-    pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool {
-        let trait_ = db
-            .lang_item(self.env.krate, SmolStr::new_inline("into_future"))
-            .and_then(|it| {
-                let into_future_fn = it.as_function()?;
-                let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
-                let into_future_trait = assoc_item.containing_trait_or_trait_impl(db)?;
-                Some(into_future_trait.id)
-            })
-            .or_else(|| {
-                let future_trait =
-                    db.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))?;
-                future_trait.as_trait()
-            });
-
-        let trait_ = match trait_ {
+    pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
+        let std_future_trait = db
+            .lang_item(self.env.krate, SmolStr::new_inline("future_trait"))
+            .and_then(|it| it.as_trait());
+        let std_future_trait = match std_future_trait {
             Some(it) => it,
             None => return false,
         };
 
         let canonical_ty =
             Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
-        method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), trait_)
+        method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait)
     }
 
     /// Checks that particular type `ty` implements `std::ops::FnOnce`.
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index bd35af06e2..ae2896e193 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -27,7 +27,6 @@ use hir_def::{
 use hir_expand::{
     builtin_fn_macro::BuiltinFnLikeExpander,
     hygiene::Hygiene,
-    mod_path::path,
     name,
     name::{AsName, Name},
     HirFileId, InFile,
@@ -270,35 +269,14 @@ impl SourceAnalyzer {
         db: &dyn HirDatabase,
         await_expr: &ast::AwaitExpr,
     ) -> Option<FunctionId> {
-        let mut ty = self.ty_of_expr(db, &await_expr.expr()?.into())?.clone();
-
-        let into_future_trait = self
-            .resolver
-            .resolve_known_trait(db.upcast(), &path![core::future::IntoFuture])
-            .map(Trait::from);
-
-        if let Some(into_future_trait) = into_future_trait {
-            let type_ = Type::new_with_resolver(db, &self.resolver, ty.clone());
-            if type_.impls_trait(db, into_future_trait, &[]) {
-                let items = into_future_trait.items(db);
-                let into_future_type = items.into_iter().find_map(|item| match item {
-                    AssocItem::TypeAlias(alias)
-                        if alias.name(db) == hir_expand::name![IntoFuture] =>
-                    {
-                        Some(alias)
-                    }
-                    _ => None,
-                })?;
-                let future_trait = type_.normalize_trait_assoc_type(db, &[], into_future_type)?;
-                ty = future_trait.ty;
-            }
-        }
+        let ty = self.ty_of_expr(db, &await_expr.expr()?.into())?;
 
-        let poll_fn = db
+        let op_fn = db
             .lang_item(self.resolver.krate(), hir_expand::name![poll].to_smol_str())?
             .as_function()?;
-        let substs = hir_ty::TyBuilder::subst_for_def(db, poll_fn).push(ty.clone()).build();
-        Some(self.resolve_impl_method_or_trait_def(db, poll_fn, &substs))
+        let substs = hir_ty::TyBuilder::subst_for_def(db, op_fn).push(ty.clone()).build();
+
+        Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
     }
 
     pub(crate) fn resolve_prefix_expr(
diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs
index e26c76da18..d564a05408 100644
--- a/crates/ide-assists/src/handlers/generate_function.rs
+++ b/crates/ide-assists/src/handlers/generate_function.rs
@@ -61,72 +61,56 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     }
 
     let fn_name = &*name_ref.text();
-    let TargetInfo { target_module, adt_name, target, file, insert_offset } =
-        fn_target_info(ctx, path, &call, fn_name)?;
-    let function_builder = FunctionBuilder::from_call(ctx, &call, fn_name, target_module, target)?;
-    let text_range = call.syntax().text_range();
-    let label = format!("Generate {} function", function_builder.fn_name);
-    add_func_to_accumulator(
-        acc,
-        ctx,
-        text_range,
-        function_builder,
-        insert_offset,
-        file,
-        adt_name,
-        label,
-    )
-}
-
-struct TargetInfo {
-    target_module: Option<Module>,
-    adt_name: Option<hir::Name>,
-    target: GeneratedFunctionTarget,
-    file: FileId,
-    insert_offset: TextSize,
-}
+    let target_module;
+    let mut adt_name = None;
 
-impl TargetInfo {
-    fn new(
-        target_module: Option<Module>,
-        adt_name: Option<hir::Name>,
-        target: GeneratedFunctionTarget,
-        file: FileId,
-        insert_offset: TextSize,
-    ) -> Self {
-        Self { target_module, adt_name, target, file, insert_offset }
-    }
-}
-
-fn fn_target_info(
-    ctx: &AssistContext<'_>,
-    path: ast::Path,
-    call: &CallExpr,
-    fn_name: &str,
-) -> Option<TargetInfo> {
-    match path.qualifier() {
+    let (target, file, insert_offset) = match path.qualifier() {
         Some(qualifier) => match ctx.sema.resolve_path(&qualifier) {
             Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) => {
-                get_fn_target_info(ctx, &Some(module), call.clone())
+                target_module = Some(module);
+                get_fn_target(ctx, &target_module, call.clone())?
             }
             Some(hir::PathResolution::Def(hir::ModuleDef::Adt(adt))) => {
                 if let hir::Adt::Enum(_) = adt {
                     // Don't suggest generating function if the name starts with an uppercase letter
-                    if fn_name.starts_with(char::is_uppercase) {
+                    if name_ref.text().starts_with(char::is_uppercase) {
                         return None;
                     }
                 }
 
-                assoc_fn_target_info(ctx, call, adt, fn_name)
+                let current_module = ctx.sema.scope(call.syntax())?.module();
+                let module = adt.module(ctx.sema.db);
+                target_module = if current_module == module { None } else { Some(module) };
+                if current_module.krate() != module.krate() {
+                    return None;
+                }
+                let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?;
+                let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?;
+                adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
+                (target, file, insert_offset)
             }
-            Some(hir::PathResolution::SelfType(impl_)) => {
-                let adt = impl_.self_ty(ctx.db()).as_adt()?;
-                assoc_fn_target_info(ctx, call, adt, fn_name)
+            _ => {
+                return None;
             }
-            _ => None,
         },
-        _ => get_fn_target_info(ctx, &None, call.clone()),
-    }
+        _ => {
+            target_module = None;
+            get_fn_target(ctx, &target_module, call.clone())?
+        }
+    };
+    let function_builder = FunctionBuilder::from_call(ctx, &call, fn_name, target_module, target)?;
+    let text_range = call.syntax().text_range();
+    let label = format!("Generate {} function", function_builder.fn_name);
+    add_func_to_accumulator(
+        acc,
+        ctx,
+        text_range,
+        function_builder,
+        insert_offset,
+        file,
+        adt_name,
+        label,
+    )
 }
 
 fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
@@ -382,15 +366,6 @@ fn make_return_type(
     (ret_type, should_focus_return_type)
 }
 
-fn get_fn_target_info(
-    ctx: &AssistContext<'_>,
-    target_module: &Option<Module>,
-    call: CallExpr,
-) -> Option<TargetInfo> {
-    let (target, file, insert_offset) = get_fn_target(ctx, target_module, call)?;
-    Some(TargetInfo::new(*target_module, None, target, file, insert_offset))
-}
-
 fn get_fn_target(
     ctx: &AssistContext<'_>,
     target_module: &Option<Module>,
@@ -424,24 +399,6 @@ fn get_method_target(
     Some((target.clone(), get_insert_offset(&target)))
 }
 
-fn assoc_fn_target_info(
-    ctx: &AssistContext<'_>,
-    call: &CallExpr,
-    adt: hir::Adt,
-    fn_name: &str,
-) -> Option<TargetInfo> {
-    let current_module = ctx.sema.scope(call.syntax())?.module();
-    let module = adt.module(ctx.sema.db);
-    let target_module = if current_module == module { None } else { Some(module) };
-    if current_module.krate() != module.krate() {
-        return None;
-    }
-    let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?;
-    let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?;
-    let adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
-    Some(TargetInfo::new(target_module, adt_name, target, file, insert_offset))
-}
-
 fn get_insert_offset(target: &GeneratedFunctionTarget) -> TextSize {
     match &target {
         GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(),
@@ -1676,33 +1633,6 @@ fn bar() ${0:-> _} {
         )
     }
 
-    #[test]
-    fn create_static_method_within_an_impl_with_self_syntax() {
-        check_assist(
-            generate_function,
-            r"
-struct S;
-impl S {
-    fn foo(&self) {
-        Self::bar$0();
-    }
-}
-",
-            r"
-struct S;
-impl S {
-    fn foo(&self) {
-        Self::bar();
-    }
-
-    fn bar() ${0:-> _} {
-        todo!()
-    }
-}
-",
-        )
-    }
-
     #[test]
     fn no_panic_on_invalid_global_path() {
         check_assist(
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs
index b5d092e39b..80d3b92559 100644
--- a/crates/ide-assists/src/handlers/inline_call.rs
+++ b/crates/ide-assists/src/handlers/inline_call.rs
@@ -13,7 +13,7 @@ use ide_db::{
 use itertools::{izip, Itertools};
 use syntax::{
     ast::{self, edit_in_place::Indent, HasArgList, PathExpr},
-    ted, AstNode, NodeOrToken, SyntaxKind,
+    ted, AstNode,
 };
 
 use crate::{
@@ -311,13 +311,6 @@ fn inline(
     } else {
         fn_body.clone_for_update()
     };
-    if let Some(t) = body.syntax().ancestors().find_map(ast::Impl::cast).and_then(|i| i.self_ty()) {
-        body.syntax()
-            .descendants_with_tokens()
-            .filter_map(NodeOrToken::into_token)
-            .filter(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW)
-            .for_each(|tok| ted::replace(tok, t.syntax()));
-    }
     let usages_for_locals = |local| {
         Definition::Local(local)
             .usages(sema)
@@ -352,7 +345,6 @@ fn inline(
             }
         })
         .collect();
-
     if function.self_param(sema.db).is_some() {
         let this = || make::name_ref("this").syntax().clone_for_update();
         if let Some(self_local) = params[0].2.as_local(sema.db) {
@@ -1196,31 +1188,6 @@ fn bar() -> u32 {
       x
     }
 }
-"#,
-        )
-    }
-
-    #[test]
-    fn inline_call_with_self_type() {
-        check_assist(
-            inline_call,
-            r#"
-struct A(u32);
-impl A {
-    fn f() -> Self { Self(114514) }
-}
-fn main() {
-    A::f$0();
-}
-"#,
-            r#"
-struct A(u32);
-impl A {
-    fn f() -> Self { Self(114514) }
-}
-fn main() {
-    A(114514);
-}
 "#,
         )
     }
diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs
index 9adf6381c1..054663a06a 100644
--- a/crates/ide-assists/src/handlers/inline_type_alias.rs
+++ b/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -1,9 +1,9 @@
 // Some ideas for future improvements:
 // - Support replacing aliases which are used in expressions, e.g. `A::new()`.
+// - "inline_alias_to_users" assist #10881.
 // - Remove unused aliases if there are no longer any users, see inline_call.rs.
 
 use hir::{HasSource, PathResolution};
-use ide_db::{defs::Definition, search::FileReference};
 use itertools::Itertools;
 use std::collections::HashMap;
 use syntax::{
@@ -16,78 +16,6 @@ use crate::{
     AssistId, AssistKind,
 };
 
-// Assist: inline_type_alias_uses
-//
-// Inline a type alias into all of its uses where possible.
-//
-// ```
-// type $0A = i32;
-// fn id(x: A) -> A {
-//     x
-// };
-// fn foo() {
-//     let _: A = 3;
-// }
-// ```
-// ->
-// ```
-// type A = i32;
-// fn id(x: i32) -> i32 {
-//     x
-// };
-// fn foo() {
-//     let _: i32 = 3;
-// }
-pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let name = ctx.find_node_at_offset::<ast::Name>()?;
-    let ast_alias = name.syntax().parent().and_then(ast::TypeAlias::cast)?;
-
-    let hir_alias = ctx.sema.to_def(&ast_alias)?;
-    let concrete_type = ast_alias.ty()?;
-
-    let usages = Definition::TypeAlias(hir_alias).usages(&ctx.sema);
-    if !usages.at_least_one() {
-        return None;
-    }
-
-    // until this is ok
-
-    acc.add(
-        AssistId("inline_type_alias_uses", AssistKind::RefactorInline),
-        "Inline type alias into all uses",
-        name.syntax().text_range(),
-        |builder| {
-            let usages = usages.all();
-
-            let mut inline_refs_for_file = |file_id, refs: Vec<FileReference>| {
-                builder.edit_file(file_id);
-
-                let path_types: Vec<ast::PathType> = refs
-                    .into_iter()
-                    .filter_map(|file_ref| match file_ref.name {
-                        ast::NameLike::NameRef(path_type) => {
-                            path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast)
-                        }
-                        _ => None,
-                    })
-                    .collect();
-
-                for (target, replacement) in path_types.into_iter().filter_map(|path_type| {
-                    let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type);
-                    let target = path_type.syntax().text_range();
-                    Some((target, replacement))
-                }) {
-                    builder.replace(target, replacement);
-                }
-            };
-
-            for (file_id, refs) in usages.into_iter() {
-                inline_refs_for_file(file_id, refs);
-            }
-        },
-    )
-}
-
 // Assist: inline_type_alias
 //
 // Replace a type alias with its concrete type.
@@ -108,6 +36,11 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>)
 // }
 // ```
 pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    enum Replacement {
+        Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
+        Plain,
+    }
+
     let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
     let concrete_type;
     let replacement;
@@ -126,7 +59,23 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         _ => {
             let alias = get_type_alias(&ctx, &alias_instance)?;
             concrete_type = alias.ty()?;
-            replacement = inline(&alias, &alias_instance)?;
+
+            replacement = if let Some(alias_generics) = alias.generic_param_list() {
+                if alias_generics.generic_params().next().is_none() {
+                    cov_mark::hit!(no_generics_params);
+                    return None;
+                }
+
+                let instance_args =
+                    alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
+
+                Replacement::Generic {
+                    lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
+                    const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
+                }
+            } else {
+                Replacement::Plain
+            };
         }
     }
 
@@ -136,43 +85,17 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         AssistId("inline_type_alias", AssistKind::RefactorInline),
         "Inline type alias",
         target,
-        |builder| builder.replace(target, replacement.to_text(&concrete_type)),
-    )
-}
-
-impl Replacement {
-    fn to_text(&self, concrete_type: &ast::Type) -> String {
-        match self {
-            Replacement::Generic { lifetime_map, const_and_type_map } => {
-                create_replacement(&lifetime_map, &const_and_type_map, &concrete_type)
-            }
-            Replacement::Plain => concrete_type.to_string(),
-        }
-    }
-}
-
-enum Replacement {
-    Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
-    Plain,
-}
-
-fn inline(alias_def: &ast::TypeAlias, alias_instance: &ast::PathType) -> Option<Replacement> {
-    let repl = if let Some(alias_generics) = alias_def.generic_param_list() {
-        if alias_generics.generic_params().next().is_none() {
-            cov_mark::hit!(no_generics_params);
-            return None;
-        }
-        let instance_args =
-            alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
+        |builder| {
+            let replacement_text = match replacement {
+                Replacement::Generic { lifetime_map, const_and_type_map } => {
+                    create_replacement(&lifetime_map, &const_and_type_map, &concrete_type)
+                }
+                Replacement::Plain => concrete_type.to_string(),
+            };
 
-        Replacement::Generic {
-            lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
-            const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
-        }
-    } else {
-        Replacement::Plain
-    };
-    Some(repl)
+            builder.replace(target, replacement_text);
+        },
+    )
 }
 
 struct LifetimeMap(HashMap<String, ast::Lifetime>);
@@ -912,90 +835,4 @@ trait Tr {
 "#,
         );
     }
-
-    mod inline_type_alias_uses {
-        use crate::{handlers::inline_type_alias::inline_type_alias_uses, tests::check_assist};
-
-        #[test]
-        fn inline_uses() {
-            check_assist(
-                inline_type_alias_uses,
-                r#"
-type $0A = u32;
-
-fn foo() {
-    let _: A = 3;
-    let _: A = 4;
-}
-"#,
-                r#"
-type A = u32;
-
-fn foo() {
-    let _: u32 = 3;
-    let _: u32 = 4;
-}
-"#,
-            );
-        }
-
-        #[test]
-        fn inline_uses_across_files() {
-            check_assist(
-                inline_type_alias_uses,
-                r#"
-//- /lib.rs
-mod foo;
-type $0T<E> = Vec<E>;
-fn f() -> T<&str> {
-    vec!["hello"]
-}
-
-//- /foo.rs
-use super::T;
-fn foo() {
-    let _: T<i8> = Vec::new();
-}
-"#,
-                r#"
-//- /lib.rs
-mod foo;
-type T<E> = Vec<E>;
-fn f() -> Vec<&str> {
-    vec!["hello"]
-}
-
-//- /foo.rs
-use super::T;
-fn foo() {
-    let _: Vec<i8> = Vec::new();
-}
-"#,
-            );
-        }
-
-        #[test]
-        fn inline_uses_across_files_2() {
-            check_assist(
-                inline_type_alias_uses,
-                r#"
-//- /lib.rs
-mod foo;
-type $0I = i32;
-
-//- /foo.rs
-use super::I;
-fn foo() {
-    let _: I = 0;
-}
-"#,
-                r#"
-use super::I;
-fn foo() {
-    let _: i32 = 0;
-}
-"#,
-            );
-        }
-    }
 }
diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs
index 7fb35143fa..fe87aa15fc 100644
--- a/crates/ide-assists/src/lib.rs
+++ b/crates/ide-assists/src/lib.rs
@@ -243,7 +243,6 @@ mod handlers {
             inline_call::inline_into_callers,
             inline_local_variable::inline_local_variable,
             inline_type_alias::inline_type_alias,
-            inline_type_alias::inline_type_alias_uses,
             introduce_named_generic::introduce_named_generic,
             introduce_named_lifetime::introduce_named_lifetime,
             invert_if::invert_if,
diff --git a/crates/ide-assists/src/utils/suggest_name.rs b/crates/ide-assists/src/utils/suggest_name.rs
index c521a10fcc..662ddd063f 100644
--- a/crates/ide-assists/src/utils/suggest_name.rs
+++ b/crates/ide-assists/src/utils/suggest_name.rs
@@ -55,7 +55,6 @@ const USELESS_METHODS: &[&str] = &[
     "iter",
     "into_iter",
     "iter_mut",
-    "into_future",
 ];
 
 pub(crate) fn for_generic_parameter(ty: &ast::ImplTraitType) -> SmolStr {
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index 02004ff7b6..cf40ca489c 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -19,7 +19,7 @@ pub(crate) fn complete_dot(
     };
 
     // Suggest .await syntax for types that implement Future trait
-    if receiver_ty.impls_into_future(ctx.db) {
+    if receiver_ty.impls_future(ctx.db) {
         let mut item =
             CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await");
         item.detail("expr.await");
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs
index 1d03c8cc5c..3989a451bd 100644
--- a/crates/ide-completion/src/completions/keyword.rs
+++ b/crates/ide-completion/src/completions/keyword.rs
@@ -75,17 +75,16 @@ impl Future for A {}
 fn foo(a: A) { a.$0 }
 "#,
             expect![[r#"
-                kw await                  expr.await
-                me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
-                sn box                    Box::new(expr)
-                sn call                   function(expr)
-                sn dbg                    dbg!(expr)
-                sn dbgr                   dbg!(&expr)
-                sn let                    let
-                sn letm                   let mut
-                sn match                  match expr {}
-                sn ref                    &expr
-                sn refm                   &mut expr
+                kw await expr.await
+                sn box   Box::new(expr)
+                sn call  function(expr)
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn let   let
+                sn letm  let mut
+                sn match match expr {}
+                sn ref   &expr
+                sn refm  &mut expr
             "#]],
         );
 
@@ -99,45 +98,18 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                kw await                  expr.await
-                me into_future() (use core::future::IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
-                sn box                    Box::new(expr)
-                sn call                   function(expr)
-                sn dbg                    dbg!(expr)
-                sn dbgr                   dbg!(&expr)
-                sn let                    let
-                sn letm                   let mut
-                sn match                  match expr {}
-                sn ref                    &expr
-                sn refm                   &mut expr
+                kw await expr.await
+                sn box   Box::new(expr)
+                sn call  function(expr)
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn let   let
+                sn letm  let mut
+                sn match match expr {}
+                sn ref   &expr
+                sn refm  &mut expr
             "#]],
-        );
-    }
-
-    #[test]
-    fn test_completion_await_impls_into_future() {
-        check(
-            r#"
-//- minicore: future
-use core::future::*;
-struct A {}
-impl IntoFuture for A {}
-fn foo(a: A) { a.$0 }
-"#,
-            expect![[r#"
-                kw await                  expr.await
-                me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
-                sn box                    Box::new(expr)
-                sn call                   function(expr)
-                sn dbg                    dbg!(expr)
-                sn dbgr                   dbg!(&expr)
-                sn let                    let
-                sn letm                   let mut
-                sn match                  match expr {}
-                sn ref                    &expr
-                sn refm                   &mut expr
-            "#]],
-        );
+        )
     }
 
     #[test]
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 36a648fe4a..d6cd5783f0 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1664,40 +1664,6 @@ fn f() {
         );
     }
 
-    #[test]
-    fn goto_await_into_future_poll() {
-        check(
-            r#"
-//- minicore: future
-
-struct Futurable;
-
-impl core::future::IntoFuture for Futurable {
-    type IntoFuture = MyFut;
-}
-
-struct MyFut;
-
-impl core::future::Future for MyFut {
-    type Output = ();
-
-    fn poll(
-     //^^^^
-        self: std::pin::Pin<&mut Self>,
-        cx: &mut std::task::Context<'_>
-    ) -> std::task::Poll<Self::Output>
-    {
-        ()
-    }
-}
-
-fn f() {
-    Futurable.await$0;
-}
-"#,
-        );
-    }
-
     #[test]
     fn goto_try_op() {
         check(
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index e0bcc80b31..943d043bc1 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -51,12 +51,6 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
     Ok(())
 }
 
-pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
-    let _p = profile::span("handle_stop_flycheck");
-    state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
-    Ok(())
-}
-
 pub(crate) fn handle_analyzer_status(
     snap: GlobalStateSnapshot,
     params: lsp_ext::AnalyzerStatusParams,
@@ -709,8 +703,10 @@ pub(crate) fn handle_runnables(
 
     let mut res = Vec::new();
     for runnable in snap.analysis.runnables(file_id)? {
-        if should_skip_for_offset(&runnable, offset) {
-            continue;
+        if let Some(offset) = offset {
+            if !runnable.nav.full_range.contains_inclusive(offset) {
+                continue;
+            }
         }
         if should_skip_target(&runnable, cargo_spec.as_ref()) {
             continue;
@@ -776,14 +772,6 @@ pub(crate) fn handle_runnables(
     Ok(res)
 }
 
-fn should_skip_for_offset(runnable: &Runnable, offset: Option<TextSize>) -> bool {
-    match offset {
-        None => false,
-        _ if matches!(&runnable.kind, RunnableKind::TestMod { .. }) => false,
-        Some(offset) => !runnable.nav.full_range.contains_inclusive(offset),
-    }
-}
-
 pub(crate) fn handle_related_tests(
     snap: GlobalStateSnapshot,
     params: lsp_types::TextDocumentPositionParams,
@@ -1777,7 +1765,7 @@ fn run_rustfmt(
 
     let line_index = snap.file_line_index(file_id)?;
 
-    let mut command = match snap.config.rustfmt() {
+    let mut rustfmt = match snap.config.rustfmt() {
         RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
             let mut cmd = process::Command::new(toolchain::rustfmt());
             cmd.args(extra_args);
@@ -1842,12 +1830,12 @@ fn run_rustfmt(
         }
     };
 
-    let mut rustfmt = command
+    let mut rustfmt = rustfmt
         .stdin(Stdio::piped())
         .stdout(Stdio::piped())
         .stderr(Stdio::piped())
         .spawn()
-        .context(format!("Failed to spawn {:?}", command))?;
+        .context(format!("Failed to spawn {:?}", rustfmt))?;
 
     rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?;
 
@@ -1866,11 +1854,7 @@ fn run_rustfmt(
                 // formatting because otherwise an error is surfaced to the user on top of the
                 // syntax error diagnostics they're already receiving. This is especially jarring
                 // if they have format on save enabled.
-                tracing::warn!(
-                    ?command,
-                    %captured_stderr,
-                    "rustfmt exited with status 1"
-                );
+                tracing::info!("rustfmt exited with status 1, assuming parse error and ignoring");
                 Ok(None)
             }
             _ => {
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index e61c8b643d..5f0e108624 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -129,14 +129,6 @@ pub struct ExpandedMacro {
     pub expansion: String,
 }
 
-pub enum CancelFlycheck {}
-
-impl Request for CancelFlycheck {
-    type Params = ();
-    type Result = ();
-    const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
-}
-
 pub enum MatchingBrace {}
 
 impl Request for MatchingBrace {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index f187547019..7741999824 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -288,7 +288,7 @@ impl GlobalState {
 
             if became_quiescent {
                 // Project has loaded properly, kick off initial flycheck
-                self.flycheck.iter().for_each(FlycheckHandle::restart);
+                self.flycheck.iter().for_each(FlycheckHandle::update);
                 if self.config.prefill_caches() {
                     self.prime_caches_queue.request_op("became quiescent".to_string());
                 }
@@ -590,7 +590,6 @@ impl GlobalState {
             .on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
             .on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
             .on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
-            .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)
             .on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
             .on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
             .on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
@@ -780,7 +779,7 @@ impl GlobalState {
                             for (id, _) in workspace_ids.clone() {
                                 if id == flycheck.id() {
                                     updated = true;
-                                    flycheck.restart();
+                                    flycheck.update();
                                     continue;
                                 }
                             }
@@ -799,7 +798,7 @@ impl GlobalState {
                 // No specific flycheck was triggered, so let's trigger all of them.
                 if !updated {
                     for flycheck in &this.flycheck {
-                        flycheck.restart();
+                        flycheck.update();
                     }
                 }
                 Ok(())
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 037de876d4..83f8bbac58 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -25,7 +25,7 @@ pub mod ext {
         return from_text(&name.text());
 
         fn from_text(text: &str) -> ast::IdentPat {
-            ast_from_text(&format!("fn f({}: ())", text))
+            ast_from_text(&format!("fn f({text}: ())"))
         }
     }
     pub fn ident_path(ident: &str) -> ast::Path {
@@ -60,10 +60,10 @@ pub mod ext {
         expr_from_text("todo!()")
     }
     pub fn expr_ty_default(ty: &ast::Type) -> ast::Expr {
-        expr_from_text(&format!("{}::default()", ty))
+        expr_from_text(&format!("{ty}::default()"))
     }
     pub fn expr_ty_new(ty: &ast::Type) -> ast::Expr {
-        expr_from_text(&format!("{}::new()", ty))
+        expr_from_text(&format!("{ty}::new()"))
     }
 
     pub fn zero_number() -> ast::Expr {
@@ -92,18 +92,20 @@ pub mod ext {
         ty_path(ident_path("bool"))
     }
     pub fn ty_option(t: ast::Type) -> ast::Type {
-        ty_from_text(&format!("Option<{}>", t))
+        ty_from_text(&format!("Option<{t}>"))
     }
     pub fn ty_result(t: ast::Type, e: ast::Type) -> ast::Type {
-        ty_from_text(&format!("Result<{}, {}>", t, e))
+        ty_from_text(&format!("Result<{t}, {e}>"))
     }
 }
 
-pub fn name(text: &str) -> ast::Name {
-    ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text))
+pub fn name(name: &str) -> ast::Name {
+    let raw_escape = raw_ident_esc(name);
+    ast_from_text(&format!("mod {raw_escape}{name};"))
 }
-pub fn name_ref(text: &str) -> ast::NameRef {
-    ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
+pub fn name_ref(name_ref: &str) -> ast::NameRef {
+    let raw_escape = raw_ident_esc(name_ref);
+    ast_from_text(&format!("fn f() {{ {raw_escape}{name_ref}; }}"))
 }
 fn raw_ident_esc(ident: &str) -> &'static str {
     let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
@@ -118,10 +120,10 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
     let mut text = text;
     let tmp;
     if never!(!text.starts_with('\'')) {
-        tmp = format!("'{}", text);
+        tmp = format!("'{text}");
         text = &tmp;
     }
-    ast_from_text(&format!("fn f<{}>() {{ }}", text))
+    ast_from_text(&format!("fn f<{text}>() {{ }}"))
 }
 
 // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
@@ -142,16 +144,16 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
         contents.push(',');
     }
 
-    ty_from_text(&format!("({})", contents))
+    ty_from_text(&format!("({contents})"))
 }
 pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
-    ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
+    ty_from_text(&if exclusive { format!("&mut {target}") } else { format!("&{target}") })
 }
 pub fn ty_path(path: ast::Path) -> ast::Type {
     ty_from_text(&path.to_string())
 }
 fn ty_from_text(text: &str) -> ast::Type {
-    ast_from_text(&format!("type _T = {};", text))
+    ast_from_text(&format!("type _T = {text};"))
 }
 
 pub fn assoc_item_list() -> ast::AssocItemList {
@@ -171,7 +173,7 @@ pub fn impl_(
         Some(params) => params.to_string(),
         None => String::new(),
     };
-    ast_from_text(&format!("impl{} {}{} {{}}", params, ty, ty_params))
+    ast_from_text(&format!("impl{params} {ty}{ty_params} {{}}"))
 }
 
 pub fn impl_trait(
@@ -180,7 +182,7 @@ pub fn impl_trait(
     ty_params: Option<ast::GenericParamList>,
 ) -> ast::Impl {
     let ty_params = ty_params.map_or_else(String::new, |params| params.to_string());
-    ast_from_text(&format!("impl{2} {} for {}{2} {{}}", trait_, ty, ty_params))
+    ast_from_text(&format!("impl{ty_params} {trait_} for {ty}{ty_params} {{}}"))
 }
 
 pub(crate) fn generic_arg_list() -> ast::GenericArgList {
@@ -188,13 +190,13 @@ pub(crate) fn generic_arg_list() -> ast::GenericArgList {
 }
 
 pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
-    ast_from_text(&format!("type __ = {};", name_ref))
+    ast_from_text(&format!("type __ = {name_ref};"))
 }
 
 pub fn path_segment_ty(type_ref: ast::Type, trait_ref: Option<ast::PathType>) -> ast::PathSegment {
     let text = match trait_ref {
-        Some(trait_ref) => format!("fn f(x: <{} as {}>) {{}}", type_ref, trait_ref),
-        None => format!("fn f(x: <{}>) {{}}", type_ref),
+        Some(trait_ref) => format!("fn f(x: <{type_ref} as {trait_ref}>) {{}}"),
+        None => format!("fn f(x: <{type_ref}>) {{}}"),
     };
     ast_from_text(&text)
 }
@@ -212,15 +214,15 @@ pub fn path_segment_crate() -> ast::PathSegment {
 }
 
 pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
-    ast_from_text(&format!("type __ = {};", segment))
+    ast_from_text(&format!("type __ = {segment};"))
 }
 
 pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
-    ast_from_text(&format!("{}::{}", qual, segment))
+    ast_from_text(&format!("{qual}::{segment}"))
 }
 // FIXME: path concatenation operation doesn't make sense as AST op.
 pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path {
-    ast_from_text(&format!("type __ = {}::{};", first, second))
+    ast_from_text(&format!("type __ = {first}::{second};"))
 }
 
 pub fn path_from_segments(
@@ -229,20 +231,20 @@ pub fn path_from_segments(
 ) -> ast::Path {
     let segments = segments.into_iter().map(|it| it.syntax().clone()).join("::");
     ast_from_text(&if is_abs {
-        format!("fn f(x: ::{}) {{}}", segments)
+        format!("fn f(x: ::{segments}) {{}}")
     } else {
-        format!("fn f(x: {}) {{}}", segments)
+        format!("fn f(x: {segments}) {{}}")
     })
 }
 
 pub fn join_paths(paths: impl IntoIterator<Item = ast::Path>) -> ast::Path {
     let paths = paths.into_iter().map(|it| it.syntax().clone()).join("::");
-    ast_from_text(&format!("type __ = {};", paths))
+    ast_from_text(&format!("type __ = {paths};"))
 }
 
 // FIXME: should not be pub
 pub fn path_from_text(text: &str) -> ast::Path {
-    ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
+    ast_from_text(&format!("fn main() {{ let test = {text}; }}"))
 }
 
 pub fn use_tree_glob() -> ast::UseTree {
@@ -257,50 +259,50 @@ pub fn use_tree(
     let mut buf = "use ".to_string();
     buf += &path.syntax().to_string();
     if let Some(use_tree_list) = use_tree_list {
-        format_to!(buf, "::{}", use_tree_list);
+        format_to!(buf, "::{use_tree_list}");
     }
     if add_star {
         buf += "::*";
     }
 
     if let Some(alias) = alias {
-        format_to!(buf, " {}", alias);
+        format_to!(buf, " {alias}");
     }
     ast_from_text(&buf)
 }
 
 pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast::UseTreeList {
     let use_trees = use_trees.into_iter().map(|it| it.syntax().clone()).join(", ");
-    ast_from_text(&format!("use {{{}}};", use_trees))
+    ast_from_text(&format!("use {{{use_trees}}};"))
 }
 
 pub fn use_(visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("{}use {};", visibility, use_tree))
+    ast_from_text(&format!("{visibility}use {use_tree};"))
 }
 
 pub fn record_expr(path: ast::Path, fields: ast::RecordExprFieldList) -> ast::RecordExpr {
-    ast_from_text(&format!("fn f() {{ {} {} }}", path, fields))
+    ast_from_text(&format!("fn f() {{ {path} {fields} }}"))
 }
 
 pub fn record_expr_field_list(
     fields: impl IntoIterator<Item = ast::RecordExprField>,
 ) -> ast::RecordExprFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("fn f() {{ S {{ {} }} }}", fields))
+    ast_from_text(&format!("fn f() {{ S {{ {fields} }} }}"))
 }
 
 pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField {
     return match expr {
-        Some(expr) => from_text(&format!("{}: {}", name, expr)),
+        Some(expr) => from_text(&format!("{name}: {expr}")),
         None => from_text(&name.to_string()),
     };
 
     fn from_text(text: &str) -> ast::RecordExprField {
-        ast_from_text(&format!("fn f() {{ S {{ {}, }} }}", text))
+        ast_from_text(&format!("fn f() {{ S {{ {text}, }} }}"))
     }
 }
 
@@ -311,9 +313,9 @@ pub fn record_field(
 ) -> ast::RecordField {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("struct S {{ {}{}: {}, }}", visibility, name, ty))
+    ast_from_text(&format!("struct S {{ {visibility}{name}: {ty}, }}"))
 }
 
 // TODO
@@ -323,13 +325,13 @@ pub fn block_expr(
 ) -> ast::BlockExpr {
     let mut buf = "{\n".to_string();
     for stmt in stmts.into_iter() {
-        format_to!(buf, "    {}\n", stmt);
+        format_to!(buf, "    {stmt}\n");
     }
     if let Some(tail_expr) = tail_expr {
-        format_to!(buf, "    {}\n", tail_expr);
+        format_to!(buf, "    {tail_expr}\n");
     }
     buf += "}";
-    ast_from_text(&format!("fn f() {}", buf))
+    ast_from_text(&format!("fn f() {buf}"))
 }
 
 /// Ideally this function wouldn't exist since it involves manual indenting.
@@ -343,18 +345,18 @@ pub fn hacky_block_expr_with_comments(
     let mut buf = "{\n".to_string();
     for node_or_token in elements.into_iter() {
         match node_or_token {
-            rowan::NodeOrToken::Node(n) => format_to!(buf, "    {}\n", n),
+            rowan::NodeOrToken::Node(n) => format_to!(buf, "    {n}\n"),
             rowan::NodeOrToken::Token(t) if t.kind() == SyntaxKind::COMMENT => {
-                format_to!(buf, "    {}\n", t)
+                format_to!(buf, "    {t}\n")
             }
             _ => (),
         }
     }
     if let Some(tail_expr) = tail_expr {
-        format_to!(buf, "    {}\n", tail_expr);
+        format_to!(buf, "    {tail_expr}\n");
     }
     buf += "}";
-    ast_from_text(&format!("fn f() {}", buf))
+    ast_from_text(&format!("fn f() {buf}"))
 }
 
 pub fn expr_unit() -> ast::Expr {
@@ -362,7 +364,7 @@ pub fn expr_unit() -> ast::Expr {
 }
 pub fn expr_literal(text: &str) -> ast::Literal {
     assert_eq!(text.trim(), text);
-    ast_from_text(&format!("fn f() {{ let _ = {}; }}", text))
+    ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
 }
 
 pub fn expr_empty_block() -> ast::Expr {
@@ -373,41 +375,41 @@ pub fn expr_path(path: ast::Path) -> ast::Expr {
 }
 pub fn expr_continue(label: Option<ast::Lifetime>) -> ast::Expr {
     match label {
-        Some(label) => expr_from_text(&format!("continue {}", label)),
+        Some(label) => expr_from_text(&format!("continue {label}")),
         None => expr_from_text("continue"),
     }
 }
 // Consider `op: SyntaxKind` instead for nicer syntax at the call-site?
 pub fn expr_bin_op(lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{} {} {}", lhs, op, rhs))
+    expr_from_text(&format!("{lhs} {op} {rhs}"))
 }
 pub fn expr_break(label: Option<ast::Lifetime>, expr: Option<ast::Expr>) -> ast::Expr {
     let mut s = String::from("break");
 
     if let Some(label) = label {
-        format_to!(s, " {}", label);
+        format_to!(s, " {label}");
     }
 
     if let Some(expr) = expr {
-        format_to!(s, " {}", expr);
+        format_to!(s, " {expr}");
     }
 
     expr_from_text(&s)
 }
 pub fn expr_return(expr: Option<ast::Expr>) -> ast::Expr {
     match expr {
-        Some(expr) => expr_from_text(&format!("return {}", expr)),
+        Some(expr) => expr_from_text(&format!("return {expr}")),
         None => expr_from_text("return"),
     }
 }
 pub fn expr_try(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{}?", expr))
+    expr_from_text(&format!("{expr}?"))
 }
 pub fn expr_await(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{}.await", expr))
+    expr_from_text(&format!("{expr}.await"))
 }
 pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
-    expr_from_text(&format!("match {} {}", expr, match_arm_list))
+    expr_from_text(&format!("match {expr} {match_arm_list}"))
 }
 pub fn expr_if(
     condition: ast::Expr,
@@ -415,66 +417,67 @@ pub fn expr_if(
     else_branch: Option<ast::ElseBranch>,
 ) -> ast::Expr {
     let else_branch = match else_branch {
-        Some(ast::ElseBranch::Block(block)) => format!("else {}", block),
-        Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {}", if_expr),
+        Some(ast::ElseBranch::Block(block)) => format!("else {block}"),
+        Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {if_expr}"),
         None => String::new(),
     };
-    expr_from_text(&format!("if {} {} {}", condition, then_branch, else_branch))
+    expr_from_text(&format!("if {condition} {then_branch} {else_branch}"))
 }
 pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr {
-    expr_from_text(&format!("for {} in {} {}", pat, expr, block))
+    expr_from_text(&format!("for {pat} in {expr} {block}"))
 }
 
 pub fn expr_loop(block: ast::BlockExpr) -> ast::Expr {
-    expr_from_text(&format!("loop {}", block))
+    expr_from_text(&format!("loop {block}"))
 }
 
 pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
     let token = token(op);
-    expr_from_text(&format!("{}{}", token, expr))
+    expr_from_text(&format!("{token}{expr}"))
 }
 pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
-    expr_from_text(&format!("{}{}", f, arg_list))
+    expr_from_text(&format!("{f}{arg_list}"))
 }
 pub fn expr_method_call(
     receiver: ast::Expr,
     method: ast::NameRef,
     arg_list: ast::ArgList,
 ) -> ast::Expr {
-    expr_from_text(&format!("{}.{}{}", receiver, method, arg_list))
+    expr_from_text(&format!("{receiver}.{method}{arg_list}"))
 }
 pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
-    expr_from_text(&format!("{}!{}", f, arg_list))
+    expr_from_text(&format!("{f}!{arg_list}"))
 }
 pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr {
-    expr_from_text(&if exclusive { format!("&mut {}", expr) } else { format!("&{}", expr) })
+    expr_from_text(&if exclusive { format!("&mut {expr}") } else { format!("&{expr}") })
 }
 pub fn expr_closure(pats: impl IntoIterator<Item = ast::Param>, expr: ast::Expr) -> ast::Expr {
     let params = pats.into_iter().join(", ");
-    expr_from_text(&format!("|{}| {}", params, expr))
+    expr_from_text(&format!("|{params}| {expr}"))
 }
 pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
-    expr_from_text(&format!("{}.{}", receiver, field))
+    expr_from_text(&format!("{receiver}.{field}"))
 }
 pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("({})", expr))
+    expr_from_text(&format!("({expr})"))
 }
 pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::Expr {
     let expr = elements.into_iter().format(", ");
-    expr_from_text(&format!("({})", expr))
+    expr_from_text(&format!("({expr})"))
 }
 pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{} = {}", lhs, rhs))
+    expr_from_text(&format!("{lhs} = {rhs}"))
 }
 fn expr_from_text(text: &str) -> ast::Expr {
-    ast_from_text(&format!("const C: () = {};", text))
+    ast_from_text(&format!("const C: () = {text};"))
 }
 pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {
-    ast_from_text(&format!("const _: () = while let {} = {} {{}};", pattern, expr))
+    ast_from_text(&format!("const _: () = while let {pattern} = {expr} {{}};"))
 }
 
 pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
-    ast_from_text(&format!("fn main() {{ ()({}) }}", args.into_iter().format(", ")))
+    let args = args.into_iter().format(", ");
+    ast_from_text(&format!("fn main() {{ ()({args}) }}"))
 }
 
 pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
@@ -485,7 +488,7 @@ pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
     if mut_ {
         s.push_str("mut ");
     }
-    format_to!(s, "{}", name);
+    format_to!(s, "{name}");
     s.push_str(": ())");
     ast_from_text(&s)
 }
@@ -494,7 +497,7 @@ pub fn wildcard_pat() -> ast::WildcardPat {
     return from_text("_");
 
     fn from_text(text: &str) -> ast::WildcardPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -502,7 +505,7 @@ pub fn literal_pat(lit: &str) -> ast::LiteralPat {
     return from_text(lit);
 
     fn from_text(text: &str) -> ast::LiteralPat {
-        ast_from_text(&format!("fn f() {{ match x {{ {} => {{}} }} }}", text))
+        ast_from_text(&format!("fn f() {{ match x {{ {text} => {{}} }} }}"))
     }
 }
 
@@ -515,10 +518,10 @@ pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
     if count == 1 {
         pats_str.push(',');
     }
-    return from_text(&format!("({})", pats_str));
+    return from_text(&format!("({pats_str})"));
 
     fn from_text(text: &str) -> ast::TuplePat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -527,46 +530,46 @@ pub fn tuple_struct_pat(
     pats: impl IntoIterator<Item = ast::Pat>,
 ) -> ast::TupleStructPat {
     let pats_str = pats.into_iter().join(", ");
-    return from_text(&format!("{}({})", path, pats_str));
+    return from_text(&format!("{path}({pats_str})"));
 
     fn from_text(text: &str) -> ast::TupleStructPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
 pub fn record_pat(path: ast::Path, pats: impl IntoIterator<Item = ast::Pat>) -> ast::RecordPat {
     let pats_str = pats.into_iter().join(", ");
-    return from_text(&format!("{} {{ {} }}", path, pats_str));
+    return from_text(&format!("{path} {{ {pats_str} }}"));
 
     fn from_text(text: &str) -> ast::RecordPat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
 pub fn record_pat_with_fields(path: ast::Path, fields: ast::RecordPatFieldList) -> ast::RecordPat {
-    ast_from_text(&format!("fn f({} {}: ()))", path, fields))
+    ast_from_text(&format!("fn f({path} {fields}: ()))"))
 }
 
 pub fn record_pat_field_list(
     fields: impl IntoIterator<Item = ast::RecordPatField>,
 ) -> ast::RecordPatFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("fn f(S {{ {} }}: ()))", fields))
+    ast_from_text(&format!("fn f(S {{ {fields} }}: ()))"))
 }
 
 pub fn record_pat_field(name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField {
-    ast_from_text(&format!("fn f(S {{ {}: {} }}: ()))", name_ref, pat))
+    ast_from_text(&format!("fn f(S {{ {name_ref}: {pat} }}: ()))"))
 }
 
 pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField {
-    ast_from_text(&format!("fn f(S {{ {} }}: ()))", name_ref))
+    ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))"))
 }
 
 /// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise.
 pub fn path_pat(path: ast::Path) -> ast::Pat {
     return from_text(&path.to_string());
     fn from_text(text: &str) -> ast::Pat {
-        ast_from_text(&format!("fn f({}: ())", text))
+        ast_from_text(&format!("fn f({text}: ())"))
     }
 }
 
@@ -577,12 +580,12 @@ pub fn match_arm(
 ) -> ast::MatchArm {
     let pats_str = pats.into_iter().join(" | ");
     return match guard {
-        Some(guard) => from_text(&format!("{} if {} => {}", pats_str, guard, expr)),
-        None => from_text(&format!("{} => {}", pats_str, expr)),
+        Some(guard) => from_text(&format!("{pats_str} if {guard} => {expr}")),
+        None => from_text(&format!("{pats_str} => {expr}")),
     };
 
     fn from_text(text: &str) -> ast::MatchArm {
-        ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
     }
 }
 
@@ -592,10 +595,10 @@ pub fn match_arm_with_guard(
     expr: ast::Expr,
 ) -> ast::MatchArm {
     let pats_str = pats.into_iter().join(" | ");
-    return from_text(&format!("{} if {} => {}", pats_str, guard, expr));
+    return from_text(&format!("{pats_str} if {guard} => {expr}"));
 
     fn from_text(text: &str) -> ast::MatchArm {
-        ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{{text}}} }}"))
     }
 }
 
@@ -605,13 +608,14 @@ pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::Mat
         .map(|arm| {
             let needs_comma = arm.expr().map_or(true, |it| !it.is_block_like());
             let comma = if needs_comma { "," } else { "" };
-            format!("    {}{}\n", arm.syntax(), comma)
+            let arm = arm.syntax();
+            format!("    {arm}{comma}\n")
         })
         .collect::<String>();
     return from_text(&arms_str);
 
     fn from_text(text: &str) -> ast::MatchArmList {
-        ast_from_text(&format!("fn f() {{ match () {{\n{}}} }}", text))
+        ast_from_text(&format!("fn f() {{ match () {{\n{text}}} }}"))
     }
 }
 
@@ -620,10 +624,10 @@ pub fn where_pred(
     bounds: impl IntoIterator<Item = ast::TypeBound>,
 ) -> ast::WherePred {
     let bounds = bounds.into_iter().join(" + ");
-    return from_text(&format!("{}: {}", path, bounds));
+    return from_text(&format!("{path}: {bounds}"));
 
     fn from_text(text: &str) -> ast::WherePred {
-        ast_from_text(&format!("fn f() where {} {{ }}", text))
+        ast_from_text(&format!("fn f() where {text} {{ }}"))
     }
 }
 
@@ -632,7 +636,7 @@ pub fn where_clause(preds: impl IntoIterator<Item = ast::WherePred>) -> ast::Whe
     return from_text(preds.as_str());
 
     fn from_text(text: &str) -> ast::WhereClause {
-        ast_from_text(&format!("fn f() where {} {{ }}", text))
+        ast_from_text(&format!("fn f() where {text} {{ }}"))
     }
 }
 
@@ -642,19 +646,19 @@ pub fn let_stmt(
     initializer: Option<ast::Expr>,
 ) -> ast::LetStmt {
     let mut text = String::new();
-    format_to!(text, "let {}", pattern);
+    format_to!(text, "let {pattern}");
     if let Some(ty) = ty {
-        format_to!(text, ": {}", ty);
+        format_to!(text, ": {ty}");
     }
     match initializer {
-        Some(it) => format_to!(text, " = {};", it),
+        Some(it) => format_to!(text, " = {it};"),
         None => format_to!(text, ";"),
     };
-    ast_from_text(&format!("fn f() {{ {} }}", text))
+    ast_from_text(&format!("fn f() {{ {text} }}"))
 }
 pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
     let semi = if expr.is_block_like() { "" } else { ";" };
-    ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
+    ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))
 }
 
 pub fn item_const(
@@ -665,13 +669,13 @@ pub fn item_const(
 ) -> ast::Const {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("{} const {}: {} = {};", visibility, name, ty, expr))
+    ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};"))
 }
 
 pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param {
-    ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty))
+    ast_from_text(&format!("fn f({pat}: {ty}) {{ }}"))
 }
 
 pub fn self_param() -> ast::SelfParam {
@@ -679,7 +683,7 @@ pub fn self_param() -> ast::SelfParam {
 }
 
 pub fn ret_type(ty: ast::Type) -> ast::RetType {
-    ast_from_text(&format!("fn f() -> {} {{ }}", ty))
+    ast_from_text(&format!("fn f() -> {ty} {{ }}"))
 }
 
 pub fn param_list(
@@ -688,30 +692,30 @@ pub fn param_list(
 ) -> ast::ParamList {
     let args = pats.into_iter().join(", ");
     let list = match self_param {
-        Some(self_param) if args.is_empty() => format!("fn f({}) {{ }}", self_param),
-        Some(self_param) => format!("fn f({}, {}) {{ }}", self_param, args),
-        None => format!("fn f({}) {{ }}", args),
+        Some(self_param) if args.is_empty() => format!("fn f({self_param}) {{ }}"),
+        Some(self_param) => format!("fn f({self_param}, {args}) {{ }}"),
+        None => format!("fn f({args}) {{ }}"),
     };
     ast_from_text(&list)
 }
 
 pub fn type_param(name: ast::Name, ty: Option<ast::TypeBoundList>) -> ast::TypeParam {
     let bound = match ty {
-        Some(it) => format!(": {}", it),
+        Some(it) => format!(": {it}"),
         None => String::new(),
     };
-    ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound))
+    ast_from_text(&format!("fn f<{name}{bound}>() {{ }}"))
 }
 
 pub fn lifetime_param(lifetime: ast::Lifetime) -> ast::LifetimeParam {
-    ast_from_text(&format!("fn f<{}>() {{ }}", lifetime))
+    ast_from_text(&format!("fn f<{lifetime}>() {{ }}"))
 }
 
 pub fn generic_param_list(
     pats: impl IntoIterator<Item = ast::GenericParam>,
 ) -> ast::GenericParamList {
     let args = pats.into_iter().join(", ");
-    ast_from_text(&format!("fn f<{}>() {{ }}", args))
+    ast_from_text(&format!("fn f<{args}>() {{ }}"))
 }
 
 pub fn visibility_pub_crate() -> ast::Visibility {
@@ -724,33 +728,33 @@ pub fn visibility_pub() -> ast::Visibility {
 
 pub fn tuple_field_list(fields: impl IntoIterator<Item = ast::TupleField>) -> ast::TupleFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("struct f({});", fields))
+    ast_from_text(&format!("struct f({fields});"))
 }
 
 pub fn record_field_list(
     fields: impl IntoIterator<Item = ast::RecordField>,
 ) -> ast::RecordFieldList {
     let fields = fields.into_iter().join(", ");
-    ast_from_text(&format!("struct f {{ {} }}", fields))
+    ast_from_text(&format!("struct f {{ {fields} }}"))
 }
 
 pub fn tuple_field(visibility: Option<ast::Visibility>, ty: ast::Type) -> ast::TupleField {
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
-    ast_from_text(&format!("struct f({}{});", visibility, ty))
+    ast_from_text(&format!("struct f({visibility}{ty});"))
 }
 
 pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Variant {
     let field_list = match field_list {
         None => String::new(),
         Some(it) => match it {
-            ast::FieldList::RecordFieldList(record) => format!(" {}", record),
-            ast::FieldList::TupleFieldList(tuple) => format!("{}", tuple),
+            ast::FieldList::RecordFieldList(record) => format!(" {record}"),
+            ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
         },
     };
-    ast_from_text(&format!("enum f {{ {}{} }}", name, field_list))
+    ast_from_text(&format!("enum f {{ {name}{field_list} }}"))
 }
 
 pub fn fn_(
@@ -763,23 +767,22 @@ pub fn fn_(
     is_async: bool,
 ) -> ast::Fn {
     let type_params = match type_params {
-        Some(type_params) => format!("{}", type_params),
+        Some(type_params) => format!("{type_params}"),
         None => "".into(),
     };
     let ret_type = match ret_type {
-        Some(ret_type) => format!("{} ", ret_type),
+        Some(ret_type) => format!("{ret_type} "),
         None => "".into(),
     };
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
 
     let async_literal = if is_async { "async " } else { "" };
 
     ast_from_text(&format!(
-        "{}{}fn {}{}{} {}{}",
-        visibility, async_literal, fn_name, type_params, params, ret_type, body
+        "{visibility}{async_literal}fn {fn_name}{type_params}{params} {ret_type}{body}",
     ))
 }
 
@@ -793,13 +796,10 @@ pub fn struct_(
     let type_params = generic_param_list.map_or_else(String::new, |it| it.to_string());
     let visibility = match visibility {
         None => String::new(),
-        Some(it) => format!("{} ", it),
+        Some(it) => format!("{it} "),
     };
 
-    ast_from_text(&format!(
-        "{}struct {}{}{}{}",
-        visibility, strukt_name, type_params, field_list, semicolon
-    ))
+    ast_from_text(&format!("{visibility}struct {strukt_name}{type_params}{field_list}{semicolon}",))
 }
 
 #[track_caller]
@@ -808,7 +808,8 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
     let node = match parse.tree().syntax().descendants().find_map(N::cast) {
         Some(it) => it,
         None => {
-            panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
+            let node = std::any::type_name::<N>();
+            panic!("Failed to make ast node `{node}` from text {text}")
         }
     };
     let node = node.clone_subtree();
@@ -824,7 +825,7 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
         .descendants_with_tokens()
         .filter_map(|it| it.into_token())
         .find(|it| it.kind() == kind)
-        .unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
+        .unwrap_or_else(|| panic!("unhandled token: {kind:?}"))
 }
 
 pub mod tokens {
@@ -863,7 +864,7 @@ pub mod tokens {
 
     pub fn literal(text: &str) -> SyntaxToken {
         assert_eq!(text.trim(), text);
-        let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {}; }}", text));
+        let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {text}; }}"));
         lit.syntax().first_child_or_token().unwrap().into_token().unwrap()
     }
 
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 6d2c7d7b06..5040643d34 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 7b710095d773b978
+lsp_ext.rs hash: 2a188defec26cc7c
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue:
diff --git a/editors/code/package.json b/editors/code/package.json
index 2e38c05730..0714b356fe 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -235,11 +235,6 @@
                 "command": "rust-analyzer.moveItemDown",
                 "title": "Move item down",
                 "category": "rust-analyzer"
-            },
-            {
-                "command": "rust-analyzer.cancelFlycheck",
-                "title": "Cancel running flychecks",
-                "category": "rust-analyzer"
             }
         ],
         "keybindings": [
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index a21b304bbd..12f666401f 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -817,12 +817,6 @@ export function openDocs(ctx: Ctx): Cmd {
     };
 }
 
-export function cancelFlycheck(ctx: Ctx): Cmd {
-    return async () => {
-        await ctx.client.sendRequest(ra.cancelFlycheck);
-    };
-}
-
 export function resolveCodeAction(ctx: Ctx): Cmd {
     const client = ctx.client;
     return async (params: lc.CodeAction) => {
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index b83582a344..1c58040d58 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -5,6 +5,8 @@ import { log } from "./util";
 
 export type UpdatesChannel = "stable" | "nightly";
 
+const NIGHTLY_TAG = "nightly";
+
 export type RunnableEnvCfg =
     | undefined
     | Record<string, string>
@@ -173,6 +175,10 @@ export class Config {
             gotoTypeDef: this.get<boolean>("hover.actions.gotoTypeDef.enable"),
         };
     }
+
+    get currentExtensionIsNightly() {
+        return this.package.releaseTag === NIGHTLY_TAG;
+    }
 }
 
 export async function updateConfig(config: vscode.WorkspaceConfiguration) {
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index 875261c48a..f80af78a74 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -75,23 +75,6 @@ export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro |
     "rust-analyzer/expandMacro"
 );
 
-export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
-    "rust-analyzer/relatedTests"
-);
-
-export const cancelFlycheck = new lc.RequestType0<void, void>("rust-analyzer/cancelFlycheck");
-
-// Experimental extensions
-
-export interface SsrParams {
-    query: string;
-    parseOnly: boolean;
-    textDocument: lc.TextDocumentIdentifier;
-    position: lc.Position;
-    selections: readonly lc.Range[];
-}
-export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
-
 export interface MatchingBraceParams {
     textDocument: lc.TextDocumentIdentifier;
     positions: lc.Position[];
@@ -144,6 +127,19 @@ export interface TestInfo {
     runnable: Runnable;
 }
 
+export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
+    "rust-analyzer/relatedTests"
+);
+
+export interface SsrParams {
+    query: string;
+    parseOnly: boolean;
+    textDocument: lc.TextDocumentIdentifier;
+    position: lc.Position;
+    selections: readonly lc.Range[];
+}
+export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
+
 export interface CommandLink extends lc.Command {
     /**
      * A tooltip for the command, when represented in the UI.
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index a9847dd2a6..d78b711a47 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -163,7 +163,6 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
     ctx.registerCommand("peekTests", commands.peekTests);
     ctx.registerCommand("moveItemUp", commands.moveItemUp);
     ctx.registerCommand("moveItemDown", commands.moveItemDown);
-    ctx.registerCommand("cancelFlycheck", commands.cancelFlycheck);
 
     defaultOnEnter.dispose();
     ctx.registerCommand("onEnter", commands.onEnter);


Test patch:
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index eb04bf8778..94efe7bc11 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -488,42 +488,6 @@ fn infer_adt_pattern() {
     );
 }
 
-#[test]
-fn tuple_struct_destructured_with_self() {
-    check_infer(
-        r#"
-struct Foo(usize,);
-impl Foo {
-    fn f() {
-        let Self(s,) = &Foo(0,);
-        let Self(s,) = &mut Foo(0,);
-        let Self(s,) = Foo(0,);
-    }
-}
-        "#,
-        expect![[r#"
-            42..151 '{     ...     }': ()
-            56..64 'Self(s,)': Foo
-            61..62 's': &usize
-            67..75 '&Foo(0,)': &Foo
-            68..71 'Foo': Foo(usize) -> Foo
-            68..75 'Foo(0,)': Foo
-            72..73 '0': usize
-            89..97 'Self(s,)': Foo
-            94..95 's': &mut usize
-            100..112 '&mut Foo(0,)': &mut Foo
-            105..108 'Foo': Foo(usize) -> Foo
-            105..112 'Foo(0,)': Foo
-            109..110 '0': usize
-            126..134 'Self(s,)': Foo
-            131..132 's': usize
-            137..140 'Foo': Foo(usize) -> Foo
-            137..144 'Foo(0,)': Foo
-            141..142 '0': usize
-        "#]],
-    );
-}
-
 #[test]
 fn enum_variant_through_self_in_pattern() {
     check_infer(
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 0f37970e2b..75802a5eb4 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -137,31 +137,6 @@ fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
     );
 }
 
-#[test]
-fn into_future_trait() {
-    check_types(
-        r#"
-//- minicore: future
-struct Futurable;
-impl core::future::IntoFuture for Futurable {
-    type Output = u64;
-    type IntoFuture = IntFuture;
-}
-
-struct IntFuture;
-impl core::future::Future for IntFuture {
-    type Output = u64;
-}
-
-fn test() {
-    let r = Futurable;
-    let v = r.await;
-    v;
-} //^ u64
-"#,
-    );
-}
-
 #[test]
 fn infer_try() {
     check_types(
@@ -1501,34 +1476,6 @@ fn test(x: Trait, y: &Trait) -> u64 {
             165..172 'z.foo()': u64
         "#]],
     );
-
-    check_infer_with_mismatches(
-        r#"
-//- minicore: fn, coerce_unsized
-struct S;
-impl S {
-    fn foo(&self) {}
-}
-fn f(_: &Fn(S)) {}
-fn main() {
-    f(&|number| number.foo());
-}
-        "#,
-        expect![[r#"
-            31..35 'self': &S
-            37..39 '{}': ()
-            47..48 '_': &dyn Fn(S)
-            58..60 '{}': ()
-            71..105 '{     ...()); }': ()
-            77..78 'f': fn f(&dyn Fn(S))
-            77..102 'f(&|nu...foo())': ()
-            79..101 '&|numb....foo()': &|S| -> ()
-            80..101 '|numbe....foo()': |S| -> ()
-            81..87 'number': S
-            89..95 'number': S
-            89..101 'number.foo()': ()
-        "#]],
-    )
 }
 
 #[test]
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index 22319f3613..6eaab48a32 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -1356,31 +1356,6 @@ fn main() {
     )
 }
 
-#[test]
-fn doctest_inline_type_alias_uses() {
-    check_doc_test(
-        "inline_type_alias_uses",
-        r#####"
-type $0A = i32;
-fn id(x: A) -> A {
-    x
-};
-fn foo() {
-    let _: A = 3;
-}
-"#####,
-        r#####"
-type A = i32;
-fn id(x: i32) -> i32 {
-    x
-};
-fn foo() {
-    let _: i32 = 3;
-}
-"#####,
-    )
-}
-
 #[test]
 fn doctest_introduce_named_generic() {
     check_doc_test(
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 6df29db474..f48d1ec66a 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -471,21 +471,6 @@ pub mod future {
         #[lang = "poll"]
         fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
     }
-
-    pub trait IntoFuture {
-        type Output;
-        type IntoFuture: Future<Output = Self::Output>;
-        #[lang = "into_future"]
-        fn into_future(self) -> Self::IntoFuture;
-    }
-
-    impl<F: Future> IntoFuture for F {
-        type Output = F::Output;
-        type IntoFuture = F;
-        fn into_future(self) -> F {
-            self
-        }
-    }
 }
 pub mod task {
     pub enum Poll<T> {