mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Complete crate
, super
and self
in non-usetree paths
This commit is contained in:
parent
2b6770c936
commit
9f9cc72ee5
10 changed files with 126 additions and 57 deletions
|
@ -74,6 +74,12 @@ impl Completions {
|
||||||
items.into_iter().for_each(|item| self.add(item.into()))
|
items.into_iter().for_each(|item| self.add(item.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext, keyword: &'static str) {
|
||||||
|
let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), keyword);
|
||||||
|
item.kind(CompletionItemKind::Keyword);
|
||||||
|
item.add_to(self);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn add_resolution(
|
pub(crate) fn add_resolution(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &CompletionContext,
|
ctx: &CompletionContext,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
//! Completes keywords.
|
//! Completes keywords.
|
||||||
|
|
||||||
use std::iter;
|
|
||||||
|
|
||||||
use syntax::{SyntaxKind, T};
|
use syntax::{SyntaxKind, T};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -9,36 +7,6 @@ use crate::{
|
||||||
CompletionItemKind, CompletionKind, Completions,
|
CompletionItemKind, CompletionKind, Completions,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
|
||||||
// complete keyword "crate" in use stmt
|
|
||||||
let source_range = ctx.source_range();
|
|
||||||
let kw_completion = move |text: &str| {
|
|
||||||
let mut item = CompletionItem::new(CompletionKind::Keyword, source_range, text);
|
|
||||||
item.kind(CompletionItemKind::Keyword).insert_text(text);
|
|
||||||
item
|
|
||||||
};
|
|
||||||
|
|
||||||
if ctx.in_use_tree() {
|
|
||||||
match &ctx.path_context {
|
|
||||||
Some(PathCompletionContext { qualifier: Some(qual), use_tree_parent, .. }) => {
|
|
||||||
if iter::successors(Some(qual.clone()), |p| p.qualifier())
|
|
||||||
.all(|p| p.segment().and_then(|s| s.super_token()).is_some())
|
|
||||||
{
|
|
||||||
kw_completion("super::").add_to(acc);
|
|
||||||
}
|
|
||||||
if *use_tree_parent {
|
|
||||||
kw_completion("self").add_to(acc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
kw_completion("crate::").add_to(acc);
|
|
||||||
kw_completion("self::").add_to(acc);
|
|
||||||
kw_completion("super::").add_to(acc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if ctx.token.kind() == SyntaxKind::COMMENT {
|
if ctx.token.kind() == SyntaxKind::COMMENT {
|
||||||
cov_mark::hit!(no_keyword_completion_in_comments);
|
cov_mark::hit!(no_keyword_completion_in_comments);
|
||||||
|
@ -243,6 +211,9 @@ mod tests {
|
||||||
kw for
|
kw for
|
||||||
kw let
|
kw let
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -271,6 +242,9 @@ mod tests {
|
||||||
kw for
|
kw for
|
||||||
kw let
|
kw let
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -301,6 +275,9 @@ mod tests {
|
||||||
kw else
|
kw else
|
||||||
kw else if
|
kw else if
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
check_edit(
|
check_edit(
|
||||||
|
@ -330,6 +307,9 @@ fn quux() -> i32 {
|
||||||
kw if let
|
kw if let
|
||||||
kw for
|
kw for
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -360,6 +340,9 @@ fn quux() -> i32 {
|
||||||
kw continue
|
kw continue
|
||||||
kw break
|
kw break
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -448,6 +431,9 @@ fn foo() {
|
||||||
kw if let
|
kw if let
|
||||||
kw for
|
kw for
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -493,6 +479,9 @@ fn foo() {
|
||||||
kw if let
|
kw if let
|
||||||
kw for
|
kw for
|
||||||
kw return
|
kw return
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
//! Completion of paths, i.e. `some::prefix::$0`.
|
//! Completion of paths, i.e. `some::prefix::$0`.
|
||||||
|
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
use hir::HasVisibility;
|
use hir::HasVisibility;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use syntax::AstNode;
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
use crate::{CompletionContext, Completions};
|
use crate::{context::PathCompletionContext, CompletionContext, Completions};
|
||||||
|
|
||||||
pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if ctx.is_path_disallowed() {
|
if ctx.is_path_disallowed() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let path = match ctx.path_qual() {
|
let (path, use_tree_parent) = match &ctx.path_context {
|
||||||
Some(path) => path,
|
Some(PathCompletionContext { qualifier: Some(qualifier), use_tree_parent, .. }) => {
|
||||||
None => return,
|
(qualifier, *use_tree_parent)
|
||||||
|
}
|
||||||
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let resolution = match ctx.sema.resolve_path(path) {
|
let resolution = match ctx.sema.resolve_path(path) {
|
||||||
|
@ -39,6 +43,23 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.in_use_tree() {
|
||||||
|
if iter::successors(Some(path.clone()), |p| p.qualifier())
|
||||||
|
.all(|p| p.segment().and_then(|s| s.super_token()).is_some())
|
||||||
|
{
|
||||||
|
acc.add_keyword(ctx, "super::");
|
||||||
|
}
|
||||||
|
// only show `self` in a new use-tree when the qualifier doesn't end in self
|
||||||
|
if use_tree_parent
|
||||||
|
&& !matches!(
|
||||||
|
path.segment().and_then(|it| it.kind()),
|
||||||
|
Some(ast::PathSegmentKind::SelfKw)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
acc.add_keyword(ctx, "self");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add associated types on type parameters and `Self`.
|
// Add associated types on type parameters and `Self`.
|
||||||
resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
|
resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
|
||||||
acc.add_type_alias(ctx, alias);
|
acc.add_type_alias(ctx, alias);
|
||||||
|
|
|
@ -10,6 +10,21 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.in_use_tree() {
|
||||||
|
// only show modules in a fresh UseTree
|
||||||
|
cov_mark::hit!(only_completes_modules_in_import);
|
||||||
|
ctx.scope.process_all_names(&mut |name, res| {
|
||||||
|
if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
|
||||||
|
acc.add_resolution(ctx, name, &res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::array::IntoIter::new(["self::", "super::", "crate::"])
|
||||||
|
.for_each(|kw| acc.add_keyword(ctx, kw));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::array::IntoIter::new(["self", "super", "crate"]).for_each(|kw| acc.add_keyword(ctx, kw));
|
||||||
|
|
||||||
if ctx.expects_item() || ctx.expects_assoc_item() {
|
if ctx.expects_item() || ctx.expects_assoc_item() {
|
||||||
// only show macros in {Assoc}ItemList
|
// only show macros in {Assoc}ItemList
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
ctx.scope.process_all_names(&mut |name, res| {
|
||||||
|
@ -25,17 +40,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.in_use_tree() {
|
|
||||||
// only show modules in a fresh UseTree
|
|
||||||
cov_mark::hit!(only_completes_modules_in_import);
|
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
|
||||||
if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
|
|
||||||
acc.add_resolution(ctx, name, &res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(&ctx.completion_location, Some(ImmediateLocation::TypeBound)) {
|
if matches!(&ctx.completion_location, Some(ImmediateLocation::TypeBound)) {
|
||||||
ctx.scope.process_all_names(&mut |name, res| {
|
ctx.scope.process_all_names(&mut |name, res| {
|
||||||
let add_resolution = match res {
|
let add_resolution = match res {
|
||||||
|
|
|
@ -150,7 +150,6 @@ pub fn completions(
|
||||||
completions::attribute::complete_attribute(&mut acc, &ctx);
|
completions::attribute::complete_attribute(&mut acc, &ctx);
|
||||||
completions::fn_param::complete_fn_param(&mut acc, &ctx);
|
completions::fn_param::complete_fn_param(&mut acc, &ctx);
|
||||||
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
|
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
|
||||||
completions::keyword::complete_use_tree_keyword(&mut acc, &ctx);
|
|
||||||
completions::snippet::complete_expr_snippet(&mut acc, &ctx);
|
completions::snippet::complete_expr_snippet(&mut acc, &ctx);
|
||||||
completions::snippet::complete_item_snippet(&mut acc, &ctx);
|
completions::snippet::complete_item_snippet(&mut acc, &ctx);
|
||||||
completions::qualified_path::complete_qualified_path(&mut acc, &ctx);
|
completions::qualified_path::complete_qualified_path(&mut acc, &ctx);
|
||||||
|
|
|
@ -30,6 +30,9 @@ fn in_mod_item_list() {
|
||||||
sn tmod (Test module)
|
sn tmod (Test module)
|
||||||
sn tfn (Test function)
|
sn tfn (Test function)
|
||||||
sn macro_rules
|
sn macro_rules
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
|
@ -58,6 +61,9 @@ fn in_source_file_item_list() {
|
||||||
sn tmod (Test module)
|
sn tmod (Test module)
|
||||||
sn tfn (Test function)
|
sn tfn (Test function)
|
||||||
sn macro_rules
|
sn macro_rules
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
@ -174,6 +180,9 @@ fn in_impl_assoc_item_list() {
|
||||||
kw fn
|
kw fn
|
||||||
kw const
|
kw const
|
||||||
kw type
|
kw type
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
@ -205,6 +214,9 @@ fn in_trait_assoc_item_list() {
|
||||||
kw fn
|
kw fn
|
||||||
kw const
|
kw const
|
||||||
kw type
|
kw type
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
|
|
@ -18,6 +18,9 @@ fn target_type_or_trait_in_impl_block() {
|
||||||
impl Tra$0
|
impl Tra$0
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Record
|
st Record
|
||||||
|
@ -38,6 +41,9 @@ fn target_type_in_trait_impl_block() {
|
||||||
impl Trait for Str$0
|
impl Trait for Str$0
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Record
|
st Record
|
||||||
|
|
|
@ -16,6 +16,9 @@ fn predicate_start() {
|
||||||
struct Foo<'lt, T, const C: usize> where $0 {}
|
struct Foo<'lt, T, const C: usize> where $0 {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Record
|
st Record
|
||||||
|
@ -38,6 +41,9 @@ fn bound_for_type_pred() {
|
||||||
struct Foo<'lt, T, const C: usize> where T: $0 {}
|
struct Foo<'lt, T, const C: usize> where T: $0 {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
@ -54,6 +60,9 @@ fn bound_for_lifetime_pred() {
|
||||||
struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
|
struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
@ -69,6 +78,9 @@ fn bound_for_for_pred() {
|
||||||
struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
|
struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
md module
|
md module
|
||||||
ma makro!(…) #[macro_export] macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
@ -84,6 +96,9 @@ fn param_list_for_for_pred() {
|
||||||
struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
|
struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Record
|
st Record
|
||||||
|
@ -107,6 +122,9 @@ impl Record {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r##"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
sp Self
|
sp Self
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
|
|
|
@ -30,6 +30,9 @@ struct Foo<'lt, T, const C: usize> {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
sp Self
|
sp Self
|
||||||
tp T
|
tp T
|
||||||
tt Trait
|
tt Trait
|
||||||
|
@ -54,6 +57,9 @@ struct Foo<'lt, T, const C: usize>(f$0);
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
kw pub(crate)
|
kw pub(crate)
|
||||||
kw pub
|
kw pub
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
sp Self
|
sp Self
|
||||||
tp T
|
tp T
|
||||||
tt Trait
|
tt Trait
|
||||||
|
@ -76,6 +82,9 @@ fn fn_return_type() {
|
||||||
fn x<'lt, T, const C: usize>() -> $0
|
fn x<'lt, T, const C: usize>() -> $0
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tp T
|
tp T
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
|
@ -99,6 +108,9 @@ fn foo<'lt, T, const C: usize>() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
tp T
|
tp T
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
|
@ -140,6 +152,9 @@ trait Trait2 {
|
||||||
fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
|
fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
kw self
|
||||||
|
kw super
|
||||||
|
kw crate
|
||||||
ta Foo = (as Trait2) type Foo;
|
ta Foo = (as Trait2) type Foo;
|
||||||
tp T
|
tp T
|
||||||
cp CONST_PARAM
|
cp CONST_PARAM
|
||||||
|
|
|
@ -22,11 +22,11 @@ mod foo {}
|
||||||
// nothing here
|
// nothing here
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
kw crate::
|
|
||||||
kw self::
|
|
||||||
kw super::
|
|
||||||
md foo
|
md foo
|
||||||
md other_crate
|
md other_crate
|
||||||
|
kw self::
|
||||||
|
kw super::
|
||||||
|
kw crate::
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ mod foo { pub struct S; }
|
||||||
use self::{foo::*, bar$0};
|
use self::{foo::*, bar$0};
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
kw self
|
|
||||||
st S
|
st S
|
||||||
md foo
|
md foo
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -230,10 +229,10 @@ pub mod bar {}
|
||||||
pub use $0;
|
pub use $0;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
kw crate::
|
md bar
|
||||||
kw self::
|
kw self::
|
||||||
kw super::
|
kw super::
|
||||||
md bar
|
kw crate::
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -247,10 +246,10 @@ mod bar {}
|
||||||
use {$0};
|
use {$0};
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
kw crate::
|
md bar
|
||||||
kw self::
|
kw self::
|
||||||
kw super::
|
kw super::
|
||||||
md bar
|
kw crate::
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue