mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge ref 'efd420c770bb' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: efd420c770bb179537c01063e98cb6990c439654 Filtered ref: d11dbbb02905535a89393e80c24274bee81fa928 This merge was created using https://github.com/rust-lang/josh-sync.
This commit is contained in:
commit
1ebfd77437
41
Cargo.lock
generated
41
Cargo.lock
generated
@ -1268,7 +1268,7 @@ dependencies = [
|
|||||||
"expect-test",
|
"expect-test",
|
||||||
"intern",
|
"intern",
|
||||||
"parser",
|
"parser",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer 0.122.0",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"span",
|
"span",
|
||||||
@ -1504,7 +1504,7 @@ dependencies = [
|
|||||||
"drop_bomb",
|
"drop_bomb",
|
||||||
"edition",
|
"edition",
|
||||||
"expect-test",
|
"expect-test",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer 0.122.0",
|
||||||
"rustc-literal-escaper",
|
"rustc-literal-escaper",
|
||||||
"stdx",
|
"stdx",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -1614,7 +1614,7 @@ dependencies = [
|
|||||||
"object",
|
"object",
|
||||||
"paths",
|
"paths",
|
||||||
"proc-macro-test",
|
"proc-macro-test",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer 0.122.0",
|
||||||
"span",
|
"span",
|
||||||
"syntax-bridge",
|
"syntax-bridge",
|
||||||
"tt",
|
"tt",
|
||||||
@ -1756,9 +1756,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_abi"
|
name = "ra-ap-rustc_abi"
|
||||||
version = "0.121.0"
|
version = "0.122.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ee51482d1c9d3e538acda8cce723db8eea1a81540544bf362bf4c3d841b2329"
|
checksum = "fb01e1fec578003c85481c1cad4ff8cd8195b07c2dc85ae3f716108507ae15d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"ra-ap-rustc_hashes",
|
"ra-ap-rustc_hashes",
|
||||||
@ -1768,18 +1768,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_hashes"
|
name = "ra-ap-rustc_hashes"
|
||||||
version = "0.121.0"
|
version = "0.122.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19c8f1e0c28e24e1b4c55dc08058c6c9829df2204497d4034259f491d348c204"
|
checksum = "e0ec056e72a472ffef8761ce96ece6c626eb07368c09d0105b6df30d27d07673"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-stable-hash",
|
"rustc-stable-hash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_index"
|
name = "ra-ap-rustc_index"
|
||||||
version = "0.121.0"
|
version = "0.122.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f33f429cec6b92fa2c7243883279fb29dd233fdc3e94099aff32aa91aa87f50"
|
checksum = "0fcdd1001db0295e59052e9f53aeda588bbe81e362534f4687d41bd44777b5a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_index_macros",
|
"ra-ap-rustc_index_macros",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@ -1787,9 +1787,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_index_macros"
|
name = "ra-ap-rustc_index_macros"
|
||||||
version = "0.121.0"
|
version = "0.122.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9b55910dbe1fe7ef34bdc1d1bcb41e99b377eb680ea58a1218d95d6b4152257"
|
checksum = "728d64dd98e25530b32e3f7c7c1e844e52722b269360daa1cdeba9dff9727a26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1807,21 +1807,32 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ra-ap-rustc_lexer"
|
||||||
|
version = "0.122.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "415f0821f512608d825b3215489a6a6a2c18ed9f0045953d514e7ec23d4b90ab"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"unicode-properties",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_parse_format"
|
name = "ra-ap-rustc_parse_format"
|
||||||
version = "0.121.0"
|
version = "0.121.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81057891bc2063ad9e353f29462fbc47a0f5072560af34428ae9313aaa5e9d97"
|
checksum = "81057891bc2063ad9e353f29462fbc47a0f5072560af34428ae9313aaa5e9d97"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer 0.121.0",
|
||||||
"rustc-literal-escaper",
|
"rustc-literal-escaper",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_pattern_analysis"
|
name = "ra-ap-rustc_pattern_analysis"
|
||||||
version = "0.121.0"
|
version = "0.122.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe21a3542980d56d2435e96c2720773cac1c63fd4db666417e414729da192eb3"
|
checksum = "4657fcfdfe06e2a02ec8180d4e7c95aecf4811ba50367e363d1a2300b7623284"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_index",
|
"ra-ap-rustc_index",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
@ -2581,7 +2592,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"intern",
|
"intern",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer 0.122.0",
|
||||||
"stdx",
|
"stdx",
|
||||||
"text-size",
|
"text-size",
|
||||||
]
|
]
|
||||||
|
@ -89,11 +89,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
|
|||||||
vfs = { path = "./crates/vfs", version = "0.0.0" }
|
vfs = { path = "./crates/vfs", version = "0.0.0" }
|
||||||
edition = { path = "./crates/edition", version = "0.0.0" }
|
edition = { path = "./crates/edition", version = "0.0.0" }
|
||||||
|
|
||||||
ra-ap-rustc_lexer = { version = "0.121", default-features = false }
|
ra-ap-rustc_lexer = { version = "0.122", default-features = false }
|
||||||
ra-ap-rustc_parse_format = { version = "0.121", default-features = false }
|
ra-ap-rustc_parse_format = { version = "0.121", default-features = false }
|
||||||
ra-ap-rustc_index = { version = "0.121", default-features = false }
|
ra-ap-rustc_index = { version = "0.122", default-features = false }
|
||||||
ra-ap-rustc_abi = { version = "0.121", default-features = false }
|
ra-ap-rustc_abi = { version = "0.122", default-features = false }
|
||||||
ra-ap-rustc_pattern_analysis = { version = "0.121", default-features = false }
|
ra-ap-rustc_pattern_analysis = { version = "0.122", default-features = false }
|
||||||
|
|
||||||
# local crates that aren't published to crates.io. These should not have versions.
|
# local crates that aren't published to crates.io. These should not have versions.
|
||||||
|
|
||||||
|
@ -68,6 +68,11 @@ impl CfgExpr {
|
|||||||
next_cfg_expr(&mut tt.iter()).unwrap_or(CfgExpr::Invalid)
|
next_cfg_expr(&mut tt.iter()).unwrap_or(CfgExpr::Invalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tt")]
|
||||||
|
pub fn parse_from_iter<S: Copy>(tt: &mut tt::iter::TtIter<'_, S>) -> CfgExpr {
|
||||||
|
next_cfg_expr(tt).unwrap_or(CfgExpr::Invalid)
|
||||||
|
}
|
||||||
|
|
||||||
/// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
|
/// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
|
||||||
pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option<bool> {
|
pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option<bool> {
|
||||||
match self {
|
match self {
|
||||||
@ -96,7 +101,14 @@ fn next_cfg_expr<S: Copy>(it: &mut tt::iter::TtIter<'_, S>) -> Option<CfgExpr> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let ret = match it.peek() {
|
let ret = match it.peek() {
|
||||||
Some(TtElement::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => {
|
Some(TtElement::Leaf(tt::Leaf::Punct(punct)))
|
||||||
|
// Don't consume on e.g. `=>`.
|
||||||
|
if punct.char == '='
|
||||||
|
&& (punct.spacing == tt::Spacing::Alone
|
||||||
|
|| it.remaining().flat_tokens().get(1).is_none_or(|peek2| {
|
||||||
|
!matches!(peek2, tt::TokenTree::Leaf(tt::Leaf::Punct(_)))
|
||||||
|
})) =>
|
||||||
|
{
|
||||||
match it.remaining().flat_tokens().get(1) {
|
match it.remaining().flat_tokens().get(1) {
|
||||||
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
|
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
|
||||||
it.next();
|
it.next();
|
||||||
|
@ -550,3 +550,51 @@ fn main() { "\"hello\""; }
|
|||||||
"##]],
|
"##]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cfg_select() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro cfg_select($($tt:tt)*) {}
|
||||||
|
|
||||||
|
cfg_select! {
|
||||||
|
false => { fn false_1() {} }
|
||||||
|
any(false, true) => { fn true_1() {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_select! {
|
||||||
|
false => { fn false_2() {} }
|
||||||
|
_ => { fn true_2() {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_select! {
|
||||||
|
false => { fn false_3() {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_select! {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_select! {
|
||||||
|
false =>
|
||||||
|
}
|
||||||
|
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro cfg_select($($tt:tt)*) {}
|
||||||
|
|
||||||
|
fn true_1() {}
|
||||||
|
|
||||||
|
fn true_2() {}
|
||||||
|
|
||||||
|
/* error: none of the predicates in this `cfg_select` evaluated to true */
|
||||||
|
|
||||||
|
/* error: expected `=>` after cfg expression */
|
||||||
|
|
||||||
|
/* error: expected a token tree after `=>` */
|
||||||
|
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -127,6 +127,7 @@ register_builtin! {
|
|||||||
(asm, Asm) => asm_expand,
|
(asm, Asm) => asm_expand,
|
||||||
(global_asm, GlobalAsm) => global_asm_expand,
|
(global_asm, GlobalAsm) => global_asm_expand,
|
||||||
(naked_asm, NakedAsm) => naked_asm_expand,
|
(naked_asm, NakedAsm) => naked_asm_expand,
|
||||||
|
(cfg_select, CfgSelect) => cfg_select_expand,
|
||||||
(cfg, Cfg) => cfg_expand,
|
(cfg, Cfg) => cfg_expand,
|
||||||
(core_panic, CorePanic) => panic_expand,
|
(core_panic, CorePanic) => panic_expand,
|
||||||
(std_panic, StdPanic) => panic_expand,
|
(std_panic, StdPanic) => panic_expand,
|
||||||
@ -355,6 +356,71 @@ fn naked_asm_expand(
|
|||||||
ExpandResult::ok(expanded)
|
ExpandResult::ok(expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cfg_select_expand(
|
||||||
|
db: &dyn ExpandDatabase,
|
||||||
|
id: MacroCallId,
|
||||||
|
tt: &tt::TopSubtree,
|
||||||
|
span: Span,
|
||||||
|
) -> ExpandResult<tt::TopSubtree> {
|
||||||
|
let loc = db.lookup_intern_macro_call(id);
|
||||||
|
let cfg_options = loc.krate.cfg_options(db);
|
||||||
|
|
||||||
|
let mut iter = tt.iter();
|
||||||
|
let mut expand_to = None;
|
||||||
|
while let Some(next) = iter.peek() {
|
||||||
|
let active = if let tt::TtElement::Leaf(tt::Leaf::Ident(ident)) = next
|
||||||
|
&& ident.sym == sym::underscore
|
||||||
|
{
|
||||||
|
iter.next();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
cfg_options.check(&CfgExpr::parse_from_iter(&mut iter)) != Some(false)
|
||||||
|
};
|
||||||
|
match iter.expect_glued_punct() {
|
||||||
|
Ok(it) if it.len() == 2 && it[0].char == '=' && it[1].char == '>' => {}
|
||||||
|
_ => {
|
||||||
|
let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span);
|
||||||
|
return ExpandResult::new(
|
||||||
|
tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
|
||||||
|
ExpandError::other(err_span, "expected `=>` after cfg expression"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let expand_to_if_active = match iter.next() {
|
||||||
|
Some(tt::TtElement::Subtree(_, tt)) => tt.remaining(),
|
||||||
|
_ => {
|
||||||
|
let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span);
|
||||||
|
return ExpandResult::new(
|
||||||
|
tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
|
||||||
|
ExpandError::other(err_span, "expected a token tree after `=>`"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if expand_to.is_none() && active {
|
||||||
|
expand_to = Some(expand_to_if_active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match expand_to {
|
||||||
|
Some(expand_to) => {
|
||||||
|
let mut builder = tt::TopSubtreeBuilder::new(tt::Delimiter {
|
||||||
|
kind: tt::DelimiterKind::Invisible,
|
||||||
|
open: span,
|
||||||
|
close: span,
|
||||||
|
});
|
||||||
|
builder.extend_with_tt(expand_to);
|
||||||
|
ExpandResult::ok(builder.build())
|
||||||
|
}
|
||||||
|
None => ExpandResult::new(
|
||||||
|
tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
|
||||||
|
ExpandError::other(
|
||||||
|
span,
|
||||||
|
"none of the predicates in this `cfg_select` evaluated to true",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn cfg_expand(
|
fn cfg_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
|
@ -10,7 +10,7 @@ use syntax::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
AssistId,
|
AssistId,
|
||||||
assist_context::{AssistContext, Assists, SourceChangeBuilder},
|
assist_context::{AssistContext, Assists, SourceChangeBuilder},
|
||||||
utils::generate_trait_impl_text,
|
utils::generate_trait_impl_text_intransitive,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assist: generate_deref
|
// Assist: generate_deref
|
||||||
@ -150,7 +150,7 @@ fn generate_edit(
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
let strukt_adt = ast::Adt::Struct(strukt);
|
let strukt_adt = ast::Adt::Struct(strukt);
|
||||||
let deref_impl = generate_trait_impl_text(
|
let deref_impl = generate_trait_impl_text_intransitive(
|
||||||
&strukt_adt,
|
&strukt_adt,
|
||||||
&trait_path.display(db, edition).to_string(),
|
&trait_path.display(db, edition).to_string(),
|
||||||
&impl_code,
|
&impl_code,
|
||||||
@ -227,6 +227,28 @@ impl core::ops::Deref for B {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_generate_record_deref_with_generic() {
|
||||||
|
check_assist(
|
||||||
|
generate_deref,
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
struct A<T>($0T);
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
struct A<T>(T);
|
||||||
|
|
||||||
|
impl<T> core::ops::Deref for A<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generate_record_deref_short_path() {
|
fn test_generate_record_deref_short_path() {
|
||||||
check_assist(
|
check_assist(
|
||||||
|
@ -134,6 +134,9 @@ fn get_trait_mut(apply_trait: &hir::Trait, famous: FamousDefs<'_, '_>) -> Option
|
|||||||
if trait_ == famous.core_borrow_Borrow().as_ref() {
|
if trait_ == famous.core_borrow_Borrow().as_ref() {
|
||||||
return Some("BorrowMut");
|
return Some("BorrowMut");
|
||||||
}
|
}
|
||||||
|
if trait_ == famous.core_ops_Deref().as_ref() {
|
||||||
|
return Some("DerefMut");
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +145,7 @@ fn process_method_name(name: ast::Name) -> Option<(ast::Name, &'static str)> {
|
|||||||
"index" => "index_mut",
|
"index" => "index_mut",
|
||||||
"as_ref" => "as_mut",
|
"as_ref" => "as_mut",
|
||||||
"borrow" => "borrow_mut",
|
"borrow" => "borrow_mut",
|
||||||
|
"deref" => "deref_mut",
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some((name, new_name))
|
Some((name, new_name))
|
||||||
@ -258,6 +262,39 @@ impl core::convert::AsRef<i32> for Foo {
|
|||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist(
|
||||||
|
generate_mut_trait_impl,
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
struct Foo(i32);
|
||||||
|
|
||||||
|
impl core::ops::Deref$0 for Foo {
|
||||||
|
type Target = i32;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
struct Foo(i32);
|
||||||
|
|
||||||
|
$0impl core::ops::DerefMut for Foo {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::Deref for Foo {
|
||||||
|
type Target = i32;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -567,6 +567,7 @@ pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String {
|
|||||||
///
|
///
|
||||||
/// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`.
|
/// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`.
|
||||||
// FIXME: migrate remaining uses to `generate_trait_impl`
|
// FIXME: migrate remaining uses to `generate_trait_impl`
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String {
|
pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String {
|
||||||
generate_impl_text_inner(adt, Some(trait_text), true, code)
|
generate_impl_text_inner(adt, Some(trait_text), true, code)
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ impl<'a> FindUsages<'a> {
|
|||||||
node.token_at_offset(offset)
|
node.token_at_offset(offset)
|
||||||
.find(|it| {
|
.find(|it| {
|
||||||
// `name` is stripped of raw ident prefix. See the comment on name retrieval below.
|
// `name` is stripped of raw ident prefix. See the comment on name retrieval below.
|
||||||
it.text().trim_start_matches("r#") == name
|
it.text().trim_start_matches('\'').trim_start_matches("r#") == name
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(move |token| {
|
.flat_map(move |token| {
|
||||||
@ -938,7 +938,12 @@ impl<'a> FindUsages<'a> {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
// We need to search without the `r#`, hence `as_str` access.
|
// We need to search without the `r#`, hence `as_str` access.
|
||||||
self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.as_str().to_smolstr())
|
// We strip `'` from lifetimes and labels as otherwise they may not match with raw-escaped ones,
|
||||||
|
// e.g. if we search `'foo` we won't find `'r#foo`.
|
||||||
|
self.def
|
||||||
|
.name(sema.db)
|
||||||
|
.or_else(self_kw_refs)
|
||||||
|
.map(|it| it.as_str().trim_start_matches('\'').to_smolstr())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let name = match &name {
|
let name = match &name {
|
||||||
|
@ -48,7 +48,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
|
|||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
let mut visited_comments = FxHashSet::default();
|
let mut visited_comments = FxHashSet::default();
|
||||||
let mut visited_nodes = FxHashSet::default();
|
let mut visited_nodes = FxHashSet::default();
|
||||||
let mut merged_fn_bodies = FxHashSet::default();
|
|
||||||
|
|
||||||
// regions can be nested, here is a LIFO buffer
|
// regions can be nested, here is a LIFO buffer
|
||||||
let mut region_starts: Vec<TextSize> = vec![];
|
let mut region_starts: Vec<TextSize> = vec![];
|
||||||
@ -73,7 +72,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(body) = fn_node.body() {
|
if fn_node.body().is_some() {
|
||||||
res.push(Fold {
|
res.push(Fold {
|
||||||
range: TextRange::new(
|
range: TextRange::new(
|
||||||
node.text_range().start(),
|
node.text_range().start(),
|
||||||
@ -81,7 +80,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
|
|||||||
),
|
),
|
||||||
kind: FoldKind::Function,
|
kind: FoldKind::Function,
|
||||||
});
|
});
|
||||||
merged_fn_bodies.insert(body.syntax().text_range());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3088,4 +3088,42 @@ fn main() {
|
|||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_labels_and_lifetimes() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn foo<'r#fn>(s: &'r#fn str) {
|
||||||
|
let _a: &'r#fn str = s;
|
||||||
|
let _b: &'r#fn str;
|
||||||
|
'r#break$0: {
|
||||||
|
break 'r#break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
'r#break Label FileId(0) 87..96 87..95
|
||||||
|
|
||||||
|
FileId(0) 113..121
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn foo<'r#fn$0>(s: &'r#fn str) {
|
||||||
|
let _a: &'r#fn str = s;
|
||||||
|
let _b: &'r#fn str;
|
||||||
|
'r#break: {
|
||||||
|
break 'r#break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
'r#fn LifetimeParam FileId(0) 7..12
|
||||||
|
|
||||||
|
FileId(0) 18..23
|
||||||
|
FileId(0) 44..49
|
||||||
|
FileId(0) 72..77
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,7 @@ define_symbols! {
|
|||||||
cfg_attr,
|
cfg_attr,
|
||||||
cfg_eval,
|
cfg_eval,
|
||||||
cfg,
|
cfg,
|
||||||
|
cfg_select,
|
||||||
char,
|
char,
|
||||||
clone,
|
clone,
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -217,6 +217,17 @@ pub enum TtElement<'a, S> {
|
|||||||
Subtree(&'a Subtree<S>, TtIter<'a, S>),
|
Subtree(&'a Subtree<S>, TtIter<'a, S>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Copy + fmt::Debug> fmt::Debug for TtElement<'_, S> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Leaf(leaf) => f.debug_tuple("Leaf").field(leaf).finish(),
|
||||||
|
Self::Subtree(subtree, inner) => {
|
||||||
|
f.debug_tuple("Subtree").field(subtree).field(inner).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: Copy> TtElement<'_, S> {
|
impl<S: Copy> TtElement<'_, S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn first_span(&self) -> S {
|
pub fn first_span(&self) -> S {
|
||||||
|
@ -1 +1 @@
|
|||||||
a9fb6103b05c6ad6eee6bed4c0bb5a2e8e1024c6
|
e05ab47e6c418fb2b9faa2eae9a7e70c65c98eaa
|
||||||
|
Loading…
x
Reference in New Issue
Block a user