about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-11 15:05:26 +0000
committerbors <bors@rust-lang.org>2024-06-11 15:05:26 +0000
commit5e1ab70dffc12895e984a3a1f87e6794d14c31f0 (patch)
tree49dd57dd152d1c8faa3c21f11164646c048a5c9d
parent21e9022cda994aa7304a8bac38dc659630be254b (diff)
parent36caa43ec1fb3bf16e6f8dbb050d16a7e90f6028 (diff)
downloadrust-5e1ab70dffc12895e984a3a1f87e6794d14c31f0.tar.gz
rust-5e1ab70dffc12895e984a3a1f87e6794d14c31f0.zip
Auto merge of #17394 - Veykril:recurse-fix, r=Veykril
fix: Fix `HirDisplay` stackoverflow for parameter Self defaults

Fixes https://github.com/rust-lang/rust-analyzer/issues/10932
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs43
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs21
2 files changed, 48 insertions, 16 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 5e3996f65ab..ff78fe0d54e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -4,7 +4,7 @@
 
 use std::{
     fmt::{self, Debug},
-    mem::size_of,
+    mem::{self, size_of},
 };
 
 use base_db::CrateId;
@@ -460,7 +460,7 @@ impl HirDisplay for ProjectionTy {
         let proj_params_count =
             self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
         let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
-        hir_fmt_generics(f, proj_params, None)
+        hir_fmt_generics(f, proj_params, None, None)
     }
 }
 
@@ -505,6 +505,7 @@ impl HirDisplay for Const {
                         f,
                         parameters.as_slice(Interner),
                         c.generic_def(f.db.upcast()),
+                        None,
                     )?;
                     Ok(())
                 }
@@ -1004,11 +1005,11 @@ impl HirDisplay for Ty {
                         let fn_params = generic_args_sans_defaults(f, Some(def.into()), fn_params);
 
                         write!(f, "<")?;
-                        hir_fmt_generic_arguments(f, parent_params)?;
+                        hir_fmt_generic_arguments(f, parent_params, None)?;
                         if !parent_params.is_empty() && !fn_params.is_empty() {
                             write!(f, ", ")?;
                         }
-                        hir_fmt_generic_arguments(f, fn_params)?;
+                        hir_fmt_generic_arguments(f, fn_params, None)?;
                         write!(f, ">")?;
                     }
                 }
@@ -1053,7 +1054,7 @@ impl HirDisplay for Ty {
 
                 let generic_def = self.as_generic_def(db);
 
-                hir_fmt_generics(f, parameters.as_slice(Interner), generic_def)?;
+                hir_fmt_generics(f, parameters.as_slice(Interner), generic_def, None)?;
             }
             TyKind::AssociatedType(assoc_type_id, parameters) => {
                 let type_alias = from_assoc_type_id(*assoc_type_id);
@@ -1076,7 +1077,7 @@ impl HirDisplay for Ty {
                     f.end_location_link();
                     // Note that the generic args for the associated type come before those for the
                     // trait (including the self type).
-                    hir_fmt_generics(f, parameters.as_slice(Interner), None)
+                    hir_fmt_generics(f, parameters.as_slice(Interner), None, None)
                 } else {
                     let projection_ty = ProjectionTy {
                         associated_ty_id: to_assoc_type_id(type_alias),
@@ -1178,7 +1179,7 @@ impl HirDisplay for Ty {
                     }
                     ClosureStyle::ClosureWithSubst => {
                         write!(f, "{{closure#{:?}}}", id.0.as_u32())?;
-                        return hir_fmt_generics(f, substs.as_slice(Interner), None);
+                        return hir_fmt_generics(f, substs.as_slice(Interner), None, None);
                     }
                     _ => (),
                 }
@@ -1366,6 +1367,7 @@ fn hir_fmt_generics(
     f: &mut HirFormatter<'_>,
     parameters: &[GenericArg],
     generic_def: Option<hir_def::GenericDefId>,
+    self_: Option<&Ty>,
 ) -> Result<(), HirDisplayError> {
     if parameters.is_empty() {
         return Ok(());
@@ -1385,7 +1387,7 @@ fn hir_fmt_generics(
         });
     if !parameters_to_write.is_empty() && !only_err_lifetimes {
         write!(f, "<")?;
-        hir_fmt_generic_arguments(f, parameters_to_write)?;
+        hir_fmt_generic_arguments(f, parameters_to_write, self_)?;
         write!(f, ">")?;
     }
 
@@ -1447,6 +1449,7 @@ fn generic_args_sans_defaults<'ga>(
 fn hir_fmt_generic_arguments(
     f: &mut HirFormatter<'_>,
     parameters: &[GenericArg],
+    self_: Option<&Ty>,
 ) -> Result<(), HirDisplayError> {
     let mut first = true;
     let lifetime_offset = parameters.iter().position(|arg| arg.lifetime(Interner).is_some());
@@ -1468,11 +1471,13 @@ fn hir_fmt_generic_arguments(
             continue;
         }
 
-        if !first {
+        if !mem::take(&mut first) {
             write!(f, ", ")?;
         }
-        first = false;
-        generic_arg.hir_fmt(f)?;
+        match self_ {
+            self_ @ Some(_) if generic_arg.ty(Interner) == self_ => write!(f, "Self")?,
+            _ => generic_arg.hir_fmt(f)?,
+        }
     }
     Ok(())
 }
@@ -1595,12 +1600,16 @@ fn write_bounds_like_dyn_trait(
                 write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
                 f.end_location_link();
                 if is_fn_trait {
-                    if let [_self, params @ ..] = trait_ref.substitution.as_slice(Interner) {
+                    if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner) {
                         if let Some(args) =
                             params.first().and_then(|it| it.assert_ty_ref(Interner).as_tuple())
                         {
                             write!(f, "(")?;
-                            hir_fmt_generic_arguments(f, args.as_slice(Interner))?;
+                            hir_fmt_generic_arguments(
+                                f,
+                                args.as_slice(Interner),
+                                self_.ty(Interner),
+                            )?;
                             write!(f, ")")?;
                         }
                     }
@@ -1610,10 +1619,10 @@ fn write_bounds_like_dyn_trait(
                         Some(trait_.into()),
                         trait_ref.substitution.as_slice(Interner),
                     );
-                    if let [_self, params @ ..] = params {
+                    if let [self_, params @ ..] = params {
                         if !params.is_empty() {
                             write!(f, "<")?;
-                            hir_fmt_generic_arguments(f, params)?;
+                            hir_fmt_generic_arguments(f, params, self_.ty(Interner))?;
                             // there might be assoc type bindings, so we leave the angle brackets open
                             angle_open = true;
                         }
@@ -1671,6 +1680,7 @@ fn write_bounds_like_dyn_trait(
                         hir_fmt_generic_arguments(
                             f,
                             &proj.substitution.as_slice(Interner)[..proj_arg_count],
+                            None,
                         )?;
                         write!(f, ">")?;
                     }
@@ -1727,7 +1737,8 @@ fn fmt_trait_ref(
     f.start_location_link(trait_.into());
     write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
     f.end_location_link();
-    hir_fmt_generics(f, &tr.substitution.as_slice(Interner)[1..], None)
+    let substs = tr.substitution.as_slice(Interner);
+    hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
 }
 
 impl HirDisplay for TraitRef {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index 20128a286f2..7932d8efbcf 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -709,4 +709,25 @@ fn main() {
             "#,
         )
     }
+
+    // regression test for a stackoverflow in hir display code
+    #[test]
+    fn adjustment_hints_method_call_on_impl_trait_self() {
+        check_with_config(
+            InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
+            r#"
+//- minicore: slice, coerce_unsized
+trait T<RHS = Self> {}
+
+fn hello(it: &&[impl T]) {
+    it.len();
+  //^^(
+  //^^&
+  //^^*
+  //^^*
+  //^^)
+}
+"#,
+        );
+    }
 }