about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Marcello <jonas.marcello@esbme.com>2023-02-27 07:11:35 +0100
committerJonas Marcello <jonas.marcello@esbme.com>2023-02-27 18:08:20 +0100
commit7abcc7d8624bb82ecf1292362726ea2c011fe554 (patch)
tree14091161902a0f6b90fd91513ae0ec0520ba1b35
parent4ee2e469a211e55741239f1830d41a72ec18f409 (diff)
downloadrust-7abcc7d8624bb82ecf1292362726ea2c011fe554.tar.gz
rust-7abcc7d8624bb82ecf1292362726ea2c011fe554.zip
Add const to doctest runnable definition
Refactor method to get type parameters to add const parameters
Remove unused methods
-rw-r--r--crates/hir/src/lib.rs93
-rw-r--r--crates/ide/src/runnables.rs54
2 files changed, 115 insertions, 32 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index d280ff8815a..82718b2f82c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -42,7 +42,7 @@ use hir_def::{
     adt::VariantData,
     body::{BodyDiagnostic, SyntheticSyntax},
     expr::{BindingAnnotation, ExprOrPatId, LabelId, Pat, PatId},
-    generics::{ConstParamData, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
+    generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
     item_tree::ItemTreeNode,
     lang_item::{LangItem, LangItemTarget},
     layout::{Layout, LayoutError, ReprOptions},
@@ -1189,31 +1189,6 @@ impl Adt {
             .map(|arena| arena.1.clone())
     }
 
-    /// Returns an iterator of all `const` generic paramaters
-    ///
-    /// This method is not well optimized, I could not statisfy the borrow
-    /// checker. I'm sure there are smarter ways to return the consts names
-    pub fn consts(&self, db: &dyn HirDatabase) -> impl Iterator<Item = ConstParamData> {
-        let resolver = match self {
-            Adt::Struct(s) => s.id.resolver(db.upcast()),
-            Adt::Union(u) => u.id.resolver(db.upcast()),
-            Adt::Enum(e) => e.id.resolver(db.upcast()),
-        };
-        resolver
-            .generic_params()
-            .map_or(vec![], |gp| {
-                gp.as_ref()
-                    .type_or_consts
-                    .iter()
-                    .filter_map(|arena| match arena.1 {
-                        TypeOrConstParamData::ConstParamData(consts) => Some(consts.clone()),
-                        _ => None,
-                    })
-                    .collect::<Vec<ConstParamData>>()
-            })
-            .into_iter()
-    }
-
     pub fn as_enum(&self) -> Option<Enum> {
         if let Self::Enum(v) = self {
             Some(*v)
@@ -3373,6 +3348,24 @@ impl Type {
         }
     }
 
+    /// Iterates its type arguments
+    ///
+    /// It iterates the actual type arguments when concrete types are used
+    /// and otherwise the generic names.
+    /// It does not include `const` arguments.
+    ///
+    /// For code, such as:
+    /// ```text
+    /// struct Foo<T, U>
+    ///
+    /// impl<U> Foo<String, U>
+    /// ```
+    ///
+    /// It iterates:
+    /// ```text
+    /// - "String"
+    /// - "U"
+    /// ```
     pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ {
         self.ty
             .strip_references()
@@ -3383,6 +3376,46 @@ impl Type {
             .map(move |ty| self.derived(ty))
     }
 
+    /// Iterates its type and const arguments
+    ///
+    /// It iterates the actual type and const arguments when concrete types
+    /// are used and otherwise the generic names.
+    ///
+    /// For code, such as:
+    /// ```text
+    /// struct Foo<T, const U: usize, const X: usize>
+    ///
+    /// impl<U> Foo<String, U, 12>
+    /// ```
+    ///
+    /// It iterates:
+    /// ```text
+    /// - "String"
+    /// - "U"
+    /// - "12"
+    /// ```
+    pub fn type_and_const_arguments<'a>(
+        &'a self,
+        db: &'a dyn HirDatabase,
+    ) -> impl Iterator<Item = SmolStr> + 'a {
+        self.ty
+            .strip_references()
+            .as_adt()
+            .into_iter()
+            .flat_map(|(_, substs)| substs.iter(Interner))
+            .filter_map(|arg| {
+                // arg can be either a `Ty` or `constant`
+                if let Some(ty) = arg.ty(Interner) {
+                    Some(SmolStr::new(ty.display(db).to_string()))
+                    // Some(ty)
+                } else if let Some(const_) = arg.constant(Interner) {
+                    Some(SmolStr::new_inline(&const_.display(db).to_string()))
+                } else {
+                    None
+                }
+            })
+    }
+
     /// Combines lifetime indicators, type and constant parameters into a single `Iterator`
     pub fn lifetime_type_const_paramaters<'a>(
         &'a self,
@@ -3392,12 +3425,8 @@ impl Type {
         self.as_adt()
             .and_then(|a| a.lifetime(db).and_then(|lt| Some((&lt.name).to_smol_str())))
             .into_iter()
-            // add the type paramaters
-            .chain(self.type_arguments().map(|ty| SmolStr::new(ty.display(db).to_string())))
-            // add const paramameters
-            .chain(self.as_adt().map_or(vec![], |a| {
-                a.consts(db).map(|cs| cs.name.to_smol_str()).collect::<Vec<SmolStr>>()
-            }))
+            // add the type and const paramaters
+            .chain(self.type_and_const_arguments(db))
     }
 
     pub fn iterate_method_candidates_with_traits<T>(
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 7fc396f023f..b4fa2f9b9f0 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2273,6 +2273,60 @@ mod tests {
     }
 
     #[test]
+    fn test_runnables_doc_test_in_impl_with_lifetime_type_const_value() {
+        check(
+            r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<'a, A, const B: usize, C, const D: u32>;
+impl<A, C, const D: u32> Data<'a, A, 12, C, D> {
+    /// ```
+    /// ```
+    fn foo() {}
+}
+"#,
+            &[Bin, DocTest],
+            expect![[r#"
+                [
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 1..13,
+                            focus_range: 4..8,
+                            name: "main",
+                            kind: Function,
+                        },
+                        kind: Bin,
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 121..156,
+                            name: "foo",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "Data<'a,A,12,C,D>::foo",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                ]
+            "#]],
+        );
+    }
+
+
+    #[test]
     fn doc_test_type_params() {
         check(
             r#"