Skip to content

Commit 9957bb3

Browse files
committed
Add const generics to doctest names for structt
1 parent 8bc75c4 commit 9957bb3

File tree

2 files changed

+141
-2
lines changed

2 files changed

+141
-2
lines changed

crates/hir/src/lib.rs

Lines changed: 33 additions & 2 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::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
45+
generics::{ConstParamData, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
4646
item_tree::ItemTreeNode,
4747
lang_item::{LangItem, LangItemTarget},
4848
layout::{Layout, LayoutError, ReprOptions},
@@ -1189,6 +1189,31 @@ 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+
11921217
pub fn as_enum(&self) -> Option<Enum> {
11931218
if let Self::Enum(v) = self {
11941219
Some(*v)
@@ -3358,15 +3383,21 @@ impl Type {
33583383
.map(move |ty| self.derived(ty))
33593384
}
33603385

3361-
/// Combines lifetime indicators and type arguments into a single `Iterator`
3386+
/// Combines lifetime indicators, type and constant parameters into a single `Iterator`
33623387
pub fn lifetime_and_type_arguments<'a>(
33633388
&'a self,
33643389
db: &'a dyn HirDatabase,
33653390
) -> impl Iterator<Item = SmolStr> + 'a {
3391+
// iterate the lifetime
33663392
self.as_adt()
33673393
.and_then(|a| a.lifetime(db).and_then(|lt| Some((&lt.name).to_smol_str())))
33683394
.into_iter()
3395+
// add the type paramaters
33693396
.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+
}))
33703401
}
33713402

33723403
pub fn iterate_method_candidates_with_traits<T>(

crates/ide/src/runnables.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,114 @@ impl<T, U> Data<'a, T, U> {
11021102
"#]],
11031103
);
11041104
}
1105+
1106+
#[test]
1107+
fn test_runnables_doc_test_in_impl_with_const() {
1108+
check(
1109+
r#"
1110+
//- /lib.rs
1111+
$0
1112+
fn main() {}
1113+
1114+
struct Data<const N: usize>;
1115+
impl<const N: usize> Data<N> {
1116+
/// ```
1117+
/// let x = 5;
1118+
/// ```
1119+
fn foo() {}
1120+
}
1121+
"#,
1122+
&[Bin, DocTest],
1123+
expect![[r#"
1124+
[
1125+
Runnable {
1126+
use_name_in_title: false,
1127+
nav: NavigationTarget {
1128+
file_id: FileId(
1129+
0,
1130+
),
1131+
full_range: 1..13,
1132+
focus_range: 4..8,
1133+
name: "main",
1134+
kind: Function,
1135+
},
1136+
kind: Bin,
1137+
cfg: None,
1138+
},
1139+
Runnable {
1140+
use_name_in_title: false,
1141+
nav: NavigationTarget {
1142+
file_id: FileId(
1143+
0,
1144+
),
1145+
full_range: 79..133,
1146+
name: "foo",
1147+
},
1148+
kind: DocTest {
1149+
test_id: Path(
1150+
"Data<N>::foo",
1151+
),
1152+
},
1153+
cfg: None,
1154+
},
1155+
]
1156+
"#]],
1157+
);
1158+
}
1159+
1160+
#[test]
1161+
fn test_runnables_doc_test_in_impl_with_lifetime_types_and_const() {
1162+
check(
1163+
r#"
1164+
//- /lib.rs
1165+
$0
1166+
fn main() {}
1167+
1168+
struct Data<'a, T, const N: usize>;
1169+
impl<'a, T, const N: usize> Data<'a, T, N> {
1170+
/// ```
1171+
/// let x = 5;
1172+
/// ```
1173+
fn foo() {}
1174+
}
1175+
"#,
1176+
&[Bin, DocTest],
1177+
expect![[r#"
1178+
[
1179+
Runnable {
1180+
use_name_in_title: false,
1181+
nav: NavigationTarget {
1182+
file_id: FileId(
1183+
0,
1184+
),
1185+
full_range: 1..13,
1186+
focus_range: 4..8,
1187+
name: "main",
1188+
kind: Function,
1189+
},
1190+
kind: Bin,
1191+
cfg: None,
1192+
},
1193+
Runnable {
1194+
use_name_in_title: false,
1195+
nav: NavigationTarget {
1196+
file_id: FileId(
1197+
0,
1198+
),
1199+
full_range: 100..154,
1200+
name: "foo",
1201+
},
1202+
kind: DocTest {
1203+
test_id: Path(
1204+
"Data<'a,T,N>::foo",
1205+
),
1206+
},
1207+
cfg: None,
1208+
},
1209+
]
1210+
"#]],
1211+
);
1212+
}
11051213
#[test]
11061214
fn test_runnables_module() {
11071215
check(

0 commit comments

Comments
 (0)