@@ -113,6 +113,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
113
113
res. extend ( runnable. or_else ( || module_def_doctest ( & sema, def) ) )
114
114
}
115
115
Either :: Right ( impl_) => {
116
+ res. extend ( runnable_impl ( & sema, & impl_) ) ;
116
117
res. extend ( impl_. items ( db) . into_iter ( ) . filter_map ( |assoc| match assoc {
117
118
hir:: AssocItem :: Function ( it) => {
118
119
runnable_fn ( & sema, it) . or_else ( || module_def_doctest ( & sema, it. into ( ) ) )
@@ -270,6 +271,26 @@ pub(crate) fn runnable_mod(sema: &Semantics<RootDatabase>, def: hir::Module) ->
270
271
Some ( Runnable { nav, kind : RunnableKind :: TestMod { path } , cfg } )
271
272
}
272
273
274
+ pub ( crate ) fn runnable_impl ( sema : & Semantics < RootDatabase > , def : & hir:: Impl ) -> Option < Runnable > {
275
+ let attrs = def. attrs ( sema. db ) ;
276
+ if !has_runnable_doc_test ( & attrs) {
277
+ return None ;
278
+ }
279
+ let cfg = attrs. cfg ( ) ;
280
+ let nav = def. try_to_nav ( sema. db ) ?;
281
+ let ty = def. self_ty ( sema. db ) ;
282
+ let adt_name = ty. as_adt ( ) ?. name ( sema. db ) ;
283
+ let mut ty_args = ty. type_arguments ( ) . peekable ( ) ;
284
+ let params = if ty_args. peek ( ) . is_some ( ) {
285
+ format ! ( "<{}>" , ty_args. format_with( ", " , |ty, cb| cb( & ty. display( sema. db) ) ) )
286
+ } else {
287
+ String :: new ( )
288
+ } ;
289
+ let test_id = TestId :: Path ( format ! ( "{}{}" , adt_name, params) ) ;
290
+
291
+ Some ( Runnable { nav, kind : RunnableKind :: DocTest { test_id } , cfg } )
292
+ }
293
+
273
294
fn module_def_doctest ( sema : & Semantics < RootDatabase > , def : hir:: ModuleDef ) -> Option < Runnable > {
274
295
let attrs = match def {
275
296
hir:: ModuleDef :: Module ( it) => it. attrs ( sema. db ) ,
@@ -610,8 +631,23 @@ fn should_have_no_runnable_6() {}
610
631
/// ```
611
632
struct StructWithRunnable(String);
612
633
634
+ /// ```
635
+ /// let x = 5;
636
+ /// ```
637
+ impl StructWithRunnable {}
638
+
639
+ trait Test {
640
+ fn test() -> usize {
641
+ 5usize
642
+ }
643
+ }
644
+
645
+ /// ```
646
+ /// let x = 5;
647
+ /// ```
648
+ impl Test for StructWithRunnable {}
613
649
"# ,
614
- & [ & BIN , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST ] ,
650
+ & [ & BIN , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST , & DOCTEST ] ,
615
651
expect ! [ [ r#"
616
652
[
617
653
Runnable {
@@ -717,6 +753,40 @@ struct StructWithRunnable(String);
717
753
},
718
754
cfg: None,
719
755
},
756
+ Runnable {
757
+ nav: NavigationTarget {
758
+ file_id: FileId(
759
+ 0,
760
+ ),
761
+ full_range: 967..1024,
762
+ focus_range: 1003..1021,
763
+ name: "impl",
764
+ kind: Impl,
765
+ },
766
+ kind: DocTest {
767
+ test_id: Path(
768
+ "StructWithRunnable",
769
+ ),
770
+ },
771
+ cfg: None,
772
+ },
773
+ Runnable {
774
+ nav: NavigationTarget {
775
+ file_id: FileId(
776
+ 0,
777
+ ),
778
+ full_range: 1088..1154,
779
+ focus_range: 1133..1151,
780
+ name: "impl",
781
+ kind: Impl,
782
+ },
783
+ kind: DocTest {
784
+ test_id: Path(
785
+ "StructWithRunnable",
786
+ ),
787
+ },
788
+ cfg: None,
789
+ },
720
790
]
721
791
"# ] ] ,
722
792
) ;
0 commit comments