Skip to content

Commit 7abcc7d

Browse files
committed
Add const to doctest runnable definition
Refactor method to get type parameters to add const parameters Remove unused methods
1 parent 4ee2e46 commit 7abcc7d

File tree

2 files changed

+115
-32
lines changed

2 files changed

+115
-32
lines changed

crates/hir/src/lib.rs

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use hir_def::{
4242
adt::VariantData,
4343
body::{BodyDiagnostic, SyntheticSyntax},
4444
expr::{BindingAnnotation, ExprOrPatId, LabelId, Pat, PatId},
45-
generics::{ConstParamData, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
45+
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
4646
item_tree::ItemTreeNode,
4747
lang_item::{LangItem, LangItemTarget},
4848
layout::{Layout, LayoutError, ReprOptions},
@@ -1189,31 +1189,6 @@ impl Adt {
11891189
.map(|arena| arena.1.clone())
11901190
}
11911191

1192-
/// Returns an iterator of all `const` generic paramaters
1193-
///
1194-
/// This method is not well optimized, I could not statisfy the borrow
1195-
/// checker. I'm sure there are smarter ways to return the consts names
1196-
pub fn consts(&self, db: &dyn HirDatabase) -> impl Iterator<Item = ConstParamData> {
1197-
let resolver = match self {
1198-
Adt::Struct(s) => s.id.resolver(db.upcast()),
1199-
Adt::Union(u) => u.id.resolver(db.upcast()),
1200-
Adt::Enum(e) => e.id.resolver(db.upcast()),
1201-
};
1202-
resolver
1203-
.generic_params()
1204-
.map_or(vec![], |gp| {
1205-
gp.as_ref()
1206-
.type_or_consts
1207-
.iter()
1208-
.filter_map(|arena| match arena.1 {
1209-
TypeOrConstParamData::ConstParamData(consts) => Some(consts.clone()),
1210-
_ => None,
1211-
})
1212-
.collect::<Vec<ConstParamData>>()
1213-
})
1214-
.into_iter()
1215-
}
1216-
12171192
pub fn as_enum(&self) -> Option<Enum> {
12181193
if let Self::Enum(v) = self {
12191194
Some(*v)
@@ -3373,6 +3348,24 @@ impl Type {
33733348
}
33743349
}
33753350

3351+
/// Iterates its type arguments
3352+
///
3353+
/// It iterates the actual type arguments when concrete types are used
3354+
/// and otherwise the generic names.
3355+
/// It does not include `const` arguments.
3356+
///
3357+
/// For code, such as:
3358+
/// ```text
3359+
/// struct Foo<T, U>
3360+
///
3361+
/// impl<U> Foo<String, U>
3362+
/// ```
3363+
///
3364+
/// It iterates:
3365+
/// ```text
3366+
/// - "String"
3367+
/// - "U"
3368+
/// ```
33763369
pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ {
33773370
self.ty
33783371
.strip_references()
@@ -3383,6 +3376,46 @@ impl Type {
33833376
.map(move |ty| self.derived(ty))
33843377
}
33853378

3379+
/// Iterates its type and const arguments
3380+
///
3381+
/// It iterates the actual type and const arguments when concrete types
3382+
/// are used and otherwise the generic names.
3383+
///
3384+
/// For code, such as:
3385+
/// ```text
3386+
/// struct Foo<T, const U: usize, const X: usize>
3387+
///
3388+
/// impl<U> Foo<String, U, 12>
3389+
/// ```
3390+
///
3391+
/// It iterates:
3392+
/// ```text
3393+
/// - "String"
3394+
/// - "U"
3395+
/// - "12"
3396+
/// ```
3397+
pub fn type_and_const_arguments<'a>(
3398+
&'a self,
3399+
db: &'a dyn HirDatabase,
3400+
) -> impl Iterator<Item = SmolStr> + 'a {
3401+
self.ty
3402+
.strip_references()
3403+
.as_adt()
3404+
.into_iter()
3405+
.flat_map(|(_, substs)| substs.iter(Interner))
3406+
.filter_map(|arg| {
3407+
// arg can be either a `Ty` or `constant`
3408+
if let Some(ty) = arg.ty(Interner) {
3409+
Some(SmolStr::new(ty.display(db).to_string()))
3410+
// Some(ty)
3411+
} else if let Some(const_) = arg.constant(Interner) {
3412+
Some(SmolStr::new_inline(&const_.display(db).to_string()))
3413+
} else {
3414+
None
3415+
}
3416+
})
3417+
}
3418+
33863419
/// Combines lifetime indicators, type and constant parameters into a single `Iterator`
33873420
pub fn lifetime_type_const_paramaters<'a>(
33883421
&'a self,
@@ -3392,12 +3425,8 @@ impl Type {
33923425
self.as_adt()
33933426
.and_then(|a| a.lifetime(db).and_then(|lt| Some((&lt.name).to_smol_str())))
33943427
.into_iter()
3395-
// add the type paramaters
3396-
.chain(self.type_arguments().map(|ty| SmolStr::new(ty.display(db).to_string())))
3397-
// add const paramameters
3398-
.chain(self.as_adt().map_or(vec![], |a| {
3399-
a.consts(db).map(|cs| cs.name.to_smol_str()).collect::<Vec<SmolStr>>()
3400-
}))
3428+
// add the type and const paramaters
3429+
.chain(self.type_and_const_arguments(db))
34013430
}
34023431

34033432
pub fn iterate_method_candidates_with_traits<T>(

crates/ide/src/runnables.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,6 +2272,60 @@ mod tests {
22722272
);
22732273
}
22742274

2275+
#[test]
2276+
fn test_runnables_doc_test_in_impl_with_lifetime_type_const_value() {
2277+
check(
2278+
r#"
2279+
//- /lib.rs
2280+
$0
2281+
fn main() {}
2282+
2283+
struct Data<'a, A, const B: usize, C, const D: u32>;
2284+
impl<A, C, const D: u32> Data<'a, A, 12, C, D> {
2285+
/// ```
2286+
/// ```
2287+
fn foo() {}
2288+
}
2289+
"#,
2290+
&[Bin, DocTest],
2291+
expect![[r#"
2292+
[
2293+
Runnable {
2294+
use_name_in_title: false,
2295+
nav: NavigationTarget {
2296+
file_id: FileId(
2297+
0,
2298+
),
2299+
full_range: 1..13,
2300+
focus_range: 4..8,
2301+
name: "main",
2302+
kind: Function,
2303+
},
2304+
kind: Bin,
2305+
cfg: None,
2306+
},
2307+
Runnable {
2308+
use_name_in_title: false,
2309+
nav: NavigationTarget {
2310+
file_id: FileId(
2311+
0,
2312+
),
2313+
full_range: 121..156,
2314+
name: "foo",
2315+
},
2316+
kind: DocTest {
2317+
test_id: Path(
2318+
"Data<'a,A,12,C,D>::foo",
2319+
),
2320+
},
2321+
cfg: None,
2322+
},
2323+
]
2324+
"#]],
2325+
);
2326+
}
2327+
2328+
22752329
#[test]
22762330
fn doc_test_type_params() {
22772331
check(

0 commit comments

Comments
 (0)