about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorroife <roifewu@gmail.com>2024-06-11 20:59:06 +0800
committerroife <roifewu@gmail.com>2024-06-11 21:02:13 +0800
commit445e8866a3fa9a8614b82eebbdfdd04b433ebb9b (patch)
treef10731e875fce3e819ccbf00569fd79f850d4245 /src
parente5f859868e18f78073330d5d05548c98f7ce192a (diff)
downloadrust-445e8866a3fa9a8614b82eebbdfdd04b433ebb9b.tar.gz
rust-445e8866a3fa9a8614b82eebbdfdd04b433ebb9b.zip
feat: add hover config for showing container bounds
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs36
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs1
3 files changed, 60 insertions, 14 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 f035dd11e1f..5e3996f65ab 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -74,6 +74,8 @@ pub struct HirFormatter<'a> {
     /// When rendering something that has a concept of "children" (like fields in a struct), this limits
     /// how many should be rendered.
     pub entity_limit: Option<usize>,
+    /// When rendering functions, whether to show the constraint from the container
+    show_container_bounds: bool,
     omit_verbose_types: bool,
     closure_style: ClosureStyle,
     display_target: DisplayTarget,
@@ -101,6 +103,7 @@ pub trait HirDisplay {
         omit_verbose_types: bool,
         display_target: DisplayTarget,
         closure_style: ClosureStyle,
+        show_container_bounds: bool,
     ) -> HirDisplayWrapper<'a, Self>
     where
         Self: Sized,
@@ -117,6 +120,7 @@ pub trait HirDisplay {
             omit_verbose_types,
             display_target,
             closure_style,
+            show_container_bounds,
         }
     }
 
@@ -134,6 +138,7 @@ pub trait HirDisplay {
             omit_verbose_types: false,
             closure_style: ClosureStyle::ImplFn,
             display_target: DisplayTarget::Diagnostics,
+            show_container_bounds: false,
         }
     }
 
@@ -155,6 +160,7 @@ pub trait HirDisplay {
             omit_verbose_types: true,
             closure_style: ClosureStyle::ImplFn,
             display_target: DisplayTarget::Diagnostics,
+            show_container_bounds: false,
         }
     }
 
@@ -176,6 +182,7 @@ pub trait HirDisplay {
             omit_verbose_types: true,
             closure_style: ClosureStyle::ImplFn,
             display_target: DisplayTarget::Diagnostics,
+            show_container_bounds: false,
         }
     }
 
@@ -198,6 +205,7 @@ pub trait HirDisplay {
             omit_verbose_types: false,
             closure_style: ClosureStyle::ImplFn,
             display_target: DisplayTarget::SourceCode { module_id, allow_opaque },
+            show_container_bounds: false,
         }) {
             Ok(()) => {}
             Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
@@ -219,6 +227,29 @@ pub trait HirDisplay {
             omit_verbose_types: false,
             closure_style: ClosureStyle::ImplFn,
             display_target: DisplayTarget::Test,
+            show_container_bounds: false,
+        }
+    }
+
+    /// Returns a String representation of `self` that shows the constraint from
+    /// the container for functions
+    fn display_with_container_bounds<'a>(
+        &'a self,
+        db: &'a dyn HirDatabase,
+        show_container_bounds: bool,
+    ) -> HirDisplayWrapper<'a, Self>
+    where
+        Self: Sized,
+    {
+        HirDisplayWrapper {
+            db,
+            t: self,
+            max_size: None,
+            limited_size: None,
+            omit_verbose_types: false,
+            closure_style: ClosureStyle::ImplFn,
+            display_target: DisplayTarget::Diagnostics,
+            show_container_bounds,
         }
     }
 }
@@ -277,6 +308,10 @@ impl HirFormatter<'_> {
     pub fn omit_verbose_types(&self) -> bool {
         self.omit_verbose_types
     }
+
+    pub fn show_container_bounds(&self) -> bool {
+        self.show_container_bounds
+    }
 }
 
 #[derive(Clone, Copy)]
@@ -336,6 +371,7 @@ pub struct HirDisplayWrapper<'a, T> {
     omit_verbose_types: bool,
     closure_style: ClosureStyle,
     display_target: DisplayTarget,
+    show_container_bounds: bool,
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -365,6 +401,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
             omit_verbose_types: self.omit_verbose_types,
             display_target: self.display_target,
             closure_style: self.closure_style,
+            show_container_bounds: self.show_container_bounds,
         })
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 7e16fbf21e9..90deee0b01e 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -36,12 +36,16 @@ impl HirDisplay for Function {
 
         match container {
             Some(AssocItemContainer::Trait(trait_)) => {
-                write_trait_header(&trait_, f)?;
-                f.write_str("\n")?;
+                if f.show_container_bounds() {
+                    write_trait_header(&trait_, f)?;
+                    f.write_str("\n")?;
+                }
             }
             Some(AssocItemContainer::Impl(impl_)) => {
-                write_impl_header(&impl_, f)?;
-                f.write_str("\n")?;
+                if f.show_container_bounds() {
+                    write_impl_header(&impl_, f)?;
+                    f.write_str("\n")?;
+                }
 
                 // Block-local impls are "hoisted" to the nearest (non-block) module.
                 module = module.nearest_non_block_module(db);
@@ -588,12 +592,14 @@ fn write_where_clause(
     let params = f.db.generic_params(def);
 
     let container = match def {
-        GenericDefId::FunctionId(id) => match id.lookup(f.db.upcast()).container() {
-            ItemContainerId::ImplId(it) => Some(("impl", it.into())),
-            ItemContainerId::TraitId(it) => Some(("trait", it.into())),
-            _ => None,
+        GenericDefId::FunctionId(id) if f.show_container_bounds() => {
+            match id.lookup(f.db.upcast()).container() {
+                ItemContainerId::ImplId(it) => Some(("impl", it.into())),
+                ItemContainerId::TraitId(it) => Some(("trait", it.into())),
+                _ => None,
+            }
+            .map(|(name, def)| (name, f.db.generic_params(def)))
         }
-        .map(|(name, def)| (name, f.db.generic_params(def))),
         _ => None,
     };
 
@@ -607,9 +613,9 @@ fn write_where_clause(
         })
     };
 
-    if no_displayable_pred(&params)
-        && container.as_ref().map_or(true, |(_, p)| no_displayable_pred(p))
-    {
+    let container_bounds_no_displayable =
+        container.as_ref().map_or(true, |(_, p)| no_displayable_pred(p));
+    if no_displayable_pred(&params) && container_bounds_no_displayable {
         return Ok(false);
     }
 
@@ -617,8 +623,10 @@ fn write_where_clause(
     write_where_predicates(&params, f)?;
 
     if let Some((name, container_params)) = container {
-        write!(f, "\n    // Bounds from {}:", name)?;
-        write_where_predicates(&container_params, f)?;
+        if !container_bounds_no_displayable {
+            write!(f, "\n    // Bounds from {}:", name)?;
+            write_where_predicates(&container_params, f)?;
+        }
     }
 
     Ok(true)
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 3bc17f95e70..99568c9922b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -430,6 +430,7 @@ pub(super) fn definition(
             }
             label
         }
+        Definition::Function(fn_) => fn_.display_with_container_bounds(db, true).to_string(),
         _ => def.label(db),
     };
     let docs = def.docs(db, famous_defs);