]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #12058 - jonas-schievink:one-thread-with-extra-stack-please, r=jonas...
authorbors <bors@rust-lang.org>
Fri, 22 Apr 2022 15:46:30 +0000 (15:46 +0000)
committerbors <bors@rust-lang.org>
Fri, 22 Apr 2022 15:46:30 +0000 (15:46 +0000)
fix: Spawn a new thread with a larger stack for the LSP and proc-macro server

This runs the server and proc-macro process in dedicated threads with 8 MB of stack space to paper over OS differences and fix occasional stack overflows.

This hopefully resolves https://github.com/rust-lang/rust-analyzer/issues/11669

crates/hir_ty/src/lower.rs
crates/hir_ty/src/tests/regression.rs

index 24eff4cc9a9fcbfc67a4d3ba961750ebf3070c29..a3787728eac08835b4dab7af96e4704ea52111db 100644 (file)
@@ -681,23 +681,31 @@ fn substs_from_path_segment(
 
         let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
 
-        for eid in def_generics.iter_id().take(parent_params) {
-            match eid {
-                Either::Left(_) => substs.push(ty_error.clone()),
-                Either::Right(x) => {
-                    substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
+        let mut def_generic_iter = def_generics.iter_id();
+
+        for _ in 0..parent_params {
+            if let Some(eid) = def_generic_iter.next() {
+                match eid {
+                    Either::Left(_) => substs.push(ty_error.clone()),
+                    Either::Right(x) => {
+                        substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
+                    }
                 }
             }
         }
 
         let fill_self_params = || {
-            substs.extend(
-                explicit_self_ty
-                    .into_iter()
-                    .map(|x| GenericArgData::Ty(x).intern(Interner))
-                    .chain(iter::repeat(ty_error.clone()))
-                    .take(self_params),
-            )
+            for x in explicit_self_ty
+                .into_iter()
+                .map(|x| GenericArgData::Ty(x).intern(Interner))
+                .chain(iter::repeat(ty_error.clone()))
+                .take(self_params)
+            {
+                if let Some(id) = def_generic_iter.next() {
+                    assert!(id.is_left());
+                    substs.push(x);
+                }
+            }
         };
         let mut had_explicit_args = false;
 
@@ -712,34 +720,38 @@ fn substs_from_path_segment(
             };
             let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
             // if args are provided, it should be all of them, but we can't rely on that
-            for (arg, id) in generic_args
+            for arg in generic_args
                 .args
                 .iter()
                 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
                 .skip(skip)
                 .take(expected_num)
-                .zip(def_generics.iter_id().skip(parent_params + skip))
             {
-                if let Some(x) = generic_arg_to_chalk(
-                    self.db,
-                    id,
-                    arg,
-                    &mut (),
-                    |_, type_ref| self.lower_ty(type_ref),
-                    |_, c, ty| {
-                        const_or_path_to_chalk(
-                            self.db,
-                            &self.resolver,
-                            ty,
-                            c,
-                            self.type_param_mode,
-                            || self.generics(),
-                            self.in_binders,
-                        )
-                    },
-                ) {
-                    had_explicit_args = true;
-                    substs.push(x);
+                if let Some(id) = def_generic_iter.next() {
+                    if let Some(x) = generic_arg_to_chalk(
+                        self.db,
+                        id,
+                        arg,
+                        &mut (),
+                        |_, type_ref| self.lower_ty(type_ref),
+                        |_, c, ty| {
+                            const_or_path_to_chalk(
+                                self.db,
+                                &self.resolver,
+                                ty,
+                                c,
+                                self.type_param_mode,
+                                || self.generics(),
+                                self.in_binders,
+                            )
+                        },
+                    ) {
+                        had_explicit_args = true;
+                        substs.push(x);
+                    } else {
+                        // we just filtered them out
+                        never!("Unexpected lifetime argument");
+                    }
                 }
             }
         } else {
@@ -757,14 +769,16 @@ fn substs_from_path_segment(
                 for default_ty in defaults.iter().skip(substs.len()) {
                     // each default can depend on the previous parameters
                     let substs_so_far = Substitution::from_iter(Interner, substs.clone());
-                    substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
+                    if let Some(_id) = def_generic_iter.next() {
+                        substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
+                    }
                 }
             }
         }
 
         // add placeholders for args that were not provided
         // FIXME: emit diagnostics in contexts where this is not allowed
-        for eid in def_generics.iter_id().skip(substs.len()) {
+        for eid in def_generic_iter {
             match eid {
                 Either::Left(_) => substs.push(ty_error.clone()),
                 Either::Right(x) => {
@@ -772,6 +786,7 @@ fn substs_from_path_segment(
                 }
             }
         }
+        // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
         assert_eq!(substs.len(), total_len);
 
         Substitution::from_iter(Interner, substs)
@@ -1659,6 +1674,10 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
     }
 }
 
+/// Checks if the provided generic arg matches its expected kind, then lower them via
+/// provided closures. Use unknown if there was kind mismatch.
+///
+/// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
 pub(crate) fn generic_arg_to_chalk<'a, T>(
     db: &dyn HirDatabase,
     kind_id: Either<TypeParamId, ConstParamId>,
index c3c934c4680c1546abeabde089792d753c6dd7ed..ef27667ffa5729ee2c242a501ce17497afe0eadb 100644 (file)
@@ -1470,6 +1470,22 @@ fn dynamic_programming() {
     );
 }
 
+#[test]
+fn regression_11688_4() {
+    check_types(
+        r#"
+        trait Bar<const C: usize> {
+            fn baz(&self) -> [i32; C];
+        }
+
+        fn foo(x: &dyn Bar<2>) {
+            x.baz();
+          //^^^^^^^ [i32; 2]
+        }
+        "#,
+    )
+}
+
 #[test]
 fn gat_crash_1() {
     cov_mark::check!(ignore_gats);