Skip to content

Commit

Permalink
Add const to doctest runnable definition
Browse files Browse the repository at this point in the history
Refactor method to get type parameters to add const parameters
Remove unused methods
  • Loading branch information
anergictcell committed Feb 27, 2023
1 parent 4ee2e46 commit 7abcc7d
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 32 deletions.
93 changes: 61 additions & 32 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -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,
Expand All @@ -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>(
Expand Down
54 changes: 54 additions & 0 deletions crates/ide/src/runnables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2272,6 +2272,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(
Expand Down

0 comments on commit 7abcc7d

Please sign in to comment.