Unnamed repository; edit this file 'description' to name the repository.
Add const to doctest runnable definition
Refactor method to get type parameters to add const parameters Remove unused methods
Jonas Marcello 2023-02-28
parent 4ee2e46 · commit 7abcc7d
-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 d280ff8815..82718b2f82 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 7fc396f023..b4fa2f9b9f 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#"