-
Notifications
You must be signed in to change notification settings - Fork 1.7k
remove-unnecessary-else
bad suggestions and false positives on thread_local macro
#16556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm hitting the same issue here after upgrading the nightly rustc and rust-analyzer.
Here's the reproducible code. use icu_segmenter::LineSegmenter;
use syntect::{
highlighting::ThemeSet,
parsing::SyntaxSet,
};
thread_local! {
static SYNTHEME: (SyntaxSet, ThemeSet) = (
SyntaxSet::load_defaults_newlines(),
ThemeSet::load_defaults(),
);
static SEGMENTER: LineSegmenter = LineSegmenter::new_auto();
} You can see the BTW the warning disappears when the source file containing the above |
So, this is due to RA's const SYNTHEME: ::std::thread::LocalKey<(SyntaxSet, ThemeSet)> = {
#[inline]
fn __init() -> (SyntaxSet, ThemeSet) {
(SyntaxSet::load_defaults_newlines(), ThemeSet::load_defaults())
}
#[inline]
unsafe fn __getit(
init: ::std::option::Option<&mut ::std::option::Option<(SyntaxSet, ThemeSet)>>,
) -> ::std::option::Option<&'static (SyntaxSet, ThemeSet)> {
#[thread_local]
static __KEY: ::std::thread::local_impl::Key<(SyntaxSet, ThemeSet)> = ::std::thread::local_impl::Key::<
(SyntaxSet, ThemeSet),
>::new();
unsafe {
__KEY
.get(move || {
if let ::std::option::Option::Some(init) = init {
if let ::std::option::Option::Some(value) = init.take() {
return value;
} else if true {
{
::core::panicking::panic_fmt(
format_args!(
"internal error: entered unreachable code: {0}",
format_args!("missing default value"),
),
);
};
}
}
__init()
})
}
}
unsafe { ::std::thread::LocalKey::new(__getit) }
};
const SEGMENTER: ::std::thread::LocalKey<LineSegmenter> = {
#[inline]
fn __init() -> LineSegmenter {
LineSegmenter::new_auto()
}
#[inline]
unsafe fn __getit(
init: ::std::option::Option<&mut ::std::option::Option<LineSegmenter>>,
) -> ::std::option::Option<&'static LineSegmenter> {
#[thread_local]
static __KEY: ::std::thread::local_impl::Key<LineSegmenter> = ::std::thread::local_impl::Key::<
LineSegmenter,
>::new();
unsafe {
__KEY
.get(move || {
if let ::std::option::Option::Some(init) = init {
if let ::std::option::Option::Some(value) = init.take() {
return value;
} else if true {
{
::core::panicking::panic_fmt(
format_args!(
"internal error: entered unreachable code: {0}",
format_args!("missing default value"),
),
);
};
}
}
__init()
})
}
}
unsafe { ::std::thread::LocalKey::new(__getit) }
}; and this is not wrong as itself since if let ::std::option::Option::Some(value) = init.take() {
return value;
} else if true {
//^^^^ This `else` is unnecessary, indeed
{
::core::panicking::panic_fmt(
format_args!(
"internal error: entered unreachable code: {0}",
format_args!("missing default value"),
),
);
};
} So, we should look for another approach for this |
And I've opened a PR that fixes this from |
Happy to take the fix, but this is also an r-a bug, it shouldn't lint things from other crates like this (just like rustc does). |
Honestly, I'm not even sure the code is better after rust-lang/rust#121098. At best it's arguable, I think the changed code can make the meaning of the code less clear. if foo {
return bar;
} else {
do_something_else();
} changing to if foo {
return bar;
}
do_something_else(); is fine. But this code snippet if foo {
return bar;
} else if bar {
do_something_else();
} becoming if foo {
return bar;
}
if bar {
do_something_else();
} makes it less obvious that the intended condition for the second branch is |
Thanks, I'll take a look into the rustc's diagnostics on foreign crates' macro expansions. Maybe I could get some clues from them suitable for here |
That makes sense. I've seen many lsp/linters making warnings about similar if-else things and sometimes they are irritating and not seem to be "improved" by suggested changes. Are there some idiomatic agreements or decisions about this within rust analyzer maintainers or rust community? |
Thanks for looking into this! @ShoyuVanilla The thread_local case can be minimized as follows thread_local! {
static A : Vec<u8> = Vec::from([1]);
} I tried this snippet last night, but RA didn't report remove-unnecessary-else. At present, I tried again, this time RA does emit it 😮 (I didn't change anything about rustc and RA neither the configs) |
Since the |
…ary-else, r=Nilstrieb Remove unnecessary else block from `thread_local!` expanded code Some expanded codes make ["unnecessary else block" warnings](rust-lang/rust-analyzer#16556 (comment)) for Rust Analyzer
Rollup merge of rust-lang#121098 - ShoyuVanilla:thread-local-unnecessary-else, r=Nilstrieb Remove unnecessary else block from `thread_local!` expanded code Some expanded codes make ["unnecessary else block" warnings](rust-lang/rust-analyzer#16556 (comment)) for Rust Analyzer
I see this issue has been closed by #16590, but I wonder if it also fixes the following, which just happened to me today: rust-analyzer version: rust-analyzer 1.75.0-beta.5 (1a06ac5b5d7 2023-12-01) rustc version: rustc 1.74.1 (a28077b28 2023-12-04) Before (rewritten code just to show the faulty behaviour): fn test() {
let inner = || false;
let mut count = 0;
while count == 0 {
if true {
1;
continue;
} else { // Warning here
count += 1;
if !inner() {
return;
}
}
}
} After: fn test() {
let inner = || false;
let mut count = 0;
while count == 0 {
if true {
1;
continue;
}
count += 1;
}
} The call to // ...
if true {
1;
continue;
}
count += 1;
if !inner() {
return;
}
// ... |
@ergl I guess so because of this commit, which is included in that PR. |
rust-analyzer version: rust-analyzer 0.3.1839-standalone
rustc version: rustc 1.76.0 (07dca489a 2024-02-04)
relevant settings: Unlikely any are relevant
Bad suggestions: Given this code
remove-unnecessary-else suggests
which doesn't compile.
I also get false positives on
thread_local!{}
macros, but I don't have a minimal reproduction. In my projects it lints on everythread_local!{}
call, even those as simple asthread_local!(static SOMETHING: Cell<u32> = Cell::default());
but I don't get the lints in minimal projects.The text was updated successfully, but these errors were encountered: