summary refs log tree commit diff
path: root/pkgs/development/tools/rust
diff options
context:
space:
mode:
authorSandro <sandro.jaeckel@gmail.com>2021-06-24 14:07:20 +0200
committerGitHub <noreply@github.com>2021-06-24 14:07:20 +0200
commitc7dcd066b85db94ff23580e393cc047b32902852 (patch)
treeb6bc1a14ef42c8fb87d92f7b93da8684c19e8be7 /pkgs/development/tools/rust
parent9dde08d104a9ce3b22ad375b21d3270a7589fb7a (diff)
parent2beb0f7b067323eb2c935f20487d324dab356881 (diff)
downloadnixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar.gz
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar.bz2
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar.lz
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar.xz
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.tar.zst
nixpkgs-c7dcd066b85db94ff23580e393cc047b32902852.zip
Merge pull request #127708 from oxalica/rust-analyzer
Diffstat (limited to 'pkgs/development/tools/rust')
-rw-r--r--pkgs/development/tools/rust/rust-analyzer/default.nix14
-rw-r--r--pkgs/development/tools/rust/rust-analyzer/no-rust-1-53-features.patch673
-rwxr-xr-xpkgs/development/tools/rust/rust-analyzer/update.sh3
3 files changed, 686 insertions, 4 deletions
diff --git a/pkgs/development/tools/rust/rust-analyzer/default.nix b/pkgs/development/tools/rust/rust-analyzer/default.nix
index 8eca1fda2e5..07b00deb9c3 100644
--- a/pkgs/development/tools/rust/rust-analyzer/default.nix
+++ b/pkgs/development/tools/rust/rust-analyzer/default.nix
@@ -1,21 +1,27 @@
 { lib, stdenv, fetchFromGitHub, rustPlatform, CoreServices, cmake
 , libiconv
 , useMimalloc ? false
-, doCheck ? true
+# FIXME: Test doesn't pass under rustc 1.52.1 due to different escaping of `'` in string.
+, doCheck ? false
 }:
 
 rustPlatform.buildRustPackage rec {
   pname = "rust-analyzer-unwrapped";
-  version = "2021-06-07";
-  cargoSha256 = "sha256-TyoCu2Q4Tr2EIWxQcjSxASni4dkeEVsfrF5UN7IVxSs=";
+  version = "2021-06-21";
+  cargoSha256 = "sha256-OpfcxBeNwXSD830Sz3o07kgIdXTbZNNVGpaPeCIGGV8=";
 
   src = fetchFromGitHub {
     owner = "rust-analyzer";
     repo = "rust-analyzer";
     rev = version;
-    sha256 = "sha256-f8jdBL42+bU8KKchkW4fF6+kDBjgpoOZyP5yOYsebBk=";
+    sha256 = "sha256-nL5lSvxpOS+fw4iH/Gnl/DI86T9tUtguOy+wLGRkoeY=";
   };
 
+  patches = [
+    # We have rustc 1.52.1 in nixpkgs.
+    ./no-rust-1-53-features.patch
+  ];
+
   buildAndTestSubdir = "crates/rust-analyzer";
 
   cargoBuildFlags = lib.optional useMimalloc "--features=mimalloc";
diff --git a/pkgs/development/tools/rust/rust-analyzer/no-rust-1-53-features.patch b/pkgs/development/tools/rust/rust-analyzer/no-rust-1-53-features.patch
new file mode 100644
index 00000000000..9fa54e8a903
--- /dev/null
+++ b/pkgs/development/tools/rust/rust-analyzer/no-rust-1-53-features.patch
@@ -0,0 +1,673 @@
+diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
+index 43162797e..613266e07 100644
+--- a/crates/hir/src/semantics.rs
++++ b/crates/hir/src/semantics.rs
+@@ -51,14 +51,12 @@ impl PathResolution {
+             PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
+                 Some(TypeNs::BuiltinType((*builtin).into()))
+             }
+-            PathResolution::Def(
+-                ModuleDef::Const(_)
+-                | ModuleDef::Variant(_)
+-                | ModuleDef::Function(_)
+-                | ModuleDef::Module(_)
+-                | ModuleDef::Static(_)
+-                | ModuleDef::Trait(_),
+-            ) => None,
++            PathResolution::Def(ModuleDef::Const(_))
++            | PathResolution::Def(ModuleDef::Variant(_))
++            | PathResolution::Def(ModuleDef::Function(_))
++            | PathResolution::Def(ModuleDef::Module(_))
++            | PathResolution::Def(ModuleDef::Static(_))
++            | PathResolution::Def(ModuleDef::Trait(_)) => None,
+             PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
+                 Some(TypeNs::TypeAliasId((*alias).into()))
+             }
+@@ -67,7 +65,8 @@ impl PathResolution {
+             }
+             PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
+             PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
+-            PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
++            PathResolution::AssocItem(AssocItem::Const(_))
++            | PathResolution::AssocItem(AssocItem::Function(_)) => None,
+             PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
+                 Some(TypeNs::TypeAliasId((*alias).into()))
+             }
+diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
+index e63bc8232..b1e1b70d0 100644
+--- a/crates/hir_def/src/item_tree/pretty.rs
++++ b/crates/hir_def/src/item_tree/pretty.rs
+@@ -63,7 +63,7 @@ impl<'a> Printer<'a> {
+     fn blank(&mut self) {
+         let mut iter = self.buf.chars().rev().fuse();
+         match (iter.next(), iter.next()) {
+-            (Some('\n'), Some('\n') | None) | (None, None) => {}
++            (Some('\n'), Some('\n')) | (Some('\n'), None) | (None, None) => {}
+             (Some('\n'), Some(_)) => {
+                 self.buf.push('\n');
+             }
+@@ -77,7 +77,7 @@ impl<'a> Printer<'a> {
+ 
+     fn whitespace(&mut self) {
+         match self.buf.chars().next_back() {
+-            None | Some('\n' | ' ') => {}
++            None | Some('\n') | Some(' ') => {}
+             _ => self.buf.push(' '),
+         }
+     }
+diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
+index 927a7b6e8..fc2c50fb8 100644
+--- a/crates/hir_def/src/nameres/collector.rs
++++ b/crates/hir_def/src/nameres/collector.rs
+@@ -1260,7 +1260,7 @@ impl DefCollector<'_> {
+         for directive in &self.unresolved_imports {
+             if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
+                 match (directive.import.path.segments().first(), &directive.import.path.kind) {
+-                    (Some(krate), PathKind::Plain | PathKind::Abs) => {
++                    (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
+                         if diagnosed_extern_crates.contains(krate) {
+                             continue;
+                         }
+diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
+index 49c573087..5edd93a2a 100644
+--- a/crates/hir_def/src/resolver.rs
++++ b/crates/hir_def/src/resolver.rs
+@@ -605,7 +605,8 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
+         ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
+         ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
+ 
+-        ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_))
++        ModuleDefId::AdtId(AdtId::EnumId(_))
++        | ModuleDefId::AdtId(AdtId::UnionId(_))
+         | ModuleDefId::TraitId(_)
+         | ModuleDefId::TypeAliasId(_)
+         | ModuleDefId::BuiltinType(_)
+diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs
+index aeb1e7726..83500f54e 100644
+--- a/crates/hir_def/src/visibility.rs
++++ b/crates/hir_def/src/visibility.rs
+@@ -172,8 +172,9 @@ impl Visibility {
+     /// visible in unrelated modules).
+     pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
+         match (self, other) {
+-            (Visibility::Module(_) | Visibility::Public, Visibility::Public)
+-            | (Visibility::Public, Visibility::Module(_)) => Some(Visibility::Public),
++            (Visibility::Module(_), Visibility::Public)
++            | (Visibility::Public, Visibility::Module(_))
++            | (Visibility::Public, Visibility::Public) => Some(Visibility::Public),
+             (Visibility::Module(mod_a), Visibility::Module(mod_b)) => {
+                 if mod_a.krate != mod_b.krate {
+                     return None;
+diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
+index 848522411..05c6c3fb1 100644
+--- a/crates/hir_expand/src/hygiene.rs
++++ b/crates/hir_expand/src/hygiene.rs
+@@ -146,11 +146,10 @@ impl HygieneInfo {
+                 (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start))
+             }
+             mbe::Origin::Def => match (&*self.macro_def, self.def_start) {
+-                (
+-                    TokenExpander::MacroDef { def_site_token_map, .. }
+-                    | TokenExpander::MacroRules { def_site_token_map, .. },
+-                    Some(tt),
+-                ) => (def_site_token_map, tt),
++                (TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt))
++                | (TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) => {
++                    (def_site_token_map, tt)
++                }
+                 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
+             },
+         };
+diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
+index c31426d7c..33107aa24 100644
+--- a/crates/hir_expand/src/lib.rs
++++ b/crates/hir_expand/src/lib.rs
+@@ -368,11 +368,10 @@ impl ExpansionInfo {
+         let (token_map, tt) = match origin {
+             mbe::Origin::Call => (&self.macro_arg.1, self.arg.clone()),
+             mbe::Origin::Def => match (&*self.macro_def, self.def.as_ref()) {
+-                (
+-                    db::TokenExpander::MacroRules { def_site_token_map, .. }
+-                    | db::TokenExpander::MacroDef { def_site_token_map, .. },
+-                    Some(tt),
+-                ) => (def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone())),
++                (db::TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt))
++                | (db::TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) => {
++                    (def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone()))
++                }
+                 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
+             },
+         };
+diff --git a/crates/hir_ty/src/consteval.rs b/crates/hir_ty/src/consteval.rs
+index ab1afce08..6f0bf8f8c 100644
+--- a/crates/hir_ty/src/consteval.rs
++++ b/crates/hir_ty/src/consteval.rs
+@@ -38,7 +38,8 @@ impl ConstExt for Const {
+ // FIXME: support more than just evaluating literals
+ pub fn eval_usize(expr: &Expr) -> Option<u64> {
+     match expr {
+-        Expr::Literal(Literal::Uint(v, None | Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
++        Expr::Literal(Literal::Uint(v, None))
++        | Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
+         _ => None,
+     }
+ }
+diff --git a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
+index e3d640a79..471cd4921 100644
+--- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
++++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
+@@ -84,7 +84,10 @@ impl IntRange {
+     #[inline]
+     fn is_integral(ty: &Ty) -> bool {
+         match ty.kind(&Interner) {
+-            TyKind::Scalar(Scalar::Char | Scalar::Int(_) | Scalar::Uint(_) | Scalar::Bool) => true,
++            TyKind::Scalar(Scalar::Char)
++            | TyKind::Scalar(Scalar::Int(_))
++            | TyKind::Scalar(Scalar::Uint(_))
++            | TyKind::Scalar(Scalar::Bool) => true,
+             _ => false,
+         }
+     }
+@@ -378,7 +381,7 @@ impl Constructor {
+             // Wildcards cover anything
+             (_, Wildcard) => true,
+             // The missing ctors are not covered by anything in the matrix except wildcards.
+-            (Missing | Wildcard, _) => false,
++            (Missing, _) | (Wildcard, _) => false,
+ 
+             (Single, Single) => true,
+             (Variant(self_id), Variant(other_id)) => self_id == other_id,
+@@ -520,7 +523,7 @@ impl SplitWildcard {
+                 }
+             }
+             TyKind::Scalar(Scalar::Char) => unhandled(),
+-            TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(),
++            TyKind::Scalar(Scalar::Int(..)) | TyKind::Scalar(Scalar::Uint(..)) => unhandled(),
+             TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => {
+                 smallvec![NonExhaustive]
+             }
+diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
+index 7be914451..4b7f31521 100644
+--- a/crates/hir_ty/src/infer/coerce.rs
++++ b/crates/hir_ty/src/infer/coerce.rs
+@@ -47,7 +47,10 @@ impl<'a> InferenceContext<'a> {
+         // pointers to have a chance at getting a match. See
+         // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
+         let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) {
+-            (TyKind::FnDef(..) | TyKind::Closure(..), TyKind::FnDef(..) | TyKind::Closure(..)) => {
++            (TyKind::FnDef(..), TyKind::FnDef(..))
++            | (TyKind::Closure(..), TyKind::FnDef(..))
++            | (TyKind::FnDef(..), TyKind::Closure(..))
++            | (TyKind::Closure(..), TyKind::Closure(..)) => {
+                 // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure,
+                 // we should be coercing the closure to a fn pointer of the safety of the FnDef
+                 cov_mark::hit!(coerce_fn_reification);
+@@ -445,7 +448,8 @@ fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
+ 
+ fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
+     match (from, to) {
+-        (Mutability::Mut, Mutability::Mut | Mutability::Not)
++        (Mutability::Mut, Mutability::Mut)
++        | (Mutability::Mut, Mutability::Not)
+         | (Mutability::Not, Mutability::Not) => Ok(()),
+         (Mutability::Not, Mutability::Mut) => Err(TypeError),
+     }
+diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
+index c3a5b979f..346e94128 100644
+--- a/crates/hir_ty/src/infer/expr.rs
++++ b/crates/hir_ty/src/infer/expr.rs
+@@ -593,11 +593,11 @@ impl<'a> InferenceContext<'a> {
+                     UnaryOp::Neg => {
+                         match inner_ty.kind(&Interner) {
+                             // Fast path for builtins
+-                            TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
+-                            | TyKind::InferenceVar(
+-                                _,
+-                                TyVariableKind::Integer | TyVariableKind::Float,
+-                            ) => inner_ty,
++                            TyKind::Scalar(Scalar::Int(_))
++                            | TyKind::Scalar(Scalar::Uint(_))
++                            | TyKind::Scalar(Scalar::Float(_))
++                            | TyKind::InferenceVar(_, TyVariableKind::Integer)
++                            | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty,
+                             // Otherwise we resolve via the std::ops::Neg trait
+                             _ => self
+                                 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
+@@ -606,7 +606,9 @@ impl<'a> InferenceContext<'a> {
+                     UnaryOp::Not => {
+                         match inner_ty.kind(&Interner) {
+                             // Fast path for builtins
+-                            TyKind::Scalar(Scalar::Bool | Scalar::Int(_) | Scalar::Uint(_))
++                            TyKind::Scalar(Scalar::Bool)
++                            | TyKind::Scalar(Scalar::Int(_))
++                            | TyKind::Scalar(Scalar::Uint(_))
+                             | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
+                             // Otherwise we resolve via the std::ops::Not trait
+                             _ => self
+@@ -733,7 +735,7 @@ impl<'a> InferenceContext<'a> {
+             Expr::Array(array) => {
+                 let elem_ty =
+                     match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) {
+-                        Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st.clone(),
++                        Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(),
+                         _ => self.table.new_type_var(),
+                     };
+ 
+diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
+index c79ed91ea..80ecd4ea9 100644
+--- a/crates/hir_ty/src/infer/pat.rs
++++ b/crates/hir_ty/src/infer/pat.rs
+@@ -297,11 +297,10 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
+             Expr::Literal(Literal::String(..)) => false,
+             _ => true,
+         },
+-        Pat::Bind {
+-            mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
+-            subpat: Some(subpat),
+-            ..
+-        } => is_non_ref_pat(body, *subpat),
++        Pat::Bind { mode: BindingAnnotation::Mutable, subpat: Some(subpat), .. }
++        | Pat::Bind { mode: BindingAnnotation::Unannotated, subpat: Some(subpat), .. } => {
++            is_non_ref_pat(body, *subpat)
++        }
+         Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
+     }
+ }
+diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
+index 5ef6342d5..0222de2bc 100644
+--- a/crates/hir_ty/src/op.rs
++++ b/crates/hir_ty/src/op.rs
+@@ -8,15 +8,17 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
+     match op {
+         BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
+         BinaryOp::Assignment { .. } => TyBuilder::unit(),
+-        BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => {
++        BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
+             // all integer combinations are valid here
+             if matches!(
+                 lhs_ty.kind(&Interner),
+-                TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
++                TyKind::Scalar(Scalar::Int(_))
++                    | TyKind::Scalar(Scalar::Uint(_))
+                     | TyKind::InferenceVar(_, TyVariableKind::Integer)
+             ) && matches!(
+                 rhs_ty.kind(&Interner),
+-                TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
++                TyKind::Scalar(Scalar::Int(_))
++                    | TyKind::Scalar(Scalar::Uint(_))
+                     | TyKind::InferenceVar(_, TyVariableKind::Integer)
+             ) {
+                 lhs_ty
+@@ -30,15 +32,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
+             | (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_)))
+             | (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty,
+             // ({int}, int) | ({int}, uint)
+-            (
+-                TyKind::InferenceVar(_, TyVariableKind::Integer),
+-                TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
+-            ) => rhs_ty,
++            (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Int(_)))
++            | (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Uint(_))) => {
++                rhs_ty
++            }
+             // (int, {int}) | (uint, {int})
+-            (
+-                TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
+-                TyKind::InferenceVar(_, TyVariableKind::Integer),
+-            ) => lhs_ty,
++            (TyKind::Scalar(Scalar::Int(_)), TyKind::InferenceVar(_, TyVariableKind::Integer))
++            | (TyKind::Scalar(Scalar::Uint(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) => {
++                lhs_ty
++            }
+             // ({float} | float)
+             (TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => {
+                 rhs_ty
+@@ -67,15 +69,21 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
+         BinaryOp::Assignment { op: None } => lhs_ty,
+         BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) {
+             TyKind::Scalar(_) | TyKind::Str => lhs_ty,
+-            TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
++            TyKind::InferenceVar(_, TyVariableKind::Integer)
++            | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
+             _ => TyKind::Error.intern(&Interner),
+         },
+-        BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => TyKind::Error.intern(&Interner),
++        BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
++            TyKind::Error.intern(&Interner)
++        }
+         BinaryOp::CmpOp(CmpOp::Ord { .. })
+         | BinaryOp::Assignment { op: Some(_) }
+         | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) {
+-            TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_)) => lhs_ty,
+-            TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
++            TyKind::Scalar(Scalar::Int(_))
++            | TyKind::Scalar(Scalar::Uint(_))
++            | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
++            TyKind::InferenceVar(_, TyVariableKind::Integer)
++            | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
+             _ => TyKind::Error.intern(&Interner),
+         },
+     }
+diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
+index ffa8bd182..93d3760bf 100644
+--- a/crates/ide/src/join_lines.rs
++++ b/crates/ide/src/join_lines.rs
+@@ -197,7 +197,7 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Opti
+ }
+ 
+ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
+-    matches!((left, right), (T![,], T![')'] | T![']']))
++    matches!((left, right), (T![,], T![')']) | (T![,], T![']']))
+ }
+ 
+ fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
+diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
+index 5808562a7..945c9b9e1 100644
+--- a/crates/ide/src/references.rs
++++ b/crates/ide/src/references.rs
+@@ -79,7 +79,8 @@ pub(crate) fn find_all_refs(
+                 });
+                 usages.references.retain(|_, it| !it.is_empty());
+             }
+-            Definition::ModuleDef(hir::ModuleDef::Adt(_) | hir::ModuleDef::Variant(_)) => {
++            Definition::ModuleDef(hir::ModuleDef::Adt(_))
++            | Definition::ModuleDef(hir::ModuleDef::Variant(_)) => {
+                 refs.for_each(|it| {
+                     it.retain(|reference| {
+                         reference.name.as_name_ref().map_or(false, is_lit_name_ref)
+diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
+index d44a1b45f..e186b82b7 100644
+--- a/crates/ide/src/syntax_highlighting.rs
++++ b/crates/ide/src/syntax_highlighting.rs
+@@ -294,7 +294,7 @@ fn traverse(
+                 Some(parent) => {
+                     // We only care Name and Name_ref
+                     match (token.kind(), parent.kind()) {
+-                        (IDENT, NAME | NAME_REF) => parent.into(),
++                        (IDENT, NAME) | (IDENT, NAME_REF) => parent.into(),
+                         _ => token.into(),
+                     }
+                 }
+@@ -310,7 +310,7 @@ fn traverse(
+                 Some(parent) => {
+                     // We only care Name and Name_ref
+                     match (token.kind(), parent.kind()) {
+-                        (IDENT, NAME | NAME_REF) => parent.into(),
++                        (IDENT, NAME) | (IDENT, NAME_REF) => parent.into(),
+                         _ => token.into(),
+                     }
+                 }
+diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
+index ac7f0959b..9b78cf4b1 100644
+--- a/crates/ide_assists/src/handlers/extract_function.rs
++++ b/crates/ide_assists/src/handlers/extract_function.rs
+@@ -1384,7 +1384,7 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode)
+     for (param, usages) in usages_for_param {
+         for usage in usages {
+             match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
+-                Some(ast::Expr::MethodCallExpr(_) | ast::Expr::FieldExpr(_)) => {
++                Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => {
+                     // do nothing
+                 }
+                 Some(ast::Expr::RefExpr(node))
+diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
+index 841537c77..d9d9124b6 100644
+--- a/crates/ide_assists/src/tests.rs
++++ b/crates/ide_assists/src/tests.rs
+@@ -181,10 +181,9 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
+             "unresolved assist should not contain source changes"
+         ),
+         (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
+-        (
+-            None,
+-            ExpectedResult::After(_) | ExpectedResult::Target(_) | ExpectedResult::Unresolved,
+-        ) => {
++        (None, ExpectedResult::After(_))
++        | (None, ExpectedResult::Target(_))
++        | (None, ExpectedResult::Unresolved) => {
+             panic!("code action is not applicable")
+         }
+         (None, ExpectedResult::NotApplicable) => (),
+diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
+index f5dbd203b..88f4d940d 100644
+--- a/crates/ide_completion/src/completions/qualified_path.rs
++++ b/crates/ide_completion/src/completions/qualified_path.rs
+@@ -65,11 +65,9 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
+                     // Don't suggest attribute macros and derives.
+                     hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
+                     // no values in type places
+-                    hir::ScopeDef::ModuleDef(
+-                        hir::ModuleDef::Function(_)
+-                        | hir::ModuleDef::Variant(_)
+-                        | hir::ModuleDef::Static(_),
+-                    )
++                    hir::ScopeDef::ModuleDef(hir::ModuleDef::Function(_))
++                    | hir::ScopeDef::ModuleDef(hir::ModuleDef::Variant(_))
++                    | hir::ScopeDef::ModuleDef(hir::ModuleDef::Static(_))
+                     | hir::ScopeDef::Local(_) => !ctx.expects_type(),
+                     // unless its a constant in a generic arg list position
+                     hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => {
+@@ -83,13 +81,9 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
+                 }
+             }
+         }
+-        hir::PathResolution::Def(
+-            def
+-            @
+-            (hir::ModuleDef::Adt(_)
+-            | hir::ModuleDef::TypeAlias(_)
+-            | hir::ModuleDef::BuiltinType(_)),
+-        ) => {
++        hir::PathResolution::Def(def @ hir::ModuleDef::Adt(_))
++        | hir::PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_))
++        | hir::PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => {
+             if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
+                 add_enum_variants(acc, ctx, e);
+             }
+diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
+index 81c4fb305..8ea5a2d5b 100644
+--- a/crates/ide_completion/src/completions/unqualified_path.rs
++++ b/crates/ide_completion/src/completions/unqualified_path.rs
+@@ -74,11 +74,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
+             // Don't suggest attribute macros and derives.
+             ScopeDef::MacroDef(mac) => mac.is_fn_like(),
+             // no values in type places
+-            ScopeDef::ModuleDef(
+-                hir::ModuleDef::Function(_)
+-                | hir::ModuleDef::Variant(_)
+-                | hir::ModuleDef::Static(_),
+-            )
++            ScopeDef::ModuleDef(hir::ModuleDef::Function(_))
++            | ScopeDef::ModuleDef(hir::ModuleDef::Variant(_))
++            | ScopeDef::ModuleDef(hir::ModuleDef::Static(_))
+             | ScopeDef::Local(_) => !ctx.expects_type(),
+             // unless its a constant in a generic arg list position
+             ScopeDef::ModuleDef(hir::ModuleDef::Const(_))
+diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
+index 7b76600df..09eb953fd 100644
+--- a/crates/ide_completion/src/context.rs
++++ b/crates/ide_completion/src/context.rs
+@@ -242,23 +242,24 @@ impl<'a> CompletionContext<'a> {
+     }
+ 
+     pub(crate) fn expects_assoc_item(&self) -> bool {
+-        matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
++        matches!(
++            self.completion_location,
++            Some(ImmediateLocation::Trait) | Some(ImmediateLocation::Impl)
++        )
+     }
+ 
+     pub(crate) fn has_dot_receiver(&self) -> bool {
+         matches!(
+             &self.completion_location,
+-            Some(ImmediateLocation::FieldAccess { receiver, .. } | ImmediateLocation::MethodCall { receiver,.. })
++            Some(ImmediateLocation::FieldAccess { receiver, .. }) | Some(ImmediateLocation::MethodCall { receiver,.. })
+                 if receiver.is_some()
+         )
+     }
+ 
+     pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
+         match &self.completion_location {
+-            Some(
+-                ImmediateLocation::MethodCall { receiver, .. }
+-                | ImmediateLocation::FieldAccess { receiver, .. },
+-            ) => receiver.as_ref(),
++            Some(ImmediateLocation::MethodCall { receiver, .. })
++            | Some(ImmediateLocation::FieldAccess { receiver, .. }) => receiver.as_ref(),
+             _ => None,
+         }
+     }
+@@ -282,7 +283,7 @@ impl<'a> CompletionContext<'a> {
+     pub(crate) fn expects_ident_pat_or_ref_expr(&self) -> bool {
+         matches!(
+             self.completion_location,
+-            Some(ImmediateLocation::IdentPat | ImmediateLocation::RefExpr)
++            Some(ImmediateLocation::IdentPat) | Some(ImmediateLocation::RefExpr)
+         )
+     }
+ 
+@@ -293,14 +294,14 @@ impl<'a> CompletionContext<'a> {
+     pub(crate) fn in_use_tree(&self) -> bool {
+         matches!(
+             self.completion_location,
+-            Some(ImmediateLocation::Use | ImmediateLocation::UseTree)
++            Some(ImmediateLocation::Use) | Some(ImmediateLocation::UseTree)
+         )
+     }
+ 
+     pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
+         matches!(
+             self.prev_sibling,
+-            Some(ImmediatePrevSibling::ImplDefType | ImmediatePrevSibling::TraitDefName)
++            Some(ImmediatePrevSibling::ImplDefType) | Some(ImmediatePrevSibling::TraitDefName)
+         )
+     }
+ 
+@@ -321,16 +322,14 @@ impl<'a> CompletionContext<'a> {
+             || self.previous_token_is(T![unsafe])
+             || matches!(
+                 self.prev_sibling,
+-                Some(ImmediatePrevSibling::Attribute | ImmediatePrevSibling::Visibility)
++                Some(ImmediatePrevSibling::Attribute) | Some(ImmediatePrevSibling::Visibility)
+             )
+             || matches!(
+                 self.completion_location,
+-                Some(
+-                    ImmediateLocation::Attribute(_)
+-                        | ImmediateLocation::ModDeclaration(_)
+-                        | ImmediateLocation::RecordPat(_)
+-                        | ImmediateLocation::RecordExpr(_)
+-                )
++                Some(ImmediateLocation::Attribute(_))
++                    | Some(ImmediateLocation::ModDeclaration(_))
++                    | Some(ImmediateLocation::RecordPat(_))
++                    | Some(ImmediateLocation::RecordExpr(_))
+             )
+     }
+ 
+@@ -704,8 +703,8 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
+ 
+ fn has_ref(token: &SyntaxToken) -> bool {
+     let mut token = token.clone();
+-    for skip in [WHITESPACE, IDENT, T![mut]] {
+-        if token.kind() == skip {
++    for skip in &[WHITESPACE, IDENT, T![mut]] {
++        if token.kind() == *skip {
+             token = match token.prev_token() {
+                 Some(it) => it,
+                 None => return false,
+diff --git a/crates/ide_completion/src/render/builder_ext.rs b/crates/ide_completion/src/render/builder_ext.rs
+index 33d3a5ee1..749dfc665 100644
+--- a/crates/ide_completion/src/render/builder_ext.rs
++++ b/crates/ide_completion/src/render/builder_ext.rs
+@@ -32,7 +32,7 @@ impl Builder {
+             cov_mark::hit!(no_parens_in_use_item);
+             return false;
+         }
+-        if matches!(ctx.path_call_kind(), Some(CallKind::Expr | CallKind::Pat))
++        if matches!(ctx.path_call_kind(), Some(CallKind::Expr) | Some(CallKind::Pat))
+             | matches!(
+                 ctx.completion_location,
+                 Some(ImmediateLocation::MethodCall { has_parens: true, .. })
+diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
+index b4f2fe9a4..c2a9a38c9 100644
+--- a/crates/mbe/src/expander/matcher.rs
++++ b/crates/mbe/src/expander/matcher.rs
+@@ -804,17 +804,33 @@ impl<'a> TtIter<'a> {
+         };
+ 
+         match (punct.char, second, third) {
+-            ('.', '.', Some('.' | '=')) | ('<', '<', Some('=')) | ('>', '>', Some('=')) => {
++            ('.', '.', Some('.'))
++            | ('.', '.', Some('='))
++            | ('<', '<', Some('='))
++            | ('>', '>', Some('=')) => {
+                 let tt2 = self.next().unwrap().clone();
+                 let tt3 = self.next().unwrap().clone();
+                 Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2, tt3] }.into())
+             }
+-            ('-' | '!' | '*' | '/' | '&' | '%' | '^' | '+' | '<' | '=' | '>' | '|', '=', _)
+-            | ('-' | '=' | '>', '>', _)
++            ('-', '=', _)
++            | ('-', '>', _)
+             | (':', ':', _)
++            | ('!', '=', _)
+             | ('.', '.', _)
++            | ('*', '=', _)
++            | ('/', '=', _)
+             | ('&', '&', _)
++            | ('&', '=', _)
++            | ('%', '=', _)
++            | ('^', '=', _)
++            | ('+', '=', _)
+             | ('<', '<', _)
++            | ('<', '=', _)
++            | ('=', '=', _)
++            | ('=', '>', _)
++            | ('>', '=', _)
++            | ('>', '>', _)
++            | ('|', '=', _)
+             | ('|', '|', _) => {
+                 let tt2 = self.next().unwrap().clone();
+                 Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2] }.into())
+diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
+index 5a78675fb..e0c1d3b3a 100644
+--- a/crates/parser/src/grammar/params.rs
++++ b/crates/parser/src/grammar/params.rs
+@@ -184,7 +184,8 @@ fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> {
+         if !matches!(
+             (p.current(), la1, la2, la3),
+             (T![&], T![self], _, _)
+-                | (T![&], T![mut] | LIFETIME_IDENT, T![self], _)
++                | (T![&], LIFETIME_IDENT, T![self], _)
++                | (T![&], T![mut], T![self], _)
+                 | (T![&], LIFETIME_IDENT, T![mut], T![self])
+         ) {
+             return Err(m);
+diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
+index ef2d7657a..2b3d7fd84 100644
+--- a/crates/vfs/src/vfs_path.rs
++++ b/crates/vfs/src/vfs_path.rs
+@@ -389,7 +389,7 @@ impl VirtualPath {
+ 
+             match (file_stem, extension) {
+                 (None, None) => None,
+-                (None | Some(""), Some(_)) => Some((file_name, None)),
++                (None, Some(_)) | (Some(""), Some(_)) => Some((file_name, None)),
+                 (Some(file_stem), extension) => Some((file_stem, extension)),
+             }
+         }
+diff --git a/xtask/src/install.rs b/xtask/src/install.rs
+index 64ab12b42..7e2dccdfe 100644
+--- a/xtask/src/install.rs
++++ b/xtask/src/install.rs
+@@ -8,7 +8,7 @@ use xshell::{cmd, pushd};
+ use crate::flags;
+ 
+ // Latest stable, feel free to send a PR if this lags behind.
+-const REQUIRED_RUST_VERSION: u32 = 53;
++const REQUIRED_RUST_VERSION: u32 = 52;
+ 
+ impl flags::Install {
+     pub(crate) fn run(self) -> Result<()> {
diff --git a/pkgs/development/tools/rust/rust-analyzer/update.sh b/pkgs/development/tools/rust/rust-analyzer/update.sh
index a67b6c927a8..3010b9bf385 100755
--- a/pkgs/development/tools/rust/rust-analyzer/update.sh
+++ b/pkgs/development/tools/rust/rust-analyzer/update.sh
@@ -51,6 +51,9 @@ build_deps="../../../../misc/vscode-extensions/rust-analyzer/build-deps"
 jq '{ name, version, dependencies: (.dependencies + .devDependencies) }' "$node_src/package.json" \
     >"$build_deps/package.json.new"
 
+# FIXME: vsce@1.93.0 breaks the build.
+sed 's/"vsce": ".*"/"vsce": "=1.88.0"/' --in-place "$build_deps/package.json.new"
+
 if cmp --quiet "$build_deps"/package.json{.new,}; then
     echo "package.json not changed, skip updating nodePackages"
     rm "$build_deps"/package.json.new