From 68ce6596ec2104b4d541a796afe74e210bf5f4b9 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Mon, 18 Nov 2024 14:26:40 +0100 Subject: Promote powerpc64le-unknown-linux-musl to tier 2 with host tools MCP: https://github.com/rust-lang/compiler-team/issues/803 Signed-off-by: Jens Reidel --- src/tools/build-manifest/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/tools') diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 39d9158a1ff..561b611148a 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -37,6 +37,7 @@ static HOSTS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", "riscv64gc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "x86_64-apple-darwin", @@ -131,6 +132,7 @@ static TARGETS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-unknown-linux-musl", "riscv32i-unknown-none-elf", "riscv32im-risc0-zkvm-elf", "riscv32im-unknown-none-elf", -- cgit 1.4.1-3-g733a5 From 1bafbe12c08e9af46ff0a55b95c3f099bafeaff0 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 11 Dec 2024 09:24:24 +0100 Subject: Unload proc-macro dlls on changed timestamp --- .../crates/proc-macro-srv/src/dylib.rs | 15 ++++++++-- .../rust-analyzer/crates/proc-macro-srv/src/lib.rs | 34 ++++++++++++---------- 2 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 78ae4574c40..49a249f2cb6 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -3,7 +3,12 @@ mod version; use proc_macro::bridge; -use std::{fmt, fs::File, io}; +use std::{ + fmt, + fs::{self, File}, + io, + time::SystemTime, +}; use libloading::Library; use memmap2::Mmap; @@ -136,6 +141,7 @@ impl ProcMacroLibraryLibloading { pub(crate) struct Expander { inner: ProcMacroLibraryLibloading, path: Utf8PathBuf, + modified_time: SystemTime, } impl Drop for Expander { @@ -151,12 +157,13 @@ impl Expander { // Some libraries for dynamic loading require canonicalized path even when it is // already absolute let lib = lib.canonicalize_utf8()?; + let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?; let path = ensure_file_with_lock_free_access(&lib)?; let library = ProcMacroLibraryLibloading::open(path.as_ref())?; - Ok(Expander { inner: library, path }) + Ok(Expander { inner: library, path, modified_time }) } pub(crate) fn expand( @@ -181,6 +188,10 @@ impl Expander { pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { self.inner.proc_macros.list_macros() } + + pub(crate) fn modified_time(&self) -> SystemTime { + self.modified_time + } } /// Copy the dylib to temp directory to prevent locking in Windows diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f0aa6b3f93f..8e78e6f2e07 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -35,7 +35,6 @@ use std::{ fs, path::{Path, PathBuf}, thread, - time::SystemTime, }; use paths::{Utf8Path, Utf8PathBuf}; @@ -53,7 +52,7 @@ use crate::server_impl::TokenStream; pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION"); pub struct ProcMacroSrv<'env> { - expanders: HashMap<(Utf8PathBuf, SystemTime), dylib::Expander>, + expanders: HashMap, span_mode: SpanMode, env: &'env EnvSnapshot, } @@ -81,10 +80,9 @@ impl<'env> ProcMacroSrv<'env> { ) -> Result<(msg::FlatTree, Vec), msg::PanicMessage> { let span_mode = self.span_mode; let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| { - debug_assert!(false, "should list macros before asking to expand"); - msg::PanicMessage(format!("failed to load macro: {err}")) - })?; + let expander = self + .expander(lib.as_ref()) + .map_err(|err| msg::PanicMessage(format!("failed to load macro: {err}")))?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -107,16 +105,20 @@ impl<'env> ProcMacroSrv<'env> { } fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> { - let time = fs::metadata(path) - .and_then(|it| it.modified()) - .map_err(|err| format!("Failed to get file metadata for {path}: {err}",))?; - - Ok(match self.expanders.entry((path.to_path_buf(), time)) { - Entry::Vacant(v) => v.insert( - dylib::Expander::new(path) - .map_err(|err| format!("Cannot create expander for {path}: {err}",))?, - ), - Entry::Occupied(e) => e.into_mut(), + let expander = || { + dylib::Expander::new(path) + .map_err(|err| format!("Cannot create expander for {path}: {err}",)) + }; + + Ok(match self.expanders.entry(path.to_path_buf()) { + Entry::Vacant(v) => v.insert(expander()?), + Entry::Occupied(mut e) => { + let time = fs::metadata(path).and_then(|it| it.modified()).ok(); + if Some(e.get().modified_time()) != time { + e.insert(expander()?); + } + e.into_mut() + } }) } } -- cgit 1.4.1-3-g733a5 From aef05d468e67f7a103738694e643b2e57c499b10 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 11 Dec 2024 10:11:12 +0100 Subject: Fix copied proc-macros not being cleaned up on exit --- .../crates/proc-macro-srv/src/dylib.rs | 82 ++++++++++------------ .../crates/proc-macro-srv/src/dylib/version.rs | 26 +++---- 2 files changed, 49 insertions(+), 59 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 49a249f2cb6..828d49e6a21 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -3,17 +3,12 @@ mod version; use proc_macro::bridge; -use std::{ - fmt, - fs::{self, File}, - io, - time::SystemTime, -}; +use std::{fmt, fs, io, time::SystemTime}; use libloading::Library; use memmap2::Mmap; use object::Object; -use paths::{AbsPath, Utf8Path, Utf8PathBuf}; +use paths::{Utf8Path, Utf8PathBuf}; use proc_macro_api::ProcMacroKind; use crate::ProcMacroSrvSpan; @@ -28,14 +23,9 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool { symbol.contains(NEW_REGISTRAR_SYMBOL) } -fn find_registrar_symbol(file: &Utf8Path) -> io::Result> { - let file = File::open(file)?; - let buffer = unsafe { Mmap::map(&file)? }; - - Ok(object::File::parse(&*buffer) - .map_err(invalid_data_err)? - .exports() - .map_err(invalid_data_err)? +fn find_registrar_symbol(buffer: &[u8]) -> object::Result> { + Ok(object::File::parse(buffer)? + .exports()? .into_iter() .map(|export| export.name()) .filter_map(|sym| String::from_utf8(sym.into()).ok()) @@ -118,17 +108,17 @@ struct ProcMacroLibraryLibloading { } impl ProcMacroLibraryLibloading { - fn open(file: &Utf8Path) -> Result { - let symbol_name = find_registrar_symbol(file)?.ok_or_else(|| { - invalid_data_err(format!("Cannot find registrar symbol in file {file}")) - })?; + fn open(path: &Utf8Path) -> Result { + let buffer = unsafe { Mmap::map(&fs::File::open(path)?)? }; + let symbol_name = + find_registrar_symbol(&buffer).map_err(invalid_data_err)?.ok_or_else(|| { + invalid_data_err(format!("Cannot find registrar symbol in file {path}")) + })?; - let abs_file: &AbsPath = file - .try_into() - .map_err(|_| invalid_data_err(format!("expected an absolute path, got {file}")))?; - let version_info = version::read_dylib_info(abs_file)?; + let version_info = version::read_dylib_info(&buffer)?; + drop(buffer); - let lib = load_library(file).map_err(invalid_data_err)?; + let lib = load_library(path).map_err(invalid_data_err)?; let proc_macros = crate::proc_macros::ProcMacros::from_lib( &lib, symbol_name, @@ -138,20 +128,22 @@ impl ProcMacroLibraryLibloading { } } -pub(crate) struct Expander { - inner: ProcMacroLibraryLibloading, - path: Utf8PathBuf, - modified_time: SystemTime, -} - -impl Drop for Expander { +struct RemoveFileOnDrop(Utf8PathBuf); +impl Drop for RemoveFileOnDrop { fn drop(&mut self) { #[cfg(windows)] - std::fs::remove_file(&self.path).ok(); - _ = self.path; + std::fs::remove_file(&self.0).unwrap(); + _ = self.0; } } +// Drop order matters as we can't remove the dylib before the library is unloaded +pub(crate) struct Expander { + inner: ProcMacroLibraryLibloading, + _remove_on_drop: RemoveFileOnDrop, + modified_time: SystemTime, +} + impl Expander { pub(crate) fn new(lib: &Utf8Path) -> Result { // Some libraries for dynamic loading require canonicalized path even when it is @@ -160,10 +152,9 @@ impl Expander { let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?; let path = ensure_file_with_lock_free_access(&lib)?; - let library = ProcMacroLibraryLibloading::open(path.as_ref())?; - Ok(Expander { inner: library, path, modified_time }) + Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time }) } pub(crate) fn expand( @@ -205,20 +196,23 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result } let mut to = Utf8PathBuf::from_path_buf(std::env::temp_dir()).unwrap(); + to.push("rust-analyzer-proc-macros"); + _ = fs::create_dir(&to); let file_name = path.file_name().ok_or_else(|| { io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}")) })?; - // Generate a unique number by abusing `HashMap`'s hasher. - // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd. - let t = RandomState::new().build_hasher().finish(); - - let mut unique_name = t.to_string(); - unique_name.push_str(file_name); - - to.push(unique_name); - std::fs::copy(path, &to)?; + to.push({ + // Generate a unique number by abusing `HashMap`'s hasher. + // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd. + let t = RandomState::new().build_hasher().finish(); + let mut unique_name = t.to_string(); + unique_name.push_str(file_name); + unique_name.push('-'); + unique_name + }); + fs::copy(path, &to)?; Ok(to) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs index 7f0e95c50de..c1804e4fef7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs @@ -1,13 +1,8 @@ //! Reading proc-macro rustc version information from binary data -use std::{ - fs::File, - io::{self, Read}, -}; +use std::io::{self, Read}; -use memmap2::Mmap; use object::read::{File as BinaryFile, Object, ObjectSection}; -use paths::AbsPath; #[derive(Debug)] #[allow(dead_code)] @@ -21,14 +16,14 @@ pub struct RustCInfo { } /// Read rustc dylib information -pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result { +pub fn read_dylib_info(buffer: &[u8]) -> io::Result { macro_rules! err { ($e:literal) => { io::Error::new(io::ErrorKind::InvalidData, $e) }; } - let ver_str = read_version(dylib_path)?; + let ver_str = read_version(buffer)?; let mut items = ver_str.split_whitespace(); let tag = items.next().ok_or_else(|| err!("version format error"))?; if tag != "rustc" { @@ -106,11 +101,8 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&' /// /// Check this issue for more about the bytes layout: /// -pub fn read_version(dylib_path: &AbsPath) -> io::Result { - let dylib_file = File::open(dylib_path)?; - let dylib_mmapped = unsafe { Mmap::map(&dylib_file) }?; - - let dot_rustc = read_section(&dylib_mmapped, ".rustc")?; +pub fn read_version(buffer: &[u8]) -> io::Result { + let dot_rustc = read_section(buffer, ".rustc")?; // check if magic is valid if &dot_rustc[0..4] != b"rust" { @@ -159,8 +151,12 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result { #[test] fn test_version_check() { - let path = paths::AbsPathBuf::assert(crate::proc_macro_test_dylib_path()); - let info = read_dylib_info(&path).unwrap(); + let info = read_dylib_info(&unsafe { + memmap2::Mmap::map(&std::fs::File::open(crate::proc_macro_test_dylib_path()).unwrap()) + .unwrap() + }) + .unwrap(); + assert_eq!( info.version_string, crate::RUSTC_VERSION_STRING, -- cgit 1.4.1-3-g733a5 From 3dcda33851225e3f7bdc7668285dd4b9316a2ad3 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:14:22 -0500 Subject: minor: Add `item_const` constructor to `SyntaxFactory` --- .../syntax/src/ast/syntax_factory/constructors.rs | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index e86c291f76c..d2ab30fb47d 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -188,6 +188,33 @@ impl SyntaxFactory { ast } + pub fn item_const( + &self, + visibility: Option, + name: ast::Name, + ty: ast::Type, + expr: ast::Expr, + ) -> ast::Const { + let ast = make::item_const(visibility.clone(), name.clone(), ty.clone(), expr.clone()) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn turbofish_generic_arg_list( &self, args: impl IntoIterator + Clone, -- cgit 1.4.1-3-g733a5 From 92ba35009c8902c7819a94296da51e3737b66480 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:31:43 -0500 Subject: internal: Move `is_body_const` to `ide_assists::utils` --- .../src/handlers/promote_local_to_const.rs | 44 ++-------------------- .../rust-analyzer/crates/ide-assists/src/utils.rs | 44 ++++++++++++++++++++-- 2 files changed, 44 insertions(+), 44 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs index 7c2dc0e0c10..0cc771ff397 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -1,19 +1,17 @@ -use hir::{HirDisplay, ModuleDef, PathResolution, Semantics}; +use hir::HirDisplay; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, - syntax_helpers::node_ext::preorder_expr, - RootDatabase, }; use stdx::to_upper_snake_case; use syntax::{ ast::{self, make, HasName}, - ted, AstNode, WalkEvent, + ted, AstNode, }; use crate::{ assist_context::{AssistContext, Assists}, - utils, + utils::{self}, }; // Assist: promote_local_to_const @@ -63,7 +61,7 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) }; let initializer = let_stmt.initializer()?; - if !is_body_const(&ctx.sema, &initializer) { + if !utils::is_body_const(&ctx.sema, &initializer) { cov_mark::hit!(promote_local_non_const); return None; } @@ -103,40 +101,6 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) ) } -fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool { - let mut is_const = true; - preorder_expr(expr, &mut |ev| { - let expr = match ev { - WalkEvent::Enter(_) if !is_const => return true, - WalkEvent::Enter(expr) => expr, - WalkEvent::Leave(_) => return false, - }; - match expr { - ast::Expr::CallExpr(call) => { - if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() { - if let Some(PathResolution::Def(ModuleDef::Function(func))) = - path_expr.path().and_then(|path| sema.resolve_path(&path)) - { - is_const &= func.is_const(sema.db); - } - } - } - ast::Expr::MethodCallExpr(call) => { - is_const &= - sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true) - } - ast::Expr::ForExpr(_) - | ast::Expr::ReturnExpr(_) - | ast::Expr::TryExpr(_) - | ast::Expr::YieldExpr(_) - | ast::Expr::AwaitExpr(_) => is_const = false, - _ => (), - } - !is_const - }); - is_const -} - #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 0830017bd0f..3c26b043597 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -3,11 +3,13 @@ pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ db::{ExpandDatabase, HirDatabase}, - HasAttrs as HirHasAttrs, HirDisplay, InFile, Semantics, + HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, Semantics, }; use ide_db::{ - famous_defs::FamousDefs, path_transform::PathTransform, - syntax_helpers::prettify_macro_expansion, RootDatabase, + famous_defs::FamousDefs, + path_transform::PathTransform, + syntax_helpers::{node_ext::preorder_expr, prettify_macro_expansion}, + RootDatabase, }; use stdx::format_to; use syntax::{ @@ -19,7 +21,7 @@ use syntax::{ }, ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextRange, TextSize, T, + SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, }; use crate::assist_context::{AssistContext, SourceChangeBuilder}; @@ -966,3 +968,37 @@ pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec, expr: &ast::Expr) -> bool { + let mut is_const = true; + preorder_expr(expr, &mut |ev| { + let expr = match ev { + WalkEvent::Enter(_) if !is_const => return true, + WalkEvent::Enter(expr) => expr, + WalkEvent::Leave(_) => return false, + }; + match expr { + ast::Expr::CallExpr(call) => { + if let Some(ast::Expr::PathExpr(path_expr)) = call.expr() { + if let Some(PathResolution::Def(ModuleDef::Function(func))) = + path_expr.path().and_then(|path| sema.resolve_path(&path)) + { + is_const &= func.is_const(sema.db); + } + } + } + ast::Expr::MethodCallExpr(call) => { + is_const &= + sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true) + } + ast::Expr::ForExpr(_) + | ast::Expr::ReturnExpr(_) + | ast::Expr::TryExpr(_) + | ast::Expr::YieldExpr(_) + | ast::Expr::AwaitExpr(_) => is_const = false, + _ => (), + } + !is_const + }); + is_const +} -- cgit 1.4.1-3-g733a5 From e2300523272ba9755872b83062083e7a04b5c94d Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:23:36 -0500 Subject: feat: Add an assist to extract an expression into a constant --- .../ide-assists/src/handlers/extract_variable.rs | 896 ++++++++++++++++----- .../rust-analyzer/crates/ide-assists/src/tests.rs | 122 ++- .../crates/ide-assists/src/tests/generated.rs | 18 + 3 files changed, 847 insertions(+), 189 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 61dc72e0b33..6670eac6a7a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -1,4 +1,4 @@ -use hir::TypeInfo; +use hir::{HirDisplay, TypeInfo}; use ide_db::syntax_helpers::suggest_name; use syntax::{ ast::{ @@ -7,11 +7,11 @@ use syntax::{ }, syntax_editor::Position, NodeOrToken, - SyntaxKind::{BLOCK_EXPR, BREAK_EXPR, COMMENT, LOOP_EXPR, MATCH_GUARD, PATH_EXPR, RETURN_EXPR}, + SyntaxKind::{self}, SyntaxNode, T, }; -use crate::{AssistContext, AssistId, AssistKind, Assists}; +use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists}; // Assist: extract_variable // @@ -29,6 +29,23 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // var_name * 4; // } // ``` + +// Assist: extract_constant +// +// Extracts subexpression into a constant. +// +// ``` +// fn main() { +// $0(1 + 2)$0 * 4; +// } +// ``` +// -> +// ``` +// fn main() { +// const $0VAR_NAME: i32 = 1 + 2; +// VAR_NAME * 4; +// } +// ``` pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let node = if ctx.has_empty_selection() { if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) { @@ -41,7 +58,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } else { match ctx.covering_element() { NodeOrToken::Node(it) => it, - NodeOrToken::Token(it) if it.kind() == COMMENT => { + NodeOrToken::Token(it) if it.kind() == SyntaxKind::COMMENT => { cov_mark::hit!(extract_var_in_comment_is_not_applicable); return None; } @@ -87,27 +104,39 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } _ => false, }; - - let anchor = Anchor::from(&to_extract)?; + let module = ctx.sema.scope(to_extract.syntax())?.module(); let target = to_extract.syntax().text_range(); - acc.add( - AssistId("extract_variable", AssistKind::RefactorExtract), - "Extract into variable", - target, - move |edit| { - let field_shorthand = to_extract - .syntax() - .parent() - .and_then(ast::RecordExprField::cast) - .filter(|field| field.name_ref().is_some()); - - let (var_name, expr_replace) = match field_shorthand { - Some(field) => (field.to_string(), field.syntax().clone()), - None => ( - suggest_name::for_variable(&to_extract, &ctx.sema), - to_extract.syntax().clone(), - ), - }; + let needs_mut = match &parent { + Some(ast::Expr::RefExpr(expr)) => expr.mut_token().is_some(), + _ => needs_adjust && !needs_ref && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()), + }; + for kind in ExtractionKind::ALL { + let Some(anchor) = Anchor::from(&to_extract, kind) else { + continue; + }; + let ty_string = match kind { + ExtractionKind::Constant => { + let Some(ty) = ty.clone() else { + continue; + }; + + // We can't mutably reference a const, nor can we define + // one using a non-const expression or one of unknown type + if needs_mut || !is_body_const(&ctx.sema, &to_extract_no_ref) || ty.is_unknown() { + continue; + } + + let Ok(type_string) = ty.display_source_code(ctx.db(), module.into(), false) else { + continue; + }; + + type_string + } + _ => "".to_owned(), + }; + + acc.add(kind.assist_id(), kind.label(), target, |edit| { + let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract); let make = SyntaxFactory::new(); let mut editor = edit.make_editor(&expr_replace); @@ -120,35 +149,31 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op editor.add_annotation(pat_name.syntax().clone(), tabstop); } - let ident_pat = match parent { - Some(ast::Expr::RefExpr(expr)) if expr.mut_token().is_some() => { - make.ident_pat(false, true, pat_name) + let initializer = match ty.as_ref().filter(|_| needs_ref) { + Some(receiver_type) if receiver_type.is_mutable_reference() => { + make.expr_ref(to_extract_no_ref.clone(), true) } - _ if needs_adjust - && !needs_ref - && ty.as_ref().is_some_and(|ty| ty.is_mutable_reference()) => - { - make.ident_pat(false, true, pat_name) + Some(receiver_type) if receiver_type.is_reference() => { + make.expr_ref(to_extract_no_ref.clone(), false) } - _ => make.ident_pat(false, false, pat_name), + _ => to_extract_no_ref.clone(), }; - let to_extract_no_ref = match ty.as_ref().filter(|_| needs_ref) { - Some(receiver_type) if receiver_type.is_mutable_reference() => { - make.expr_ref(to_extract_no_ref, true) + let new_stmt: ast::Stmt = match kind { + ExtractionKind::Variable => { + let ident_pat = make.ident_pat(false, needs_mut, pat_name); + make.let_stmt(ident_pat.into(), None, Some(initializer)).into() } - Some(receiver_type) if receiver_type.is_reference() => { - make.expr_ref(to_extract_no_ref, false) + ExtractionKind::Constant => { + let ast_ty = make.ty(&ty_string); + ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer)).into() } - _ => to_extract_no_ref, }; - let let_stmt = make.let_stmt(ident_pat.into(), None, Some(to_extract_no_ref)); - - match anchor { + match &anchor { Anchor::Before(place) => { let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token()); - let indent_to = IndentLevel::from_node(&place); + let indent_to = IndentLevel::from_node(place); // Adjust ws to insert depending on if this is all inline or on separate lines let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) { @@ -160,7 +185,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op editor.insert_all( Position::before(place), vec![ - let_stmt.syntax().clone().into(), + new_stmt.syntax().clone().into(), make::tokens::whitespace(&trailing_ws).into(), ], ); @@ -170,7 +195,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op Anchor::Replace(stmt) => { cov_mark::hit!(test_extract_var_expr_stmt); - editor.replace(stmt.syntax(), let_stmt.syntax()); + editor.replace(stmt.syntax(), new_stmt.syntax()); } Anchor::WrapInBlock(to_wrap) => { let indent_to = to_wrap.indent_level(); @@ -178,11 +203,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let block = if to_wrap.syntax() == &expr_replace { // Since `expr_replace` is the same that needs to be wrapped in a block, // we can just directly replace it with a block - make.block_expr([let_stmt.into()], Some(name_expr)) + make.block_expr([new_stmt], Some(name_expr)) } else { // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`. editor.replace(expr_replace, name_expr.syntax()); - make.block_expr([let_stmt.into()], Some(to_wrap.clone())) + make.block_expr([new_stmt], Some(to_wrap.clone())) }; editor.replace(to_wrap.syntax(), block.syntax()); @@ -195,8 +220,10 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.file_id(), editor); edit.rename(); - }, - ) + }); + } + + Some(()) } fn peel_parens(mut expr: ast::Expr) -> ast::Expr { @@ -211,17 +238,67 @@ fn peel_parens(mut expr: ast::Expr) -> ast::Expr { /// In general that's true for any expression, but in some cases that would produce invalid code. fn valid_target_expr(node: SyntaxNode) -> Option { match node.kind() { - PATH_EXPR | LOOP_EXPR => None, - BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), - RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()), - BLOCK_EXPR => { + SyntaxKind::PATH_EXPR | SyntaxKind::LOOP_EXPR => None, + SyntaxKind::BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), + SyntaxKind::RETURN_EXPR => ast::ReturnExpr::cast(node).and_then(|e| e.expr()), + SyntaxKind::BLOCK_EXPR => { ast::BlockExpr::cast(node).filter(|it| it.is_standalone()).map(ast::Expr::from) } _ => ast::Expr::cast(node), } } -#[derive(Debug)] +enum ExtractionKind { + Variable, + Constant, +} + +impl ExtractionKind { + const ALL: &'static [ExtractionKind] = &[ExtractionKind::Variable, ExtractionKind::Constant]; + + fn assist_id(&self) -> AssistId { + let s = match self { + ExtractionKind::Variable => "extract_variable", + ExtractionKind::Constant => "extract_constant", + }; + + AssistId(s, AssistKind::RefactorExtract) + } + + fn label(&self) -> &'static str { + match self { + ExtractionKind::Variable => "Extract into variable", + ExtractionKind::Constant => "Extract into constant", + } + } + + fn get_name_and_expr( + &self, + ctx: &AssistContext<'_>, + to_extract: &ast::Expr, + ) -> (String, SyntaxNode) { + let field_shorthand = to_extract + .syntax() + .parent() + .and_then(ast::RecordExprField::cast) + .filter(|field| field.name_ref().is_some()); + let (var_name, expr_replace) = match field_shorthand { + Some(field) => (field.to_string(), field.syntax().clone()), + None => { + (suggest_name::for_variable(to_extract, &ctx.sema), to_extract.syntax().clone()) + } + }; + + let var_name = match self { + ExtractionKind::Variable => var_name, + ExtractionKind::Constant => var_name.to_uppercase(), + }; + + (var_name, expr_replace) + } +} + +#[derive(Debug, Clone)] enum Anchor { Before(SyntaxNode), Replace(ast::ExprStmt), @@ -229,8 +306,8 @@ enum Anchor { } impl Anchor { - fn from(to_extract: &ast::Expr) -> Option { - to_extract + fn from(to_extract: &ast::Expr, kind: &ExtractionKind) -> Option { + let result = to_extract .syntax() .ancestors() .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind())) @@ -253,7 +330,7 @@ impl Anchor { return parent.body().map(Anchor::WrapInBlock); } if let Some(parent) = ast::MatchArm::cast(parent) { - if node.kind() == MATCH_GUARD { + if node.kind() == SyntaxKind::MATCH_GUARD { cov_mark::hit!(test_extract_var_in_match_guard); } else { cov_mark::hit!(test_extract_var_in_match_arm_no_block); @@ -271,19 +348,57 @@ impl Anchor { return Some(Anchor::Before(node)); } None - }) + }); + + match kind { + ExtractionKind::Constant if result.is_none() => { + to_extract.syntax().ancestors().find_map(|node| { + let item = ast::Item::cast(node.clone())?; + let parent = item.syntax().parent()?; + match parent.kind() { + SyntaxKind::ITEM_LIST + | SyntaxKind::SOURCE_FILE + | SyntaxKind::ASSOC_ITEM_LIST + | SyntaxKind::STMT_LIST => Some(Anchor::Before(node)), + _ => None, + } + }) + } + _ => result, + } } } #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + // NOTE: We use check_assist_by_label, but not check_assist_not_applicable_by_label + // because all of our not-applicable tests should behave that way for both assists + // extract_variable offers, and check_assist_not_applicable ensures neither is offered + use crate::tests::{ + check_assist_by_label, check_assist_not_applicable, check_assist_not_applicable_by_label, + check_assist_target, + }; use super::*; #[test] - fn test_extract_var_simple_without_select() { - check_assist( + fn now_bad() { + // unknown type + check_assist_not_applicable_by_label( + extract_variable, + r#" +fn main() { + let a = Some(2); + a.is_some();$0 +} +"#, + "Extract into constant", + ); + } + + #[test] + fn extract_var_simple_without_select() { + check_assist_by_label( extract_variable, r#" fn main() -> i32 { @@ -304,9 +419,10 @@ fn main() -> i32 { var_name } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() -> i32 { 1 } @@ -320,9 +436,10 @@ fn main() { let $0foo = foo(); } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -336,9 +453,10 @@ fn main() { let $0is_some = a.is_some(); } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -350,9 +468,10 @@ fn main() { let $0var_name = "hello"; } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -364,9 +483,10 @@ fn main() { let $0var_name = 1 + 2; } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -384,11 +504,107 @@ fn main() { }; } "#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_simple_without_select() { + check_assist_by_label( + extract_variable, + r#" +fn main() -> i32 { + if true { + 1 + } else { + 2 + }$0 +} +"#, + r#" +fn main() -> i32 { + const $0VAR_NAME: i32 = if true { + 1 + } else { + 2 + }; + VAR_NAME +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo() -> i32 { 1 } +fn main() { + foo();$0 +} +"#, + r#" +const fn foo() -> i32 { 1 } +fn main() { + const $0FOO: i32 = foo(); +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + "hello"$0; +} +"#, + r#" +fn main() { + const $0VAR_NAME: &str = "hello"; +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + 1 + 2$0; +} +"#, + r#" +fn main() { + const $0VAR_NAME: i32 = 1 + 2; +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + match () { + () if true => 1, + _ => 2, + };$0 +} +"#, + r#" +fn main() { + const $0VAR_NAME: i32 = match () { + () if true => 1, + _ => 2, + }; +} +"#, + "Extract into constant", ); } #[test] - fn test_extract_var_unit_expr_without_select_not_applicable() { + fn extract_var_unit_expr_without_select_not_applicable() { check_assist_not_applicable( extract_variable, r#" @@ -414,8 +630,8 @@ fn foo() { } #[test] - fn test_extract_var_simple() { - check_assist( + fn extract_var_simple() { + check_assist_by_label( extract_variable, r#" fn foo() { @@ -426,19 +642,37 @@ fn foo() { let $0var_name = 1 + 1; foo(var_name); }"#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_simple() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + foo($01 + 1$0); +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; + foo(VAR_NAME); +}"#, + "Extract into constant", ); } #[test] fn extract_var_in_comment_is_not_applicable() { cov_mark::check!(extract_var_in_comment_is_not_applicable); - check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }"); + check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#); } #[test] - fn test_extract_var_expr_stmt() { + fn extract_var_expr_stmt() { cov_mark::check!(test_extract_var_expr_stmt); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() { @@ -448,42 +682,94 @@ fn foo() { fn foo() { let $0var_name = 1 + 1; }"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - r" + r#" fn foo() { $0{ let x = 0; x }$0; something_else(); -}", - r" +}"#, + r#" fn foo() { let $0var_name = { let x = 0; x }; something_else(); -}", +}"#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_expr_stmt() { + cov_mark::check!(test_extract_var_expr_stmt); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0 1 + 1$0; +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; +}"#, + "Extract into constant", + ); + // This is hilarious but as far as I know, it's valid + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0{ let x = 0; x }$0; + something_else(); +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = { let x = 0; x }; + something_else(); +}"#, + "Extract into constant", ); } #[test] - fn test_extract_var_part_of_expr_stmt() { - check_assist( + fn extract_var_part_of_expr_stmt() { + check_assist_by_label( extract_variable, - r" + r#" fn foo() { $01$0 + 1; -}", - r" +}"#, + r#" fn foo() { let $0var_name = 1; var_name + 1; -}", +}"#, + "Extract into variable", ); } #[test] - fn test_extract_var_last_expr() { + fn extract_const_part_of_expr_stmt() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $01$0 + 1; +}"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1; + VAR_NAME + 1; +}"#, + "Extract into constant", + ); + } + + #[test] + fn extract_var_last_expr() { cov_mark::check!(test_extract_var_last_expr); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() { @@ -496,8 +782,9 @@ fn foo() { bar(var_name) } "#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, r#" fn foo() -> i32 { @@ -518,13 +805,57 @@ fn bar(i: i32) -> i32 { i } "#, + "Extract into variable", ) } #[test] - fn test_extract_var_in_match_arm_no_block() { + fn extract_const_last_expr() { + cov_mark::check!(test_extract_var_last_expr); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + bar($01 + 1$0) +} +"#, + r#" +fn foo() { + const $0VAR_NAME: i32 = 1 + 1; + bar(VAR_NAME) +} +"#, + "Extract into constant", + ); + check_assist_by_label( + extract_variable, + r#" +fn foo() -> i32 { + $0bar(1 + 1)$0 +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + r#" +fn foo() -> i32 { + const $0BAR: i32 = bar(1 + 1); + BAR +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + "Extract into constant", + ) + } + + #[test] + fn extract_var_in_match_arm_no_block() { cov_mark::check!(test_extract_var_in_match_arm_no_block); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -547,12 +878,13 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_match_arm_with_block() { - check_assist( + fn extract_var_in_match_arm_with_block() { + check_assist_by_label( extract_variable, r#" fn main() { @@ -579,13 +911,14 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_match_guard() { + fn extract_var_in_match_guard() { cov_mark::check!(test_extract_var_in_match_guard); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -604,13 +937,14 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_closure_no_block() { + fn extract_var_in_closure_no_block() { cov_mark::check!(test_extract_var_in_closure_no_block); - check_assist( + check_assist_by_label( extract_variable, r#" fn main() { @@ -625,12 +959,13 @@ fn main() { }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_in_closure_with_block() { - check_assist( + fn extract_var_in_closure_with_block() { + check_assist_by_label( extract_variable, r#" fn main() { @@ -642,104 +977,110 @@ fn main() { let lambda = |x: u32| { let $0var_name = x * 2; var_name }; } "#, + "Extract into variable", ); } #[test] - fn test_extract_var_path_simple() { - check_assist( + fn extract_var_path_simple() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let o = $0Some(true)$0; } -", - " +"#, + r#" fn main() { let $0var_name = Some(true); let o = var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_path_method() { - check_assist( + fn extract_var_path_method() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let v = $0bar.foo()$0; } -", - " +"#, + r#" fn main() { let $0foo = bar.foo(); let v = foo; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_return() { - check_assist( + fn extract_var_return() { + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_does_not_add_extra_whitespace() { - check_assist( + fn extract_var_does_not_add_extra_whitespace() { + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); - check_assist( + check_assist_by_label( extract_variable, - " + r#" fn foo() -> u32 { let foo = 1; @@ -748,8 +1089,8 @@ fn foo() -> u32 { $0return 2 + 2$0; } -", - " +"#, + r#" fn foo() -> u32 { let foo = 1; @@ -759,53 +1100,56 @@ fn foo() -> u32 { let $0var_name = 2 + 2; return var_name; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_break() { - check_assist( + fn extract_var_break() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let result = loop { $0break 2 + 2$0; }; } -", - " +"#, + r#" fn main() { let result = loop { let $0var_name = 2 + 2; break var_name; }; } -", +"#, + "Extract into variable", ); } #[test] - fn test_extract_var_for_cast() { - check_assist( + fn extract_var_for_cast() { + check_assist_by_label( extract_variable, - " + r#" fn main() { let v = $00f32 as u32$0; } -", - " +"#, + r#" fn main() { let $0var_name = 0f32 as u32; let v = var_name; } -", +"#, + "Extract into variable", ); } #[test] fn extract_var_field_shorthand() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S { @@ -826,12 +1170,13 @@ fn main() { S { foo } } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_type() { - check_assist( + check_assist_by_label( extract_variable, r#" struct Test(i32); @@ -848,12 +1193,13 @@ fn foo() -> Test { test } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_parameter() { - check_assist( + check_assist_by_label( extract_variable, r#" fn bar(test: u32, size: u32) @@ -870,12 +1216,13 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_var_parameter_name_has_precedence_over_type() { - check_assist( + check_assist_by_label( extract_variable, r#" struct TextSize(u32); @@ -894,12 +1241,13 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_function() { - check_assist( + check_assist_by_label( extract_variable, r#" fn is_required(test: u32, size: u32) -> bool @@ -916,12 +1264,13 @@ fn foo() -> bool { is_required } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_method() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -944,12 +1293,13 @@ fn foo() -> u32 { bar } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_method_param() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -972,12 +1322,13 @@ fn foo() { S.bar(n, 2) } "#, + "Extract into variable", ) } #[test] fn extract_var_name_from_ufcs_method_param() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1000,12 +1351,13 @@ fn foo() { S::bar(&S, n, 2) } "#, + "Extract into variable", ) } #[test] fn extract_var_parameter_name_has_precedence_over_function() { - check_assist( + check_assist_by_label( extract_variable, r#" fn bar(test: u32, size: u32) @@ -1022,14 +1374,15 @@ fn foo() { bar(1, size); } "#, + "Extract into variable", ) } #[test] fn extract_macro_call() { - check_assist( + check_assist_by_label( extract_variable, - r" + r#" struct Vec; macro_rules! vec { () => {Vec} @@ -1037,8 +1390,8 @@ macro_rules! vec { fn main() { let _ = $0vec![]$0; } -", - r" +"#, + r#" struct Vec; macro_rules! vec { () => {Vec} @@ -1047,22 +1400,47 @@ fn main() { let $0vec = vec![]; let _ = vec; } -", +"#, + "Extract into variable", + ); + + check_assist_by_label( + extract_variable, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + let _ = $0vec![]$0; +} +"#, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + const $0VEC: Vec = vec![]; + let _ = VEC; +} +"#, + "Extract into constant", ); } #[test] - fn test_extract_var_for_return_not_applicable() { + fn extract_var_for_return_not_applicable() { check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } "); } #[test] - fn test_extract_var_for_break_not_applicable() { + fn extract_var_for_break_not_applicable() { check_assist_not_applicable(extract_variable, "fn main() { loop { $0break$0; }; }"); } #[test] - fn test_extract_var_unit_expr_not_applicable() { + fn extract_var_unit_expr_not_applicable() { check_assist_not_applicable( extract_variable, r#" @@ -1080,11 +1458,11 @@ fn foo() { // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic #[test] fn extract_var_target() { - check_assist_target(extract_variable, "fn foo() -> u32 { $0return 2 + 2$0; }", "2 + 2"); + check_assist_target(extract_variable, r#"fn foo() -> u32 { $0return 2 + 2$0; }"#, "2 + 2"); check_assist_target( extract_variable, - " + r#" fn main() { let x = true; let tuple = match x { @@ -1092,24 +1470,128 @@ fn main() { _ => (0, false) }; } -", +"#, "2 + 2", ); } #[test] fn extract_var_no_block_body() { - check_assist_not_applicable( + check_assist_not_applicable_by_label( extract_variable, - r" + r#" const X: usize = $0100$0; -", +"#, + "Extract into variable", + ); + } + + #[test] + fn extract_const_no_block_body() { + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const FOO: i32 = foo($0100$0); +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const $0X: i32 = 100; +const FOO: i32 = foo(X); +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +mod foo { + enum Foo { + Bar, + Baz = $042$0, + } +} +"#, + r#" +mod foo { + const $0VAR_NAME: isize = 42; + enum Foo { + Bar, + Baz = VAR_NAME, + } +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const World = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const $0X: i32 = 42; + const World = foo(X); +} +"#, + "Extract into constant", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const BAZ: i32 = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const $0X: i32 = 42; + const BAZ: i32 = foo(X); +} +"#, + "Extract into constant", ); } #[test] - fn test_extract_var_mutable_reference_parameter() { - check_assist( + fn extract_var_mutable_reference_parameter() { + check_assist_by_label( extract_variable, r#" struct S { @@ -1138,12 +1620,34 @@ fn foo(s: &mut S) { let $0vec = &mut s.vec; vec.push(0); }"#, + "Extract into variable", + ); + } + + #[test] + fn dont_extract_const_mutable_reference_parameter() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +struct S { + vec: Vec +} + +struct Vec; +impl Vec { + fn push(&mut self, _:usize) {} +} + +fn foo(s: &mut S) { + $0s.vec$0.push(0); +}"#, + "Extract into const", ); } #[test] - fn test_extract_var_mutable_reference_parameter_deep_nesting() { - check_assist( + fn extract_var_mutable_reference_parameter_deep_nesting() { + check_assist_by_label( extract_variable, r#" struct Y { @@ -1182,12 +1686,13 @@ fn foo(f: &mut Y) { let $0vec = &mut f.field.field.vec; vec.push(0); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_parameter() { - check_assist( + fn extract_var_reference_parameter() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1222,12 +1727,13 @@ fn foo(s: &S) { let $0x = &s.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_index_deref() { - check_assist( + fn extract_var_index_deref() { + check_assist_by_label( extract_variable, r#" //- minicore: index @@ -1261,12 +1767,13 @@ fn foo(s: &S) { let $0sub = &s.sub; sub[0]; }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_parameter_deep_nesting() { - check_assist( + fn extract_var_reference_parameter_deep_nesting() { + check_assist_by_label( extract_variable, r#" struct Z; @@ -1315,12 +1822,13 @@ fn foo(s: &S) { let $0z = &s.sub.field.field; z.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_regular_parameter() { - check_assist( + fn extract_var_regular_parameter() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1355,12 +1863,13 @@ fn foo(s: S) { let $0x = &s.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_mutable_reference_local() { - check_assist( + fn extract_var_mutable_reference_local() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1421,12 +1930,13 @@ fn foo() { let $0x = &local.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_reference_local() { - check_assist( + fn extract_var_reference_local() { + check_assist_by_label( extract_variable, r#" struct X; @@ -1487,12 +1997,13 @@ fn foo() { let $0x = &local.sub; x.do_thing(); }"#, + "Extract into variable", ); } #[test] - fn test_extract_var_for_mutable_borrow() { - check_assist( + fn extract_var_for_mutable_borrow() { + check_assist_by_label( extract_variable, r#" fn foo() { @@ -1503,12 +2014,25 @@ fn foo() { let mut $0var_name = 0; let v = &mut var_name; }"#, + "Extract into variable", + ); + } + + #[test] + fn dont_extract_const_for_mutable_borrow() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +fn foo() { + let v = &mut $00$0; +}"#, + "Extract into constant", ); } #[test] fn generates_no_ref_on_calls() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1529,12 +2053,13 @@ fn foo() { let mut $0bar = bar(); bar.do_work(); }"#, + "Extract into variable", ); } #[test] fn generates_no_ref_for_deref() { - check_assist( + check_assist_by_label( extract_variable, r#" struct S; @@ -1559,6 +2084,7 @@ fn foo() { s.do_work(); } "#, + "Extract into variable", ); } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 6469957fe16..4f7f03764f5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -363,6 +363,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base Extract into variable + Extract into constant Extract into function Replace if let with match "#]] @@ -392,6 +393,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base Extract into variable + Extract into constant Extract into function Replace if let with match "#]] @@ -406,6 +408,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Extract into variable + Extract into constant Extract into function "#]] .assert_eq(&expected); @@ -440,7 +443,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); - assert_eq!(2, assists.len()); + assert_eq!(3, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -459,6 +462,22 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: None, + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -486,7 +505,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(2, assists.len()); + assert_eq!(3, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -505,6 +524,22 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: None, + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -532,7 +567,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(2, assists.len()); + assert_eq!(3, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -594,6 +629,22 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: None, + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -613,7 +664,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into()); - assert_eq!(2, assists.len()); + assert_eq!(3, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -675,6 +726,69 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_variable_assist); + let extract_into_constant_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_constant", + RefactorExtract, + ), + label: "Extract into constant", + group: None, + target: 59..60, + source_change: Some( + SourceChange { + source_file_edits: { + FileId( + 0, + ): ( + TextEdit { + indels: [ + Indel { + insert: "const", + delete: 45..47, + }, + Indel { + insert: "VAR_NAME:", + delete: 48..60, + }, + Indel { + insert: "i32", + delete: 61..81, + }, + Indel { + insert: "=", + delete: 82..86, + }, + Indel { + insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", + delete: 87..108, + }, + ], + }, + Some( + SnippetEdit( + [ + ( + 0, + 51..51, + ), + ], + ), + ), + ), + }, + file_system_edits: [], + is_snippet: true, + }, + ), + command: Some( + Rename, + ), + } + "#]] + .assert_debug_eq(&extract_into_constant_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 69ea200db16..c1799b48ed4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -932,6 +932,24 @@ enum TheEnum { ) } +#[test] +fn doctest_extract_constant() { + check_doc_test( + "extract_constant", + r#####" +fn main() { + $0(1 + 2)$0 * 4; +} +"#####, + r#####" +fn main() { + const $0VAR_NAME: i32 = 1 + 2; + VAR_NAME * 4; +} +"#####, + ) +} + #[test] fn doctest_extract_expressions_from_format_string() { check_doc_test( -- cgit 1.4.1-3-g733a5 From 2d54e06b36509e1c7d06d77ec3975fdcc8453034 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:32:32 -0500 Subject: minor: Add `item_static` constructor to `SyntaxFactory` --- .../rust-analyzer/crates/syntax/src/ast/make.rs | 24 ++++++++++++- .../syntax/src/ast/syntax_factory/constructors.rs | 40 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 05c2a8354da..eb96ab6ef59 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -895,7 +895,29 @@ pub fn item_const( None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility} const {name}: {ty} = {expr};")) + ast_from_text(&format!("{visibility}const {name}: {ty} = {expr};")) +} + +pub fn item_static( + visibility: Option, + is_unsafe: bool, + is_mut: bool, + name: ast::Name, + ty: ast::Type, + expr: Option, +) -> ast::Static { + let visibility = match visibility { + None => String::new(), + Some(it) => format!("{it} "), + }; + let is_unsafe = if is_unsafe { "unsafe " } else { "" }; + let is_mut = if is_mut { "mut " } else { "" }; + let expr = match expr { + Some(it) => &format!(" = {it}"), + None => "", + }; + + ast_from_text(&format!("{visibility}{is_unsafe}static {is_mut}{name}: {ty}{expr};")) } pub fn unnamed_param(ty: ast::Type) -> ast::Param { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index d2ab30fb47d..280c5c25cb9 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -215,6 +215,46 @@ impl SyntaxFactory { ast } + pub fn item_static( + &self, + visibility: Option, + is_unsafe: bool, + is_mut: bool, + name: ast::Name, + ty: ast::Type, + expr: Option, + ) -> ast::Static { + let ast = make::item_static( + visibility.clone(), + is_unsafe, + is_mut, + name.clone(), + ty.clone(), + expr.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + + if let Some(expr) = expr { + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + pub fn turbofish_generic_arg_list( &self, args: impl IntoIterator + Clone, -- cgit 1.4.1-3-g733a5 From 2950325f37fda0629fba99e751104b6faeb73ddb Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 2 Nov 2024 23:51:03 +0200 Subject: Properly handle different defaults for severity of lints Previously all lints were assumed to be `#[warn]`, and we had a hand-coded list of `#[allow]` exceptions. Now the severity is autogenerated from rustdoc output. Also support lints that change status between editions, and the `warnings` lint group. --- src/tools/rust-analyzer/Cargo.lock | 6 + src/tools/rust-analyzer/Cargo.toml | 1 + src/tools/rust-analyzer/crates/edition/Cargo.toml | 13 + src/tools/rust-analyzer/crates/edition/src/lib.rs | 76 + .../src/completions/attribute/lint.rs | 2 +- .../crates/ide-db/src/generated/lints.rs | 7520 ++++++++++++++++---- src/tools/rust-analyzer/crates/ide-db/src/lib.rs | 8 + .../ide-diagnostics/src/handlers/missing_unsafe.rs | 37 +- .../crates/ide-diagnostics/src/lib.rs | 111 +- .../rust-analyzer/crates/ide/src/hover/tests.rs | 4 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 6 +- src/tools/rust-analyzer/crates/parser/Cargo.toml | 2 + .../rust-analyzer/crates/parser/src/edition.rs | 77 - src/tools/rust-analyzer/crates/parser/src/lib.rs | 4 +- src/tools/rust-analyzer/xtask/Cargo.toml | 1 + src/tools/rust-analyzer/xtask/src/codegen/lints.rs | 380 +- 16 files changed, 6720 insertions(+), 1528 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/edition/Cargo.toml create mode 100644 src/tools/rust-analyzer/crates/edition/src/lib.rs delete mode 100644 src/tools/rust-analyzer/crates/parser/src/edition.rs (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 8c1d82de1da..ab6580a97a7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -389,6 +389,10 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" +[[package]] +name = "edition" +version = "0.0.0" + [[package]] name = "either" version = "1.13.0" @@ -1266,6 +1270,7 @@ name = "parser" version = "0.0.0" dependencies = [ "drop_bomb", + "edition", "expect-test", "limit", "ra-ap-rustc_lexer", @@ -2662,6 +2667,7 @@ version = "0.1.0" dependencies = [ "anyhow", "directories", + "edition", "either", "flate2", "itertools", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index f7074f91354..8086569a781 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -83,6 +83,7 @@ toolchain = { path = "./crates/toolchain", version = "0.0.0" } tt = { path = "./crates/tt", version = "0.0.0" } vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } +edition = { path = "./crates/edition", version = "0.0.0" } ra-ap-rustc_lexer = { version = "0.85", default-features = false } ra-ap-rustc_parse_format = { version = "0.85", default-features = false } diff --git a/src/tools/rust-analyzer/crates/edition/Cargo.toml b/src/tools/rust-analyzer/crates/edition/Cargo.toml new file mode 100644 index 00000000000..926b1e1cd41 --- /dev/null +++ b/src/tools/rust-analyzer/crates/edition/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "edition" +version = "0.0.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true + +[dependencies] + +[lints] +workspace = true diff --git a/src/tools/rust-analyzer/crates/edition/src/lib.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs new file mode 100644 index 00000000000..c25d5b9557b --- /dev/null +++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs @@ -0,0 +1,76 @@ +//! The edition of the Rust language used in a crate. +// This should live in a separate crate because we use it in both actual code and codegen. +use std::fmt; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum Edition { + Edition2015, + Edition2018, + Edition2021, + Edition2024, +} + +impl Edition { + pub const DEFAULT: Edition = Edition::Edition2015; + pub const LATEST: Edition = Edition::Edition2024; + pub const CURRENT: Edition = Edition::Edition2021; + /// The current latest stable edition, note this is usually not the right choice in code. + pub const CURRENT_FIXME: Edition = Edition::Edition2021; + + pub fn at_least_2024(self) -> bool { + self >= Edition::Edition2024 + } + + pub fn at_least_2021(self) -> bool { + self >= Edition::Edition2021 + } + + pub fn at_least_2018(self) -> bool { + self >= Edition::Edition2018 + } + + pub fn iter() -> impl Iterator { + [Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024] + .iter() + .copied() + } +} + +#[derive(Debug)] +pub struct ParseEditionError { + invalid_input: String, +} + +impl std::error::Error for ParseEditionError {} +impl fmt::Display for ParseEditionError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "invalid edition: {:?}", self.invalid_input) + } +} + +impl std::str::FromStr for Edition { + type Err = ParseEditionError; + + fn from_str(s: &str) -> Result { + let res = match s { + "2015" => Edition::Edition2015, + "2018" => Edition::Edition2018, + "2021" => Edition::Edition2021, + "2024" => Edition::Edition2024, + _ => return Err(ParseEditionError { invalid_input: s.to_owned() }), + }; + Ok(res) + } +} + +impl fmt::Display for Edition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Edition::Edition2015 => "2015", + Edition::Edition2018 => "2018", + Edition::Edition2021 => "2021", + Edition::Edition2024 => "2024", + }) + } +} diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs index d5f9cd5fc76..04f40e805ad 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs @@ -11,7 +11,7 @@ pub(super) fn complete_lint( existing_lints: &[ast::Path], lints_completions: &[Lint], ) { - for &Lint { label, description } in lints_completions { + for &Lint { label, description, .. } in lints_completions { let (qual, name) = { // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead? let mut parts = label.split("::"); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index b97dfb3b8ef..14af22c3193 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -1,9 +1,16 @@ //! Generated by `cargo codegen lint-definitions`, do not edit by hand. +use span::Edition; + +use crate::Severity; + #[derive(Clone)] pub struct Lint { pub label: &'static str, pub description: &'static str, + pub default_severity: Severity, + pub warn_since: Option, + pub deny_since: Option, } pub struct LintGroup { @@ -12,803 +19,1632 @@ pub struct LintGroup { } pub const DEFAULT_LINTS: &[Lint] = &[ + Lint { + label: "abi_unsupported_vector_types", + description: r##"this function call or definition uses a vector type which is not enabled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, Lint { label: "absolute_paths_not_starting_with_crate", description: r##"fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_associated_items", + description: r##"ambiguous associated items"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "ambiguous_associated_items", description: r##"ambiguous associated items"## }, Lint { label: "ambiguous_glob_imports", description: r##"detects certain glob imports that require reporting an ambiguity error"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_glob_reexports", + description: r##"ambiguous glob re-exports"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_negative_literals", + description: r##"ambiguous negative literals operations"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "ambiguous_glob_reexports", description: r##"ambiguous glob re-exports"## }, Lint { label: "ambiguous_wide_pointer_comparisons", description: r##"detects ambiguous wide pointer comparisons"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "anonymous_parameters", + description: r##"detects anonymous parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "arithmetic_overflow", + description: r##"arithmetic operation overflows"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "anonymous_parameters", description: r##"detects anonymous parameters"## }, - Lint { label: "arithmetic_overflow", description: r##"arithmetic operation overflows"## }, Lint { label: "array_into_iter", description: r##"detects calling `into_iter` on arrays in Rust 2015 and 2018"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "asm_sub_register", description: r##"using only a subset of a register for inline asm inputs"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_in_trait", description: r##"use of `async fn` in definition of a publicly-reachable trait"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "bad_asm_style", + description: r##"incorrect use of inline assembly"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "bad_asm_style", description: r##"incorrect use of inline assembly"## }, Lint { label: "bare_trait_objects", description: r##"suggest using `dyn Trait` for trait objects"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "binary_asm_labels", + description: r##"labels in inline assembly containing only 0 or 1 digits"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "bindings_with_variant_name", description: r##"detects pattern bindings with the same name as one of the matched variants"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "boxed_slice_into_iter", description: r##"detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "break_with_label_and_loop", description: r##"`break` expression with label and unlabeled loop as value expression"##, - }, - Lint { - label: "byte_slice_in_packed_struct_with_derive", - description: r##"`[u8]` or `str` used in a packed struct with `derive`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "cenum_impl_drop_cast", description: r##"a C-like enum implementing Drop is cast"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "clashing_extern_declarations", description: r##"detects when an extern fn has been declared with the same name but different types"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "closure_returning_async_block", + description: r##"closure that returns `async {}` could be rewritten as an async closure"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coherence_leak_check", description: r##"distinct impls distinguished only by the leak-check code"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "conflicting_repr_hints", description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "confusable_idents", description: r##"detects visually confusable pairs between identifiers"##, - }, - Lint { - label: "const_eval_mutable_ptr_in_final_value", - description: r##"detects a mutable pointer that has leaked into final value of a const expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "const_evaluatable_unchecked", description: r##"detects a generic constant is used in a type without a emitting a warning"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "const_item_mutation", description: r##"detects attempts to mutate a `const` item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "dangling_pointers_from_temporaries", + description: r##"detects getting a pointer from a temporary"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "dead_code", + description: r##"detect unused, unexported items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "dead_code", description: r##"detect unused, unexported items"## }, Lint { label: "dependency_on_unit_never_type_fallback", description: r##"never type fallback affecting unsafe function calls"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "deprecated", description: r##"detects use of deprecated items"## }, Lint { - label: "deprecated_cfg_attr_crate_type_name", - description: r##"detects usage of `#![cfg_attr(..., crate_type/crate_name = "...")]`"##, + label: "deprecated", + description: r##"detects use of deprecated items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_in_future", description: r##"detects use of items that will be deprecated in a future version"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "deprecated_safe", + label: "deprecated_safe_2024", description: r##"detects unsafe functions being used as safe functions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_where_clause_location", description: r##"deprecated where clause location"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deref_into_dyn_supertrait", description: r##"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "deref_nullptr", description: r##"detects when an null pointer is dereferenced"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "drop_bounds", description: r##"bounds of the form `T: Drop` are most likely incorrect"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "dropping_copy_types", description: r##"calls to `std::mem::drop` with a value that implements Copy"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "dropping_references", description: r##"calls to `std::mem::drop` with a reference instead of an owned value"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "duplicate_macro_attributes", + description: r##"duplicated attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "duplicate_macro_attributes", description: r##"duplicated attribute"## }, Lint { label: "dyn_drop", description: r##"trait objects of the form `dyn Drop` are useless"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "edition_2024_expr_fragment_specifier", + description: r##"The `expr` fragment specifier will accept more expressions in the 2024 edition. To keep the existing behavior, use the `expr_2021` fragment specifier."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "elided_lifetimes_in_associated_constant", description: r##"elided lifetimes cannot be used in associated constants in impls"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "elided_lifetimes_in_paths", description: r##"hidden lifetime parameters in types are deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "elided_named_lifetimes", + description: r##"detects when an elided lifetime gets resolved to be `'static` or some named parameter"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ellipsis_inclusive_range_patterns", description: r##"`...` range patterns are deprecated"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "enum_intrinsics_non_enums", description: r##"detects calls to `core::mem::discriminant` and `core::mem::variant_count` with non-enum types"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "explicit_builtin_cfgs_in_flags", + description: r##"detects builtin cfgs set via the `--cfg`"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "explicit_outlives_requirements", description: r##"outlives requirements can be inferred"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exported_private_dependencies", description: r##"public interface leaks type from a private dependency"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_unwind_calls", description: r##"call to foreign functions or function pointers with FFI-unwind ABI"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "for_loops_over_fallibles", description: r##"for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "forbidden_lint_groups", + description: r##"applying forbid to lint-groups"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "forbidden_lint_groups", description: r##"applying forbid to lint-groups"## }, Lint { label: "forgetting_copy_types", description: r##"calls to `std::mem::forget` with a value that implements Copy"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "forgetting_references", description: r##"calls to `std::mem::forget` with a reference instead of an owned value"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "function_item_references", description: r##"suggest casting to a function pointer when attempting to take references to function items"##, - }, - Lint { - label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "fuzzy_provenance_casts", description: r##"a fuzzy integer to pointer cast is used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hidden_glob_reexports", description: r##"name introduced by a private item shadows a name introduced by a public glob re-export"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "if_let_rescope", + description: r##"`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and rewriting in `match` is an option to preserve the semantics up to Edition 2021"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ill_formed_attribute_input", description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_overcaptures", description: r##"`impl Trait` will capture more lifetimes than possibly intended in edition 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_redundant_captures", description: r##"redundant precise-capturing `use<...>` syntax on an `impl Trait`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "improper_ctypes", description: r##"proper use of libc types in foreign modules"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "improper_ctypes_definitions", description: r##"proper use of libc types in foreign item definitions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "incomplete_features", description: r##"incomplete features that may function improperly in some or all cases"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "incomplete_include", + description: r##"trailing content in included file"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "incomplete_include", description: r##"trailing content in included file"## }, Lint { label: "ineffective_unstable_trait_impl", description: r##"detects `#[unstable]` on stable trait implementations for stable types"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "inline_no_sanitize", description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "internal_features", description: r##"internal features are not supposed to be used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_atomic_ordering", description: r##"usage of invalid atomic ordering in atomic operations and memory fences"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_doc_attributes", description: r##"detects invalid `#[doc(...)]` attributes"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_from_utf8", description: r##"using a non UTF-8 literal in `std::str::from_utf8`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_from_utf8_unchecked", description: r##"using a non UTF-8 literal in `std::str::from_utf8_unchecked`"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_macro_export_arguments", description: r##""invalid_parameter" isn't a valid argument for `#[macro_export]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_nan_comparisons", description: r##"detects invalid floating point NaN comparisons"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_reference_casting", description: r##"casts of `&T` to `&mut T` without interior mutability"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_type_param_default", description: r##"type parameter default erroneously allowed in invalid location"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "invalid_value", description: r##"an invalid value is being created (such as a null reference)"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "irrefutable_let_patterns", description: r##"detects irrefutable patterns in `if let` and `while let` statements"##, - }, - Lint { - label: "keyword_idents", - description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "keyword_idents_2018", description: r##"detects edition keywords being used as an identifier"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "keyword_idents_2024", description: r##"detects edition keywords being used as an identifier"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "large_assignments", + description: r##"detects large moves or copies"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "large_assignments", description: r##"detects large moves or copies"## }, Lint { label: "late_bound_lifetime_arguments", description: r##"detects generic lifetime arguments in path segments with late bound lifetime parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "legacy_derive_helpers", description: r##"detects derive helper attributes that are used before they are introduced"##, - }, - Lint { - label: "let_underscore", - description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "let_underscore_drop", - description: r##"non-binding let on a type that implements `Drop`"##, + description: r##"non-binding let on a type that has a destructor"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "let_underscore_lock", description: r##"non-binding let on a synchronization lock"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "long_running_const_eval", description: r##"detects long const eval operations"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "lossy_provenance_casts", description: r##"a lossy pointer to integer cast is used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_expanded_macro_exports_accessed_by_absolute_paths", description: r##"macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "macro_use_extern_crate", description: r##"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_unit_fn", description: r##"`Iterator::map` call that discard the iterator's values"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "meta_variable_misuse", description: r##"possible meta-variable misuse at macro definition"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "missing_abi", + description: r##"No declared ABI for extern declaration"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "missing_abi", description: r##"No declared ABI for extern declaration"## }, Lint { label: "missing_copy_implementations", description: r##"detects potentially-forgotten implementations of `Copy`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_debug_implementations", description: r##"detects missing implementations of Debug"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_docs", description: r##"detects missing documentation for public members"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "missing_fragment_specifier", description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "missing_unsafe_on_extern", description: r##"detects missing unsafe keyword on extern declarations"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mixed_script_confusables", description: r##"detects Unicode scripts whose mixed script confusables codepoints are solely used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "multiple_supertrait_upcastable", - description: r##"detect when an object-safe trait has multiple supertraits"##, + description: r##"detect when a dyn-compatible trait has multiple supertraits"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "must_not_suspend", description: r##"use of a `#[must_not_suspend]` value across a yield point"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mutable_transmutes", description: r##"transmuting &T to &mut T is undefined behavior, even if the reference is unused"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "named_arguments_used_positionally", description: r##"named arguments in format used positionally"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "named_asm_labels", + description: r##"named labels in inline assembly"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "named_asm_labels", description: r##"named labels in inline assembly"## }, Lint { label: "never_type_fallback_flowing_into_unsafe", description: r##"never type fallback affecting unsafe function calls"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: Some(Edition::Edition2024), }, Lint { label: "no_mangle_const_items", description: r##"const items will not have their symbols exported"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "no_mangle_generic_items", + description: r##"generic items must be mangled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_ascii_idents", + description: r##"detects non-ASCII identifiers"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "no_mangle_generic_items", description: r##"generic items must be mangled"## }, - Lint { label: "non_ascii_idents", description: r##"detects non-ASCII identifiers"## }, Lint { label: "non_camel_case_types", description: r##"types, variants, traits and type parameters should have camel case names"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_contiguous_range_endpoints", description: r##"detects off-by-one errors with exclusive range patterns"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_exhaustive_omitted_patterns", description: r##"detect when patterns of types marked `non_exhaustive` are missed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_fmt_panics", description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_local_definitions", + description: r##"checks for non-local definitions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "non_local_definitions", description: r##"checks for non-local definitions"## }, Lint { label: "non_shorthand_field_patterns", description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_snake_case", description: r##"variables, methods, functions, lifetime parameters and modules should have snake case names"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "non_upper_case_globals", description: r##"static constants should have uppercase identifiers"##, - }, - Lint { - label: "nonstandard_style", - description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "noop_method_call", description: r##"detects the use of well-known noop methods"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "opaque_hidden_inferred_bound", description: r##"detects the use of nested `impl Trait` types in associated type bounds that are not general enough"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "order_dependent_trait_objects", description: r##"trait-object types were treated as different depending on marker-trait order"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "out_of_scope_macro_calls", description: r##"detects out of scope calls to `macro_rules` in key-value attributes"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "overflowing_literals", + description: r##"literal out of range for its type"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, - Lint { label: "overflowing_literals", description: r##"literal out of range for its type"## }, Lint { label: "overlapping_range_endpoints", description: r##"detects range patterns with overlapping endpoints"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "path_statements", + description: r##"path statements with no effect"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "path_statements", description: r##"path statements with no effect"## }, Lint { label: "patterns_in_fns_without_body", description: r##"patterns in functions without body were erroneously allowed"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "private_bounds", description: r##"private type in secondary interface of an item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "private_interfaces", description: r##"private type in primary interface of an item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_derive_resolution_fallback", description: r##"detects proc macro derives using inaccessible names from parent modules"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ptr_cast_add_auto_to_object", + description: r##"detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ptr_to_integer_transmute_in_consts", + description: r##"detects pointer to integer transmutes in const functions and associated constants"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "pub_use_of_private_extern_crate", description: r##"detect public re-exports of private extern crates"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "redundant_imports", + description: r##"imports that are redundant due to being imported already"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "redundant_lifetimes", description: r##"detects lifetime parameters that are redundant because they are equal to some other named lifetime"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "redundant_semicolons", description: r##"detects unnecessary trailing semicolons"##, - }, - Lint { - label: "refining_impl_trait", - description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "refining_impl_trait_internal", description: r##"impl trait in impl method signature does not match trait method signature"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "refining_impl_trait_reachable", description: r##"impl trait in impl method signature does not match trait method signature"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "renamed_and_removed_lints", description: r##"lints that have been renamed or removed"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "repr_transparent_external_private_fields", description: r##"transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields"##, - }, - Lint { - label: "rust_2018_compatibility", - description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, - }, - Lint { - label: "rust_2018_idioms", - description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, - }, - Lint { - label: "rust_2021_compatibility", - description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_incompatible_closure_captures", description: r##"detects closures affected by Rust 2021 changes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_incompatible_or_patterns", description: r##"detects usage of old versions of or-patterns"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_prefixes_incompatible_syntax", description: r##"identifiers that will be parsed as a prefix in Rust 2021"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2021_prelude_collisions", description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "rust_2024_compatibility", - description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##, + label: "rust_2024_guarded_string_incompatible_syntax", + description: r##"will be parsed as a guarded string in Rust 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_2024_incompatible_pat", description: r##"detects patterns whose meaning will change in Rust 2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2024_prelude_collisions", + description: r##"detects the usage of trait methods which are ambiguous with traits added to the prelude in future editions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "self_constructor_from_outer_item", description: r##"detect unsupported use of `Self` from outer item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "semicolon_in_expressions_from_macros", description: r##"trailing semicolon in macro body used as expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "single_use_lifetimes", description: r##"detects lifetime parameters that are only used once"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "soft_unstable", description: r##"a feature gate that doesn't break dependent crates"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "special_module_name", description: r##"module declarations for files with a special meaning"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "stable_features", description: r##"stable features found in `#[feature]` directive"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "static_mut_refs", description: r##"shared references or mutable references of mutable static is discouraged"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: Some(Edition::Edition2024), }, Lint { label: "suspicious_double_ref_op", description: r##"suspicious call of trait method on `&&T`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { - label: "temporary_cstring_as_ptr", - description: r##"detects getting the inner pointer of a temporary `CString`"##, + label: "tail_expr_drop_order", + description: r##"Detect and warn on significant change in drop order in tail expression location"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test_unstable_lint", description: r##"this unstable lint is only for testing"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "text_direction_codepoint_in_comment", description: r##"invisible directionality-changing codepoints in comment"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "text_direction_codepoint_in_literal", description: r##"detect special Unicode codepoints that affect the visual representation of text on screen, changing the direction in which text flows"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_bounds", description: r##"these bounds don't depend on an type parameters"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_casts", description: r##"detects trivial casts which could be removed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_numeric_casts", description: r##"detects trivial casts of numeric types which could be removed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_alias_bounds", description: r##"bounds in type aliases are not enforced"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "tyvar_behind_raw_pointer", description: r##"raw pointer to an inference variable"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "uncommon_codepoints", description: r##"detects uncommon Unicode codepoints in identifiers"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unconditional_panic", description: r##"operation will cause a panic at runtime"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "unconditional_recursion", description: r##"functions that cannot return without calling themselves"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "uncovered_param_in_projection", description: r##"impl contains type parameters that are not covered"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "undefined_naked_function_abi", description: r##"undefined naked function ABI"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "undropped_manually_drops", description: r##"calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "unexpected_cfgs", description: r##"detects unexpected names and values in `#[cfg]` conditions"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unfulfilled_lint_expectations", description: r##"unfulfilled lint expectation"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "ungated_async_fn_track_caller", description: r##"enabling track_caller on an async fn is a no-op unless the async_fn_track_caller feature is enabled"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "uninhabited_static", + description: r##"uninhabited static"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "uninhabited_static", description: r##"uninhabited static"## }, Lint { label: "unit_bindings", description: r##"binding is useless because it has the unit `()` type"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unknown_crate_types", description: r##"unknown crate type found in `#[crate_type]` directive"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unknown_lints", + description: r##"unrecognized lint attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unknown_lints", description: r##"unrecognized lint attribute"## }, Lint { label: "unknown_or_malformed_diagnostic_attributes", description: r##"unrecognized or malformed diagnostic attribute"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unnameable_test_items", description: r##"detects an item that cannot be named being marked as `#[test_case]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unnameable_types", description: r##"effective visibility of a type is larger than the area in which it can be named"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unqualified_local_imports", + description: r##"`use` of a local item without leading `self::`, `super::`, or `crate::`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unreachable_code", + description: r##"detects unreachable code paths"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unreachable_patterns", + description: r##"detects unreachable patterns"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unreachable_code", description: r##"detects unreachable code paths"## }, - Lint { label: "unreachable_patterns", description: r##"detects unreachable patterns"## }, Lint { label: "unreachable_pub", description: r##"`pub` items not reachable from crate root"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_attr_outside_unsafe", description: r##"detects unsafe attributes outside of unsafe"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_code", description: r##"usage of `unsafe` code and other potentially unsound constructs"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsafe_op_in_unsafe_fn", description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##, + default_severity: Severity::Allow, + warn_since: Some(Edition::Edition2024), + deny_since: None, + }, + Lint { + label: "unstable_features", + description: r##"enabling unstable features"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "unstable_features", description: r##"enabling unstable features"## }, Lint { label: "unstable_name_collisions", description: r##"detects name collision with an existing but unstable method"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unstable_syntax_pre_expansion", description: r##"unstable syntax can change at any point in the future, causing a hard error!"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { - label: "unsupported_calling_conventions", - description: r##"use of unsupported calling convention"##, - }, - Lint { - label: "unused", - description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + label: "unsupported_fn_ptr_calling_conventions", + description: r##"use of unsupported calling convention for function pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_allocation", description: r##"detects unnecessary allocations that can be eliminated"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_assignments", description: r##"detect assignments that will never be read"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_associated_type_bounds", description: r##"detects unused `Foo = Bar` bounds in `dyn Trait`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_attributes", description: r##"detects attributes that were not used by the compiler"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_braces", + description: r##"unnecessary braces around an expression"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_braces", description: r##"unnecessary braces around an expression"## }, Lint { label: "unused_comparisons", description: r##"comparisons made useless by limits of the types involved"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_crate_dependencies", description: r##"crate dependencies that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_doc_comments", description: r##"detects doc comments that aren't used by rustdoc"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_extern_crates", + description: r##"extern crates that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_extern_crates", description: r##"extern crates that are never used"## }, Lint { label: "unused_features", description: r##"unused features found in crate-level `#[feature]` directives"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_import_braces", description: r##"unnecessary braces around an imported item"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_imports", + description: r##"imports that are never used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_labels", + description: r##"detects labels that are never used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_imports", description: r##"imports that are never used"## }, - Lint { label: "unused_labels", description: r##"detects labels that are never used"## }, Lint { label: "unused_lifetimes", description: r##"detects lifetime parameters that are never used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_macro_rules", description: r##"detects macro rules that were not used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_macros", + description: r##"detects macros that were not used"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_macros", description: r##"detects macros that were not used"## }, Lint { label: "unused_must_use", description: r##"unused result of a type flagged as `#[must_use]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_mut", description: r##"detect mut variables which don't need to be mutable"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_parens", description: r##"`if`, `match`, `while` and `return` do not need parentheses"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "unused_qualifications", description: r##"detects unnecessarily qualified names"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unused_results", description: r##"unused result of an expression in a statement"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unused_unsafe", + description: r##"unnecessary use of an `unsafe` block"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "unused_unsafe", description: r##"unnecessary use of an `unsafe` block"## }, Lint { label: "unused_variables", description: r##"detect variables which are not used in any way"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "useless_deprecated", description: r##"detects deprecation attributes with no effect"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "useless_ptr_null_checks", description: r##"useless checking of non-null-typed pointer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "variant_size_differences", description: r##"detects enums with widely varying variant sizes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "warnings", description: r##"mass-change the level for lints which produce warnings"##, - }, - Lint { - label: "warnings", - description: r##"lint group for: all lints that are set to issue warnings"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "wasm_c_abi", description: r##"detects dependencies that are incompatible with the Wasm C ABI"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, }, Lint { label: "while_true", description: r##"suggest using `loop { }` instead of `while true { }`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "deprecated_safe", + description: r##"lint group for: deprecated-safe-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "future_incompatible", + description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "keyword_idents", + description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "let_underscore", + description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonstandard_style", + description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "refining_impl_trait", + description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2018_compatibility", + description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2018_idioms", + description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2021_compatibility", + description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rust_2024_compatibility", + description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "writes_through_immutable_pointer", - description: r##"shared references are immutable, and pointers derived from them must not be written to"##, + label: "unused", + description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "warnings", + description: r##"lint group for: all lints that are set to issue warnings"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ + LintGroup { + lint: Lint { + label: "deprecated_safe", + description: r##"lint group for: deprecated-safe-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + children: &["deprecated_safe_2024"], + }, LintGroup { lint: Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, ambiguous-associated-items, ambiguous-glob-imports, byte-slice-in-packed-struct-with-derive, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-eval-mutable-ptr-in-final-value, const-evaluatable-unchecked, dependency-on-unit-never-type-fallback, deprecated-cfg-attr-crate-type-name, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, never-type-fallback-flowing-into-unsafe, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, wasm-c-abi, writes-through-immutable-pointer"##, + description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "deref_into_dyn_supertrait", + "abi_unsupported_vector_types", "ambiguous_associated_items", "ambiguous_glob_imports", - "byte_slice_in_packed_struct_with_derive", "cenum_impl_drop_cast", "coherence_leak_check", "conflicting_repr_hints", - "const_eval_mutable_ptr_in_final_value", "const_evaluatable_unchecked", - "dependency_on_unit_never_type_fallback", - "deprecated_cfg_attr_crate_type_name", "elided_lifetimes_in_associated_constant", "forbidden_lint_groups", "ill_formed_attribute_input", @@ -817,11 +1653,11 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "legacy_derive_helpers", "macro_expanded_macro_exports_accessed_by_absolute_paths", "missing_fragment_specifier", - "never_type_fallback_flowing_into_unsafe", "order_dependent_trait_objects", "out_of_scope_macro_calls", "patterns_in_fns_without_body", "proc_macro_derive_resolution_fallback", + "ptr_cast_add_auto_to_object", "pub_use_of_private_extern_crate", "repr_transparent_external_private_fields", "self_constructor_from_outer_item", @@ -831,15 +1667,17 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "uninhabited_static", "unstable_name_collisions", "unstable_syntax_pre_expansion", - "unsupported_calling_conventions", + "unsupported_fn_ptr_calling_conventions", "wasm_c_abi", - "writes_through_immutable_pointer", ], }, LintGroup { lint: Lint { label: "keyword_idents", description: r##"lint group for: keyword-idents-2018, keyword-idents-2024"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["keyword_idents_2018", "keyword_idents_2024"], }, @@ -847,6 +1685,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "let_underscore", description: r##"lint group for: let-underscore-drop, let-underscore-lock"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["let_underscore_drop", "let_underscore_lock"], }, @@ -854,6 +1695,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "nonstandard_style", description: r##"lint group for: non-camel-case-types, non-snake-case, non-upper-case-globals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["non_camel_case_types", "non_snake_case", "non_upper_case_globals"], }, @@ -861,6 +1705,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "refining_impl_trait", description: r##"lint group for: refining-impl-trait-reachable, refining-impl-trait-internal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &["refining_impl_trait_reachable", "refining_impl_trait_internal"], }, @@ -868,6 +1715,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "rust_2018_compatibility", description: r##"lint group for: keyword-idents-2018, anonymous-parameters, absolute-paths-not-starting-with-crate, tyvar-behind-raw-pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "keyword_idents_2018", @@ -880,6 +1730,9 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "rust_2018_idioms", description: r##"lint group for: bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "bare_trait_objects", @@ -892,38 +1745,56 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "rust_2021_compatibility", - description: r##"lint group for: ellipsis-inclusive-range-patterns, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions, array-into-iter, non-fmt-panics"##, + description: r##"lint group for: ellipsis-inclusive-range-patterns, array-into-iter, non-fmt-panics, bare-trait-objects, rust-2021-incompatible-closure-captures, rust-2021-incompatible-or-patterns, rust-2021-prefixes-incompatible-syntax, rust-2021-prelude-collisions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "ellipsis_inclusive_range_patterns", + "array_into_iter", + "non_fmt_panics", "bare_trait_objects", "rust_2021_incompatible_closure_captures", "rust_2021_incompatible_or_patterns", "rust_2021_prefixes_incompatible_syntax", "rust_2021_prelude_collisions", - "array_into_iter", - "non_fmt_panics", ], }, LintGroup { lint: Lint { label: "rust_2024_compatibility", - description: r##"lint group for: keyword-idents-2024, deprecated-safe, missing-unsafe-on-extern, static-mut-refs, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn, boxed-slice-into-iter"##, + description: r##"lint group for: keyword-idents-2024, edition-2024-expr-fragment-specifier, boxed-slice-into-iter, impl-trait-overcaptures, if-let-rescope, static-mut-refs, dependency-on-unit-never-type-fallback, deprecated-safe-2024, missing-unsafe-on-extern, never-type-fallback-flowing-into-unsafe, rust-2024-guarded-string-incompatible-syntax, rust-2024-incompatible-pat, rust-2024-prelude-collisions, tail-expr-drop-order, unsafe-attr-outside-unsafe, unsafe-op-in-unsafe-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "keyword_idents_2024", - "deprecated_safe", - "missing_unsafe_on_extern", + "edition_2024_expr_fragment_specifier", + "boxed_slice_into_iter", + "impl_trait_overcaptures", + "if_let_rescope", "static_mut_refs", + "dependency_on_unit_never_type_fallback", + "deprecated_safe_2024", + "missing_unsafe_on_extern", + "never_type_fallback_flowing_into_unsafe", + "rust_2024_guarded_string_incompatible_syntax", + "rust_2024_incompatible_pat", + "rust_2024_prelude_collisions", + "tail_expr_drop_order", "unsafe_attr_outside_unsafe", "unsafe_op_in_unsafe_fn", - "boxed_slice_into_iter", ], }, LintGroup { lint: Lint { label: "unused", description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "unused_imports", @@ -950,64 +1821,99 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "map_unit_fn", ], }, - LintGroup { - lint: Lint { - label: "warnings", - description: r##"lint group for: all lints that are set to issue warnings"##, - }, - children: &[], - }, ]; pub const RUSTDOC_LINTS: &[Lint] = &[ Lint { - label: "rustdoc::all", - description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + label: "rustdoc::bare_urls", + description: r##"detects URLs that are not hyperlinks"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, - Lint { label: "rustdoc::bare_urls", description: r##"detects URLs that are not hyperlinks"## }, Lint { label: "rustdoc::broken_intra_doc_links", description: r##"failures in resolving intra-doc link targets"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_codeblock_attributes", description: r##"codeblock attribute looks a lot like a known one"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_html_tags", description: r##"detects invalid HTML tags in doc comments"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::invalid_rust_codeblocks", description: r##"codeblock could not be parsed as valid Rust or is empty"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::missing_crate_level_docs", description: r##"detects crates with no crate-level documentation"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::missing_doc_code_examples", description: r##"detects publicly-exported items without code samples in their documentation"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::private_doc_tests", description: r##"detects code samples in docs of private items not documented by rustdoc"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::private_intra_doc_links", description: r##"linking from a public item to a private one"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::redundant_explicit_links", description: r##"detects redundant explicit links in doc comments"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::unescaped_backticks", description: r##"detects unescaped backticks in doc comments"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc::unportable_markdown", description: r##"detects markdown that is interpreted differently in different parser"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rustdoc::all", + description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; @@ -1015,6 +1921,9 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { lint: Lint { label: "rustdoc::all", description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "rustdoc::broken_intra_doc_links", @@ -1032,6 +1941,20 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { }]; pub const FEATURES: &[Lint] = &[ + Lint { + label: "aarch64_unstable_target_feature", + description: r##"# `aarch64_unstable_target_feature` + +The tracking issue for this feature is: [#44839] + +[#44839]: https://github.com/rust-lang/rust/issues/44839 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, Lint { label: "aarch64_ver_target_feature", description: r##"# `aarch64_ver_target_feature` @@ -1042,6 +1965,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_avr_interrupt", @@ -1053,6 +1979,9 @@ The tracking issue for this feature is: [#69664] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_c_cmse_nonsecure_call", @@ -1145,6 +2074,9 @@ call_nonsecure_function: pop {r7, pc} ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_msp430_interrupt", @@ -1191,6 +2123,9 @@ Disassembly of section .text: c000: 00 13 reti ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_ptx", @@ -1255,6 +2190,9 @@ $ cat $(find -name '*.s') } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_riscv_interrupt", @@ -1266,6 +2204,9 @@ The tracking issue for this feature is: [#111889] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_unadjusted", @@ -1275,6 +2216,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_vectorcall", @@ -1298,6 +2242,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "abi_x86_interrupt", @@ -1309,6 +2256,23 @@ The tracking issue for this feature is: [#40180] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "abort_unwind", + description: r##"# `abort_unwind` + +The tracking issue for this feature is: [#130338] + +[#130338]: https://github.com/rust-lang/rust/issues/130338 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "acceptfilter", @@ -1320,6 +2284,9 @@ The tracking issue for this feature is: [#121891] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "addr_parse_ascii", @@ -1331,6 +2298,9 @@ The tracking issue for this feature is: [#101035] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "adt_const_params", @@ -1370,6 +2340,9 @@ fn is_foo_a_and_bar_true() -> bool { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_error_handler", @@ -1381,6 +2354,9 @@ The tracking issue for this feature is: [#51540] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_error_hook", @@ -1392,6 +2368,9 @@ The tracking issue for this feature is: [#51245] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_internals", @@ -1401,6 +2380,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "alloc_layout_extra", @@ -1412,6 +2394,9 @@ The tracking issue for this feature is: [#55724] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allocator_api", @@ -1431,6 +2416,9 @@ for which you want a custom allocator. TBD "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allocator_internals", @@ -1442,6 +2430,9 @@ compiler. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allow_internal_unsafe", @@ -1451,6 +2442,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "allow_internal_unstable", @@ -1460,6 +2454,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "anonymous_lifetime_in_impl_trait", @@ -1469,6 +2466,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "anonymous_pipe", + description: r##"# `anonymous_pipe` + +The tracking issue for this feature is: [#127154] + +[#127154]: https://github.com/rust-lang/rust/issues/127154 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "arbitrary_self_types", @@ -1480,6 +2494,23 @@ The tracking issue for this feature is: [#44874] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "arbitrary_self_types_pointers", + description: r##"# `arbitrary_self_types_pointers` + +The tracking issue for this feature is: [#44874] + +[#44874]: https://github.com/rust-lang/rust/issues/44874 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "arm_target_feature", @@ -1491,6 +2522,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_chunks", @@ -1502,6 +2536,9 @@ The tracking issue for this feature is: [#74985] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_into_iter_constructors", @@ -1513,6 +2550,9 @@ The tracking issue for this feature is: [#91583] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_ptr_get", @@ -1524,6 +2564,9 @@ The tracking issue for this feature is: [#119834] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_repeat", @@ -1535,6 +2578,9 @@ The tracking issue for this feature is: [#126695] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_try_from_fn", @@ -1546,6 +2592,9 @@ The tracking issue for this feature is: [#89379] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_try_map", @@ -1557,6 +2606,9 @@ The tracking issue for this feature is: [#79711] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "array_windows", @@ -1568,6 +2620,9 @@ The tracking issue for this feature is: [#75027] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "as_array_of_cells", @@ -1579,6 +2634,9 @@ The tracking issue for this feature is: [#88248] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ascii_char", @@ -1590,6 +2648,9 @@ The tracking issue for this feature is: [#110998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ascii_char_variants", @@ -1601,21 +2662,9 @@ The tracking issue for this feature is: [#110998] ------------------------ "##, - }, - Lint { - label: "asm_const", - description: r##"# `asm_const` - -The tracking issue for this feature is: [#93332] - -[#93332]: https://github.com/rust-lang/rust/issues/93332 - ------------------------- - -This feature adds a `const ` operand type to `asm!` and `global_asm!`. -- `` must be an integer constant expression. -- The value of the expression is formatted as a string and substituted directly into the asm template string. -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "asm_experimental_arch", @@ -1639,8 +2688,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect - MSP430 - M68k - CSKY -- s390x -- Arm64EC +- SPARC ## Register classes @@ -1652,9 +2700,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None\* | `r` | | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | -| PowerPC | `reg` | `r[0-31]` | `r` | -| PowerPC | `reg_nonzero` | `r[1-31]` | `b` | +| Hexagon | `preg` | `p[0-3]` | Only clobbers | +| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | +| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | +| PowerPC | `vreg` | `v[0-31]` | `v` | | PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | | PowerPC | `xer` | `xer` | Only clobbers | | wasm32 | `local` | None\* | `r` | @@ -1671,11 +2721,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg_addr` | `a[0-3]` | `a` | | CSKY | `reg` | `r[0-31]` | `r` | | CSKY | `freg` | `f[0-31]` | `f` | -| s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` | -| s390x | `freg` | `f[0-15]` | `f` | -| Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` | -| Arm64EC | `vreg` | `v[0-15]` | `w` | -| Arm64EC | `vreg_low16` | `v[0-15]` | `x` | +| SPARC | `reg` | `r[2-29]` | `r` | +| SPARC | `yreg` | `y` | Only clobbers | > **Notes**: > - NVPTX doesn't have a fixed register set, so named registers are not supported. @@ -1694,9 +2741,12 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` | | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | -| PowerPC | `reg` | None | `i8`, `i16`, `i32` | -| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` | +| Hexagon | `preg` | N/A | Only clobbers | +| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | +| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | +| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | +| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | | PowerPC | `cr` | N/A | Only clobbers | | PowerPC | `xer` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | @@ -1709,10 +2759,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg_data` | None | `i8`, `i16`, `i32` | | CSKY | `reg` | None | `i8`, `i16`, `i32` | | CSKY | `freg` | None | `f32`, | -| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` | -| s390x | `freg` | None | `f32`, `f64` | -| Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | -| Arm64EC | `vreg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`,
`i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| SPARC | `reg` | None | `i8`, `i16`, `i32`, `i64` (SPARC64 only) | +| SPARC | `yreg` | N/A | Only clobbers | ## Register aliases @@ -1721,6 +2769,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `r29` | `sp` | | Hexagon | `r30` | `fr` | | Hexagon | `r31` | `lr` | +| PowerPC | `r1` | `sp` | +| PowerPC | `r31` | `fp` | +| PowerPC | `r[0-31]` | `[0-31]` | +| PowerPC | `f[0-31]` | `fr[0-31]`| | BPF | `r[0-10]` | `w[0-10]` | | AVR | `XH` | `r27` | | AVR | `XL` | `r26` | @@ -1745,12 +2797,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | CSKY | `r29` | `rtb` | | CSKY | `r30` | `svbr` | | CSKY | `r31` | `tls` | -| Arm64EC | `x[0-30]` | `w[0-30]` | -| Arm64EC | `x29` | `fp` | -| Arm64EC | `x30` | `lr` | -| Arm64EC | `sp` | `wsp` | -| Arm64EC | `xzr` | `wzr` | -| Arm64EC | `v[0-15]` | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` | +| SPARC | `r[0-7]` | `g[0-7]` | +| SPARC | `r[8-15]` | `o[0-7]` | +| SPARC | `r[16-23]` | `l[0-7]` | +| SPARC | `r[24-31]` | `i[0-7]` | > **Notes**: > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed @@ -1760,15 +2810,19 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| All | `sp`, `r15` (s390x) | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r11` (s390x), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output. | -| All | `r19` (Hexagon), `x19` (Arm64EC) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | +| All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. | +| All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | +| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | +| PowerPC | `r2`, `r13` | These are system reserved registers. | +| PowerPC | `lr` | The link register cannot be used as an input or output. | +| PowerPC | `ctr` | The counter register cannot be used as an input or output. | +| PowerPC | `vrsave` | The vrsave register cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | @@ -1778,9 +2832,11 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | CSKY | `r15` | This is the link register. | | CSKY | `r[26-30]` | Reserved by its ABI. | | CSKY | `r31` | This is the TLS register. | -| Arm64EC | `xzr` | This is a constant zero register which can't be modified. | -| Arm64EC | `x18` | This is an OS-reserved register. | -| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. | +| SPARC | `r0`/`g0` | This is always zero and cannot be used as inputs or outputs. | +| SPARC | `r1`/`g1` | Used internally by LLVM. | +| SPARC | `r5`/`g5` | Reserved for system. (SPARC32 only) | +| SPARC | `r6`/`g6`, `r7`/`g7` | Reserved for system. | +| SPARC | `r31`/`i7` | Return address cannot be used as inputs or outputs. | ## Template modifiers @@ -1796,21 +2852,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | None | `0` | None | | PowerPC | `reg_nonzero` | None | `3` | None | | PowerPC | `freg` | None | `0` | None | -| s390x | `reg` | None | `%r0` | None | -| s390x | `reg_addr` | None | `%r1` | None | -| s390x | `freg` | None | `%f0` | None | +| PowerPC | `vreg` | None | `0` | None | +| SPARC | `reg` | None | `%o0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | -| Arm64EC | `reg` | None | `x0` | `x` | -| Arm64EC | `reg` | `w` | `w0` | `w` | -| Arm64EC | `reg` | `x` | `x0` | `x` | -| Arm64EC | `vreg` | None | `v0` | None | -| Arm64EC | `vreg` | `v` | `v0` | None | -| Arm64EC | `vreg` | `b` | `b0` | `b` | -| Arm64EC | `vreg` | `h` | `h0` | `h` | -| Arm64EC | `vreg` | `s` | `s0` | `s` | -| Arm64EC | `vreg` | `d` | `d0` | `d` | -| Arm64EC | `vreg` | `q` | `q0` | `q` | # Flags covered by `preserves_flags` @@ -1821,39 +2866,89 @@ These flags registers must be restored upon exiting the asm block if the `preser - The status register `r2`. - M68k - The condition code register `ccr`. -- s390x - - The condition code register `cc`. -- Arm64EC - - Condition flags (`NZCV` register). - - Floating-point status (`FPSR` register). +- SPARC + - Integer condition codes (`icc` and `xcc`) + - Floating-point condition codes (`fcc[0-3]`) "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "asm_goto", - description: r##"# `asm_goto` + label: "asm_experimental_reg", + description: r##"# `asm_experimental_arch` -The tracking issue for this feature is: [#119364] +The tracking issue for this feature is: [#133416] -[#119364]: https://github.com/rust-lang/rust/issues/119364 +[#133416]: https://github.com/rust-lang/rust/issues/133416 ------------------------ -This feature adds a `label ` operand type to `asm!`. +This tracks support for additional registers in architectures where inline assembly is already stable. -Example: -```rust,ignore (partial-example, x86-only) +## Register classes -unsafe { - asm!( - "jmp {}", - label { - println!("Jumped from asm!"); - } - ); +| Architecture | Register class | Registers | LLVM constraint code | +| ------------ | -------------- | --------- | -------------------- | +| s390x | `vreg` | `v[0-31]` | `v` | + +> **Notes**: +> - s390x `vreg` is clobber-only in stable. + +## Register class supported types + +| Architecture | Register class | Target feature | Allowed types | +| ------------ | -------------- | -------------- | ------------- | +| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | + +## Register aliases + +| Architecture | Base register | Aliases | +| ------------ | ------------- | ------- | + +## Unsupported registers + +| Architecture | Unsupported register | Reason | +| ------------ | -------------------- | ------ | + +## Template modifiers + +| Architecture | Register class | Modifier | Example output | LLVM modifier | +| ------------ | -------------- | -------- | -------------- | ------------- | +| s390x | `vreg` | None | `%v0` | None | +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "asm_goto", + description: r##"# `asm_goto` + +The tracking issue for this feature is: [#119364] + +[#119364]: https://github.com/rust-lang/rust/issues/119364 + +------------------------ + +This feature adds a `label ` operand type to `asm!`. + +Example: +```rust,ignore (partial-example, x86-only) + +unsafe { + asm!( + "jmp {}", + label { + println!("Jumped from asm!"); + } + ); } ``` -The block must have unit type or diverge. +The block must have unit type or diverge. The block starts a new safety context, +so despite outer `unsafe`, you need extra unsafe to perform unsafe operations +within `label `. When `label ` is used together with `noreturn` option, it means that the assembly will not fallthrough. It's allowed to jump to a label within the @@ -1861,6 +2956,23 @@ assembly. In this case, the entire `asm!` expression will have an unit type as opposed to diverging, if not all label blocks diverge. The `asm!` expression still diverges if `noreturn` option is used and all label blocks diverge. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "asm_goto_with_outputs", + description: r##"# `asm_goto_with_outputs` + +The tracking issue for this feature is: [#119364] + +[#119364]: https://github.com/rust-lang/rust/issues/119364 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "asm_unwind", @@ -1874,6 +2986,9 @@ The tracking issue for this feature is: [#93334] This feature adds a `may_unwind` option to `asm!` which allows an `asm` block to unwind stack and be part of the stack unwinding process. This option is only supported by the LLVM backend right now. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "assert_matches", @@ -1885,6 +3000,9 @@ The tracking issue for this feature is: [#82775] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "associated_const_equality", @@ -1896,6 +3014,9 @@ The tracking issue for this feature is: [#92827] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "associated_type_defaults", @@ -1907,6 +3028,9 @@ The tracking issue for this feature is: [#29661] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_closure", @@ -1918,6 +3042,9 @@ The tracking issue for this feature is: [#62290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_drop", @@ -1929,6 +3056,9 @@ The tracking issue for this feature is: [#126482] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_track_caller", @@ -1940,6 +3070,9 @@ The tracking issue for this feature is: [#110011] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_fn_traits", @@ -1957,6 +3090,9 @@ for creating custom closure-like types that return futures. The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_for_loop", @@ -1968,6 +3104,9 @@ The tracking issue for this feature is: [#118898] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_gen_internals", @@ -1977,6 +3116,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_iter_from_iter", @@ -1988,6 +3130,9 @@ The tracking issue for this feature is: [#81798] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "async_iterator", @@ -1999,6 +3144,23 @@ The tracking issue for this feature is: [#79024] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "async_trait_bounds", + description: r##"# `async_trait_bounds` + +The tracking issue for this feature is: [#62290] + +[#62290]: https://github.com/rust-lang/rust/issues/62290 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "atomic_from_mut", @@ -2010,6 +3172,9 @@ The tracking issue for this feature is: [#76314] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "auto_traits", @@ -2120,6 +3285,23 @@ Auto traits cannot have any trait items, such as methods or associated types. Th Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "autodiff", + description: r##"# `autodiff` + +The tracking issue for this feature is: [#124509] + +[#124509]: https://github.com/rust-lang/rust/issues/124509 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "avx512_target_feature", @@ -2131,6 +3313,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "backtrace_frames", @@ -2142,6 +3327,9 @@ The tracking issue for this feature is: [#79676] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bigint_helper_methods", @@ -2153,6 +3341,9 @@ The tracking issue for this feature is: [#85532] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "binary_heap_drain_sorted", @@ -2164,6 +3355,9 @@ The tracking issue for this feature is: [#59278] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "binary_heap_into_iter_sorted", @@ -2175,6 +3369,9 @@ The tracking issue for this feature is: [#59278] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bound_as_ref", @@ -2186,6 +3383,23 @@ The tracking issue for this feature is: [#80996] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_as_ptr", + description: r##"# `box_as_ptr` + +The tracking issue for this feature is: [#129090] + +[#129090]: https://github.com/rust-lang/rust/issues/129090 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_into_boxed_slice", @@ -2197,6 +3411,9 @@ The tracking issue for this feature is: [#71582] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_into_inner", @@ -2208,6 +3425,9 @@ The tracking issue for this feature is: [#80437] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "box_patterns", @@ -2242,6 +3462,37 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_uninit_write", + description: r##"# `box_uninit_write` + +The tracking issue for this feature is: [#129397] + +[#129397]: https://github.com/rust-lang/rust/issues/129397 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "box_vec_non_null", + description: r##"# `box_vec_non_null` + +The tracking issue for this feature is: [#130364] + +[#130364]: https://github.com/rust-lang/rust/issues/130364 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "bpf_target_feature", @@ -2253,6 +3504,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "breakpoint", + description: r##"# `breakpoint` + +The tracking issue for this feature is: [#133724] + +[#133724]: https://github.com/rust-lang/rust/issues/133724 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btree_cursors", @@ -2264,6 +3532,23 @@ The tracking issue for this feature is: [#107540] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "btree_entry_insert", + description: r##"# `btree_entry_insert` + +The tracking issue for this feature is: [#65225] + +[#65225]: https://github.com/rust-lang/rust/issues/65225 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btree_extract_if", @@ -2275,6 +3560,23 @@ The tracking issue for this feature is: [#70530] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "btree_set_entry", + description: r##"# `btree_set_entry` + +The tracking issue for this feature is: [#133549] + +[#133549]: https://github.com/rust-lang/rust/issues/133549 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "btreemap_alloc", @@ -2286,6 +3588,9 @@ The tracking issue for this feature is: [#32838] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "buf_read_has_data_left", @@ -2297,28 +3602,23 @@ The tracking issue for this feature is: [#86423] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "bufread_skip_until", - description: r##"# `bufread_skip_until` - -The tracking issue for this feature is: [#111735] - -[#111735]: https://github.com/rust-lang/rust/issues/111735 - ------------------------- -"##, - }, - Lint { - label: "build_hasher_default_const_new", - description: r##"# `build_hasher_default_const_new` + label: "bufreader_peek", + description: r##"# `bufreader_peek` -The tracking issue for this feature is: [#123197] +The tracking issue for this feature is: [#128405] -[#123197]: https://github.com/rust-lang/rust/issues/123197 +[#128405]: https://github.com/rust-lang/rust/issues/128405 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "builtin_syntax", @@ -2330,6 +3630,9 @@ The tracking issue for this feature is: [#110680] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_size_t", @@ -2341,6 +3644,9 @@ The tracking issue for this feature is: [#88345] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_str_module", @@ -2352,6 +3658,9 @@ The tracking issue for this feature is: [#112134] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_variadic", @@ -2380,6 +3689,9 @@ pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_variadic", @@ -2410,6 +3722,9 @@ pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "c_void_variant", @@ -2419,6 +3734,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "can_vector", @@ -2430,6 +3748,9 @@ The tracking issue for this feature is: [#69941] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cell_leak", @@ -2441,6 +3762,9 @@ The tracking issue for this feature is: [#69099] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cell_update", @@ -2452,6 +3776,9 @@ The tracking issue for this feature is: [#50186] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_accessible", @@ -2463,6 +3790,38 @@ The tracking issue for this feature is: [#64797] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cfg_boolean_literals", + description: r##"# `cfg_boolean_literals` + +The tracking issue for this feature is: [#131204] + +[#131204]: https://github.com/rust-lang/rust/issues/131204 + +------------------------ + +The `cfg_boolean_literals` feature makes it possible to use the `true`/`false` +literal as cfg predicate. They always evaluate to true/false respectively. + +## Examples + +```rust +#![feature(cfg_boolean_literals)] + +#[cfg(true)] +const A: i32 = 5; + +#[cfg(all(false))] +const A: i32 = 58 * 89; +``` +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_eval", @@ -2474,6 +3833,9 @@ The tracking issue for this feature is: [#82679] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_match", @@ -2485,6 +3847,9 @@ The tracking issue for this feature is: [#115585] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_overflow_checks", @@ -2496,6 +3861,9 @@ The tracking issue for this feature is: [#111466] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_relocation_model", @@ -2507,6 +3875,9 @@ The tracking issue for this feature is: [#114929] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_sanitize", @@ -2545,6 +3916,9 @@ fn b() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_sanitizer_cfi", @@ -2556,6 +3930,9 @@ The tracking issue for this feature is: [#89653] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_compact", @@ -2567,6 +3944,9 @@ The tracking issue for this feature is: [#96901] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_has_atomic", @@ -2578,6 +3958,9 @@ The tracking issue for this feature is: [#94039] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_has_atomic_equal_alignment", @@ -2589,6 +3972,9 @@ The tracking issue for this feature is: [#93822] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_target_thread_local", @@ -2600,6 +3986,9 @@ The tracking issue for this feature is: [#29594] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_ub_checks", @@ -2611,6 +4000,9 @@ The tracking issue for this feature is: [#123499] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfg_version", @@ -2650,6 +4042,9 @@ fn b() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cfi_encoding", @@ -2679,17 +4074,9 @@ extern { } ``` "##, - }, - Lint { - label: "char_indices_offset", - description: r##"# `char_indices_offset` - -The tracking issue for this feature is: [#83871] - -[#83871]: https://github.com/rust-lang/rust/issues/83871 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "char_internals", @@ -2699,17 +4086,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "char_min", - description: r##"# `char_min` - -The tracking issue for this feature is: [#114298] - -[#114298]: https://github.com/rust-lang/rust/issues/114298 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clone_to_uninit", @@ -2721,6 +4100,9 @@ The tracking issue for this feature is: [#126799] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "closure_lifetime_binder", @@ -2732,6 +4114,9 @@ The tracking issue for this feature is: [#97362] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "closure_track_caller", @@ -2748,6 +4133,9 @@ Calls made to the closure or coroutine will have caller information available through `std::panic::Location::caller()`, just like using `#[track_caller]` on a function. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cmp_minmax", @@ -2759,6 +4147,9 @@ The tracking issue for this feature is: [#115939] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cmse_nonsecure_entry", @@ -2779,10 +4170,10 @@ LLVM, the Rust compiler and the linker are providing TrustZone-M feature. One of the things provided, with this unstable feature, is the -`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an +`C-cmse-nonsecure-entry` ABI. This ABI marks a Secure function as an entry function (see [section 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). -With this attribute, the compiler will do the following: +With this ABI, the compiler will do the following: * add a special symbol on the function which is the `__acle_se_` prefix and the standard function name * constrain the number of parameters to avoid using the Non-Secure stack @@ -2802,11 +4193,11 @@ gateway veneer. ``` rust,ignore +#![no_std] #![feature(cmse_nonsecure_entry)] #[no_mangle] -#[cmse_nonsecure_entry] -pub extern "C" fn entry_function(input: u32) -> u32 { +pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { input + 6 } ``` @@ -2844,6 +4235,9 @@ $ arm-none-eabi-objdump -D function.o 40: defe udf #254 ; 0xfe ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coerce_unsized", @@ -2855,6 +4249,9 @@ The tracking issue for this feature is: [#18598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "compiler_builtins", @@ -2864,6 +4261,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "concat_bytes", @@ -2875,6 +4275,9 @@ The tracking issue for this feature is: [#87555] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "concat_idents", @@ -2901,39 +4304,9 @@ fn main() { } ``` "##, - }, - Lint { - label: "const_align_of_val", - description: r##"# `const_align_of_val` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_align_of_val_raw", - description: r##"# `const_align_of_val_raw` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_align_offset", - description: r##"# `const_align_offset` - -The tracking issue for this feature is: [#90962] - -[#90962]: https://github.com/rust-lang/rust/issues/90962 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_alloc_error", @@ -2945,6 +4318,9 @@ The tracking issue for this feature is: [#92523] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_alloc_layout", @@ -2956,39 +4332,37 @@ The tracking issue for this feature is: [#67521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_arguments_as_str", - description: r##"# `const_arguments_as_str` - -The tracking issue for this feature is: [#103900] - -[#103900]: https://github.com/rust-lang/rust/issues/103900 - ------------------------- -"##, - }, - Lint { - label: "const_array_from_ref", - description: r##"# `const_array_from_ref` + label: "const_array_as_mut_slice", + description: r##"# `const_array_as_mut_slice` -The tracking issue for this feature is: [#90206] +The tracking issue for this feature is: [#133333] -[#90206]: https://github.com/rust-lang/rust/issues/90206 +[#133333]: https://github.com/rust-lang/rust/issues/133333 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_array_into_iter_constructors", - description: r##"# `const_array_into_iter_constructors` + label: "const_array_each_ref", + description: r##"# `const_array_each_ref` -The tracking issue for this feature is: [#91583] +The tracking issue for this feature is: [#133289] -[#91583]: https://github.com/rust-lang/rust/issues/91583 +[#133289]: https://github.com/rust-lang/rust/issues/133289 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_async_blocks", @@ -3000,39 +4374,9 @@ The tracking issue for this feature is: [#85368] ------------------------ "##, - }, - Lint { - label: "const_atomic_from_ptr", - description: r##"# `const_atomic_from_ptr` - -The tracking issue for this feature is: [#108652] - -[#108652]: https://github.com/rust-lang/rust/issues/108652 - ------------------------- -"##, - }, - Lint { - label: "const_bigint_helper_methods", - description: r##"# `const_bigint_helper_methods` - -The tracking issue for this feature is: [#85532] - -[#85532]: https://github.com/rust-lang/rust/issues/85532 - ------------------------- -"##, - }, - Lint { - label: "const_binary_heap_new_in", - description: r##"# `const_binary_heap_new_in` - -The tracking issue for this feature is: [#112353] - -[#112353]: https://github.com/rust-lang/rust/issues/112353 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_black_box", @@ -3042,6 +4386,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_box", @@ -3053,6 +4400,9 @@ The tracking issue for this feature is: [#92521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_btree_len", @@ -3062,17 +4412,37 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_cell", + description: r##"# `const_cell` + +The tracking issue for this feature is: [#131283] + +[#131283]: https://github.com/rust-lang/rust/issues/131283 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_cell_into_inner", - description: r##"# `const_cell_into_inner` + label: "const_char_classify", + description: r##"# `const_char_classify` -The tracking issue for this feature is: [#78729] +The tracking issue for this feature is: [#132241] -[#78729]: https://github.com/rust-lang/rust/issues/78729 +[#132241]: https://github.com/rust-lang/rust/issues/132241 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_closures", @@ -3084,28 +4454,51 @@ The tracking issue for this feature is: [#106003] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_collections_with_hasher", - description: r##"# `const_collections_with_hasher` + label: "const_copy_from_slice", + description: r##"# `const_copy_from_slice` -The tracking issue for this feature is: [#102575] +The tracking issue for this feature is: [#131415] -[#102575]: https://github.com/rust-lang/rust/issues/102575 +[#131415]: https://github.com/rust-lang/rust/issues/131415 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_cow_is_borrowed", - description: r##"# `const_cow_is_borrowed` + label: "const_destruct", + description: r##"# `const_destruct` -The tracking issue for this feature is: [#65143] +The tracking issue for this feature is: [#133214] -[#65143]: https://github.com/rust-lang/rust/issues/65143 +[#133214]: https://github.com/rust-lang/rust/issues/133214 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_eq_ignore_ascii_case", + description: r##"# `const_eq_ignore_ascii_case` + +The tracking issue for this feature is: [#131719] + +[#131719]: https://github.com/rust-lang/rust/issues/131719 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_eval_select", @@ -3117,527 +4510,133 @@ The tracking issue for this feature is: [#124625] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_exact_div", - description: r##"# `const_exact_div` + label: "const_for", + description: r##"# `const_for` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#87575] + +[#87575]: https://github.com/rust-lang/rust/issues/87575 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_extern_fn", - description: r##"# `const_extern_fn` - -The tracking issue for this feature is: [#64926] + label: "const_format_args", + description: r##"# `const_format_args` -[#64926]: https://github.com/rust-lang/rust/issues/64926 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_float_bits_conv", - description: r##"# `const_float_bits_conv` + label: "const_heap", + description: r##"# `const_heap` -The tracking issue for this feature is: [#72447] +The tracking issue for this feature is: [#79597] -[#72447]: https://github.com/rust-lang/rust/issues/72447 +[#79597]: https://github.com/rust-lang/rust/issues/79597 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_float_classify", - description: r##"# `const_float_classify` + label: "const_is_char_boundary", + description: r##"# `const_is_char_boundary` -The tracking issue for this feature is: [#72505] +The tracking issue for this feature is: [#131516] -[#72505]: https://github.com/rust-lang/rust/issues/72505 +[#131516]: https://github.com/rust-lang/rust/issues/131516 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_fmt_arguments_new", - description: r##"# `const_fmt_arguments_new` + label: "const_mut_cursor", + description: r##"# `const_mut_cursor` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#130801] + +[#130801]: https://github.com/rust-lang/rust/issues/130801 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_fn_floating_point_arithmetic", - description: r##"# `const_fn_floating_point_arithmetic` + label: "const_precise_live_drops", + description: r##"# `const_precise_live_drops` -The tracking issue for this feature is: [#57241] +The tracking issue for this feature is: [#73255] -[#57241]: https://github.com/rust-lang/rust/issues/57241 +[#73255]: https://github.com/rust-lang/rust/issues/73255 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_for", - description: r##"# `const_for` + label: "const_ptr_sub_ptr", + description: r##"# `const_ptr_sub_ptr` -The tracking issue for this feature is: [#87575] +The tracking issue for this feature is: [#95892] -[#87575]: https://github.com/rust-lang/rust/issues/87575 +[#95892]: https://github.com/rust-lang/rust/issues/95892 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_format_args", - description: r##"# `const_format_args` + label: "const_range_bounds", + description: r##"# `const_range_bounds` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#108082] + +[#108082]: https://github.com/rust-lang/rust/issues/108082 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_hash", - description: r##"# `const_hash` + label: "const_raw_ptr_comparison", + description: r##"# `const_raw_ptr_comparison` -The tracking issue for this feature is: [#104061] +The tracking issue for this feature is: [#53020] -[#104061]: https://github.com/rust-lang/rust/issues/104061 - ------------------------- -"##, - }, - Lint { - label: "const_heap", - description: r##"# `const_heap` - -The tracking issue for this feature is: [#79597] - -[#79597]: https://github.com/rust-lang/rust/issues/79597 - ------------------------- -"##, - }, - Lint { - label: "const_index_range_slice_index", - description: r##"# `const_index_range_slice_index` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_int_from_str", - description: r##"# `const_int_from_str` - -The tracking issue for this feature is: [#59133] - -[#59133]: https://github.com/rust-lang/rust/issues/59133 - ------------------------- -"##, - }, - Lint { - label: "const_intoiterator_identity", - description: r##"# `const_intoiterator_identity` - -The tracking issue for this feature is: [#90603] - -[#90603]: https://github.com/rust-lang/rust/issues/90603 - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_compare_bytes", - description: r##"# `const_intrinsic_compare_bytes` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_copy", - description: r##"# `const_intrinsic_copy` - -The tracking issue for this feature is: [#80697] - -[#80697]: https://github.com/rust-lang/rust/issues/80697 - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_forget", - description: r##"# `const_intrinsic_forget` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_intrinsic_raw_eq", - description: r##"# `const_intrinsic_raw_eq` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_ip", - description: r##"# `const_ip` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_ipv4", - description: r##"# `const_ipv4` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_ipv6", - description: r##"# `const_ipv6` - -The tracking issue for this feature is: [#76205] - -[#76205]: https://github.com/rust-lang/rust/issues/76205 - ------------------------- -"##, - }, - Lint { - label: "const_likely", - description: r##"# `const_likely` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_array_assume_init", - description: r##"# `const_maybe_uninit_array_assume_init` - -The tracking issue for this feature is: [#96097] - -[#96097]: https://github.com/rust-lang/rust/issues/96097 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_as_mut_ptr", - description: r##"# `const_maybe_uninit_as_mut_ptr` - -The tracking issue for this feature is: [#75251] - -[#75251]: https://github.com/rust-lang/rust/issues/75251 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_assume_init", - description: r##"# `const_maybe_uninit_assume_init` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_uninit_array", - description: r##"# `const_maybe_uninit_uninit_array` - -The tracking issue for this feature is: [#96097] - -[#96097]: https://github.com/rust-lang/rust/issues/96097 - ------------------------- -"##, - }, - Lint { - label: "const_maybe_uninit_write", - description: r##"# `const_maybe_uninit_write` - -The tracking issue for this feature is: [#63567] - -[#63567]: https://github.com/rust-lang/rust/issues/63567 - ------------------------- -"##, - }, - Lint { - label: "const_mut_refs", - description: r##"# `const_mut_refs` - -The tracking issue for this feature is: [#57349] - -[#57349]: https://github.com/rust-lang/rust/issues/57349 - ------------------------- -"##, - }, - Lint { - label: "const_nonnull_new", - description: r##"# `const_nonnull_new` - -The tracking issue for this feature is: [#93235] - -[#93235]: https://github.com/rust-lang/rust/issues/93235 - ------------------------- -"##, - }, - Lint { - label: "const_num_midpoint", - description: r##"# `const_num_midpoint` - -The tracking issue for this feature is: [#110840] - -[#110840]: https://github.com/rust-lang/rust/issues/110840 - ------------------------- -"##, - }, - Lint { - label: "const_option", - description: r##"# `const_option` - -The tracking issue for this feature is: [#67441] - -[#67441]: https://github.com/rust-lang/rust/issues/67441 - ------------------------- -"##, - }, - Lint { - label: "const_option_ext", - description: r##"# `const_option_ext` - -The tracking issue for this feature is: [#91930] - -[#91930]: https://github.com/rust-lang/rust/issues/91930 - ------------------------- -"##, - }, - Lint { - label: "const_pin", - description: r##"# `const_pin` - -The tracking issue for this feature is: [#76654] - -[#76654]: https://github.com/rust-lang/rust/issues/76654 - ------------------------- -"##, - }, - Lint { - label: "const_pointer_is_aligned", - description: r##"# `const_pointer_is_aligned` - -The tracking issue for this feature is: [#104203] - -[#104203]: https://github.com/rust-lang/rust/issues/104203 - ------------------------- -"##, - }, - Lint { - label: "const_precise_live_drops", - description: r##"# `const_precise_live_drops` - -The tracking issue for this feature is: [#73255] - -[#73255]: https://github.com/rust-lang/rust/issues/73255 - ------------------------- -"##, - }, - Lint { - label: "const_pref_align_of", - description: r##"# `const_pref_align_of` - -The tracking issue for this feature is: [#91971] - -[#91971]: https://github.com/rust-lang/rust/issues/91971 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_as_ref", - description: r##"# `const_ptr_as_ref` - -The tracking issue for this feature is: [#91822] - -[#91822]: https://github.com/rust-lang/rust/issues/91822 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_is_null", - description: r##"# `const_ptr_is_null` - -The tracking issue for this feature is: [#74939] - -[#74939]: https://github.com/rust-lang/rust/issues/74939 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_sub_ptr", - description: r##"# `const_ptr_sub_ptr` - -The tracking issue for this feature is: [#95892] - -[#95892]: https://github.com/rust-lang/rust/issues/95892 - ------------------------- -"##, - }, - Lint { - label: "const_ptr_write", - description: r##"# `const_ptr_write` - -The tracking issue for this feature is: [#86302] - -[#86302]: https://github.com/rust-lang/rust/issues/86302 - ------------------------- -"##, - }, - Lint { - label: "const_range_bounds", - description: r##"# `const_range_bounds` - -The tracking issue for this feature is: [#108082] - -[#108082]: https://github.com/rust-lang/rust/issues/108082 - ------------------------- -"##, - }, - Lint { - label: "const_raw_ptr_comparison", - description: r##"# `const_raw_ptr_comparison` - -The tracking issue for this feature is: [#53020] - -[#53020]: https://github.com/rust-lang/rust/issues/53020 - ------------------------- -"##, - }, - Lint { - label: "const_refs_to_cell", - description: r##"# `const_refs_to_cell` - -The tracking issue for this feature is: [#80384] - -[#80384]: https://github.com/rust-lang/rust/issues/80384 - ------------------------- -"##, - }, - Lint { - label: "const_refs_to_static", - description: r##"# `const_refs_to_static` - -The tracking issue for this feature is: [#119618] - -[#119618]: https://github.com/rust-lang/rust/issues/119618 - ------------------------- -"##, - }, - Lint { - label: "const_replace", - description: r##"# `const_replace` - -The tracking issue for this feature is: [#83164] - -[#83164]: https://github.com/rust-lang/rust/issues/83164 - ------------------------- -"##, - }, - Lint { - label: "const_result", - description: r##"# `const_result` - -The tracking issue for this feature is: [#82814] - -[#82814]: https://github.com/rust-lang/rust/issues/82814 - ------------------------- -"##, - }, - Lint { - label: "const_size_of_val", - description: r##"# `const_size_of_val` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_size_of_val_raw", - description: r##"# `const_size_of_val_raw` - -The tracking issue for this feature is: [#46571] - -[#46571]: https://github.com/rust-lang/rust/issues/46571 - ------------------------- -"##, - }, - Lint { - label: "const_slice_first_last", - description: r##"# `const_slice_first_last` - -The tracking issue for this feature is: [#83570] - -[#83570]: https://github.com/rust-lang/rust/issues/83570 - ------------------------- -"##, - }, - Lint { - label: "const_slice_first_last_chunk", - description: r##"# `const_slice_first_last_chunk` - -The tracking issue for this feature is: [#111774] - -[#111774]: https://github.com/rust-lang/rust/issues/111774 +[#53020]: https://github.com/rust-lang/rust/issues/53020 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_flatten", @@ -3649,6 +4648,9 @@ The tracking issue for this feature is: [#95629] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_from_mut_ptr_range", @@ -3660,6 +4662,9 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_slice_from_ptr_range", @@ -3671,59 +4676,23 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_slice_from_raw_parts_mut", - description: r##"# `const_slice_from_raw_parts_mut` - -The tracking issue for this feature is: [#67456] - -[#67456]: https://github.com/rust-lang/rust/issues/67456 - ------------------------- -"##, - }, - Lint { - label: "const_slice_from_ref", - description: r##"# `const_slice_from_ref` - -The tracking issue for this feature is: [#90206] - -[#90206]: https://github.com/rust-lang/rust/issues/90206 - ------------------------- -"##, - }, - Lint { - label: "const_slice_index", - description: r##"# `const_slice_index` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_slice_split_at_mut", - description: r##"# `const_slice_split_at_mut` - -The tracking issue for this feature is: [#101804] - -[#101804]: https://github.com/rust-lang/rust/issues/101804 - ------------------------- -"##, - }, - Lint { - label: "const_str_from_raw_parts_mut", - description: r##"# `const_str_from_raw_parts_mut` + label: "const_sockaddr_setters", + description: r##"# `const_sockaddr_setters` -The tracking issue for this feature is: [#119206] +The tracking issue for this feature is: [#131714] -[#119206]: https://github.com/rust-lang/rust/issues/119206 +[#131714]: https://github.com/rust-lang/rust/issues/131714 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_str_from_utf8", @@ -3735,28 +4704,23 @@ The tracking issue for this feature is: [#91006] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_str_from_utf8_unchecked_mut", - description: r##"# `const_str_from_utf8_unchecked_mut` + label: "const_str_split_at", + description: r##"# `const_str_split_at` -The tracking issue for this feature is: [#91005] +The tracking issue for this feature is: [#131518] -[#91005]: https://github.com/rust-lang/rust/issues/91005 - ------------------------- -"##, - }, - Lint { - label: "const_strict_overflow_ops", - description: r##"# `const_strict_overflow_ops` - -The tracking issue for this feature is: [#118260] - -[#118260]: https://github.com/rust-lang/rust/issues/118260 +[#131518]: https://github.com/rust-lang/rust/issues/131518 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_swap", @@ -3768,15 +4732,23 @@ The tracking issue for this feature is: [#83163] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_three_way_compare", - description: r##"# `const_three_way_compare` + label: "const_swap_nonoverlapping", + description: r##"# `const_swap_nonoverlapping` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#133668] + +[#133668]: https://github.com/rust-lang/rust/issues/133668 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_trait_impl", @@ -3788,6 +4760,9 @@ The tracking issue for this feature is: [#67792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_try", @@ -3799,6 +4774,9 @@ The tracking issue for this feature is: [#74935] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_type_id", @@ -3810,6 +4788,9 @@ The tracking issue for this feature is: [#77125] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_type_name", @@ -3821,6 +4802,9 @@ The tracking issue for this feature is: [#63084] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "const_typed_swap", @@ -3830,48 +4814,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "const_ub_checks", - description: r##"# `const_ub_checks` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - }, - Lint { - label: "const_unicode_case_lookup", - description: r##"# `const_unicode_case_lookup` - -The tracking issue for this feature is: [#101400] - -[#101400]: https://github.com/rust-lang/rust/issues/101400 - ------------------------- -"##, - }, - Lint { - label: "const_unsafecell_get_mut", - description: r##"# `const_unsafecell_get_mut` + label: "const_vec_string_slice", + description: r##"# `const_vec_string_slice` -The tracking issue for this feature is: [#88836] +The tracking issue for this feature is: [#129041] -[#88836]: https://github.com/rust-lang/rust/issues/88836 - ------------------------- -"##, - }, - Lint { - label: "const_waker", - description: r##"# `const_waker` - -The tracking issue for this feature is: [#102012] - -[#102012]: https://github.com/rust-lang/rust/issues/102012 +[#129041]: https://github.com/rust-lang/rust/issues/129041 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "container_error_extra", @@ -3881,6 +4840,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "context_ext", @@ -3892,17 +4854,9 @@ The tracking issue for this feature is: [#123392] ------------------------ "##, - }, - Lint { - label: "control_flow_enum", - description: r##"# `control_flow_enum` - -The tracking issue for this feature is: [#75744] - -[#75744]: https://github.com/rust-lang/rust/issues/75744 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "convert_float_to_int", @@ -3914,6 +4868,9 @@ The tracking issue for this feature is: [#67057] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_intrinsics", @@ -3923,6 +4880,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_io_borrowed_buf", @@ -3934,15 +4894,9 @@ The tracking issue for this feature is: [#117693] ------------------------ "##, - }, - Lint { - label: "pattern_type_macro", - description: r##"# `pattern_type_macro` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_private_bignum", @@ -3952,6 +4906,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "core_private_diy_float", @@ -3961,6 +4918,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutine_clone", @@ -3972,6 +4932,9 @@ The tracking issue for this feature is: [#95360] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutine_trait", @@ -3983,6 +4946,9 @@ The tracking issue for this feature is: [#43122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coroutines", @@ -4234,6 +5200,9 @@ it's invalid to resume a completed coroutine. It's also worth noting that this is just a rough desugaring, not a normative specification for what the compiler does. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "coverage_attribute", @@ -4268,6 +5237,9 @@ fn bar() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cow_is_borrowed", @@ -4279,6 +5251,9 @@ The tracking issue for this feature is: [#65143] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "csky_target_feature", @@ -4290,6 +5265,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cstr_bytes", @@ -4301,6 +5279,9 @@ The tracking issue for this feature is: [#112115] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "cstr_internals", @@ -4310,10 +5291,13 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "cursor_remaining", - description: r##"# `cursor_remaining` + label: "cursor_split", + description: r##"# `cursor_split` The tracking issue for this feature is: [#86369] @@ -4321,6 +5305,9 @@ The tracking issue for this feature is: [#86369] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_inner_attributes", @@ -4332,6 +5319,9 @@ The tracking issue for this feature is: [#54726] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_mir", @@ -4341,6 +5331,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "custom_test_frameworks", @@ -4377,6 +5370,9 @@ const WILL_PASS: i32 = 0; const WILL_FAIL: i32 = 4; ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deadline_api", @@ -4388,6 +5384,9 @@ The tracking issue for this feature is: [#46316] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "debug_closure_helpers", @@ -4399,6 +5398,9 @@ The tracking issue for this feature is: [#117729] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dec2flt", @@ -4408,6 +5410,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "decl_macro", @@ -4419,17 +5424,23 @@ The tracking issue for this feature is: [#39412] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "default_type_parameter_fallback", - description: r##"# `default_type_parameter_fallback` + label: "default_field_values", + description: r##"# `default_field_values` -The tracking issue for this feature is: [#27336] +The tracking issue for this feature is: [#132162] -[#27336]: https://github.com/rust-lang/rust/issues/27336 +[#132162]: https://github.com/rust-lang/rust/issues/132162 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_safe", @@ -4441,6 +5452,9 @@ The tracking issue for this feature is: [#94978] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deprecated_suggestion", @@ -4452,6 +5466,9 @@ The tracking issue for this feature is: [#94785] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deref_patterns", @@ -4463,6 +5480,9 @@ The tracking issue for this feature is: [#87121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "deref_pure_trait", @@ -4474,6 +5494,9 @@ The tracking issue for this feature is: [#87121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "derive_clone_copy", @@ -4483,35 +5506,47 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_const", - description: r##"# `derive_const` + label: "derive_coerce_pointee", + description: r##"# `derive_coerce_pointee` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#123430] + +[#123430]: https://github.com/rust-lang/rust/issues/123430 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_eq", - description: r##"# `derive_eq` + label: "derive_const", + description: r##"# `derive_const` -This feature is internal to the Rust compiler and is not intended for general use. +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "derive_smart_pointer", - description: r##"# `derive_smart_pointer` - -The tracking issue for this feature is: [#123430] + label: "derive_eq", + description: r##"# `derive_eq` -[#123430]: https://github.com/rust-lang/rust/issues/123430 +This feature is internal to the Rust compiler and is not intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dir_entry_ext2", @@ -4523,6 +5558,9 @@ The tracking issue for this feature is: [#85573] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "discriminant_kind", @@ -4532,6 +5570,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dispatch_from_dyn", @@ -4541,6 +5582,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "do_not_recommend", @@ -4552,6 +5596,9 @@ The tracking issue for this feature is: [#51992] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_auto_cfg", @@ -4563,6 +5610,9 @@ The tracking issue for this feature is: [#43781] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_cfg", @@ -4613,6 +5663,9 @@ pub struct Icon { [#43781]: https://github.com/rust-lang/rust/issues/43781 [#43348]: https://github.com/rust-lang/rust/issues/43348 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_cfg_hide", @@ -4624,6 +5677,9 @@ The tracking issue for this feature is: [#43781] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_masked", @@ -4652,6 +5708,9 @@ Such types would introduce broken links into the documentation. [#44026]: https://github.com/rust-lang/rust/pull/44026 [#44027]: https://github.com/rust-lang/rust/pull/44027 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "doc_notable_trait", @@ -4689,6 +5748,9 @@ See also its documentation in [the rustdoc book][rustdoc-book-notable_trait]. [#45039]: https://github.com/rust-lang/rust/pull/45039 [rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "downcast_unchecked", @@ -4700,6 +5762,9 @@ The tracking issue for this feature is: [#90850] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "drain_keep_rest", @@ -4711,6 +5776,9 @@ The tracking issue for this feature is: [#101122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "dropck_eyepatch", @@ -4722,6 +5790,9 @@ The tracking issue for this feature is: [#34761] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_constants", @@ -4733,6 +5804,9 @@ The tracking issue for this feature is: [#57391] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_constructors", @@ -4746,17 +5820,9 @@ The tracking issue for this feature is: [#120301] Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`. "##, - }, - Lint { - label: "duration_consts_float", - description: r##"# `duration_consts_float` - -The tracking issue for this feature is: [#72440] - -[#72440]: https://github.com/rust-lang/rust/issues/72440 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_millis_float", @@ -4768,6 +5834,9 @@ The tracking issue for this feature is: [#122451] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "duration_units", @@ -4775,61 +5844,53 @@ The tracking issue for this feature is: [#122451] The tracking issue for this feature is: [#120301] -[#120301]: https://github.com/rust-lang/rust/issues/120301 - ------------------------- -"##, - }, - Lint { - label: "dyn_star", - description: r##"# `dyn_star` - -The tracking issue for this feature is: [#102425] - -[#102425]: https://github.com/rust-lang/rust/issues/102425 - ------------------------- -"##, - }, - Lint { - label: "edition_panic", - description: r##"# `edition_panic` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +[#120301]: https://github.com/rust-lang/rust/issues/120301 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "effect_types", - description: r##"# `effect_types` + label: "dyn_compatible_for_dispatch", + description: r##"# `dyn_compatible_for_dispatch` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#43561] + +[#43561]: https://github.com/rust-lang/rust/issues/43561 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "effects", - description: r##"# `effects` + label: "dyn_star", + description: r##"# `dyn_star` -The tracking issue for this feature is: [#102090] +The tracking issue for this feature is: [#102425] -[#102090]: https://github.com/rust-lang/rust/issues/102090 +[#102425]: https://github.com/rust-lang/rust/issues/102425 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "entry_insert", - description: r##"# `entry_insert` - -The tracking issue for this feature is: [#65225] + label: "edition_panic", + description: r##"# `edition_panic` -[#65225]: https://github.com/rust-lang/rust/issues/65225 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ermsb_target_feature", @@ -4841,6 +5902,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_generic_member_access", @@ -4852,6 +5916,9 @@ The tracking issue for this feature is: [#99301] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_iter", @@ -4863,6 +5930,9 @@ The tracking issue for this feature is: [#58520] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_reporter", @@ -4874,6 +5944,9 @@ The tracking issue for this feature is: [#90172] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "error_type_id", @@ -4885,6 +5958,9 @@ The tracking issue for this feature is: [#60784] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exact_size_is_empty", @@ -4896,6 +5972,9 @@ The tracking issue for this feature is: [#35428] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exclusive_wrapper", @@ -4907,6 +5986,9 @@ The tracking issue for this feature is: [#98407] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exhaustive_patterns", @@ -4918,6 +6000,9 @@ The tracking issue for this feature is: [#51085] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exit_status_error", @@ -4929,6 +6014,9 @@ The tracking issue for this feature is: [#84908] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "exitcode_exit_method", @@ -4940,6 +6028,9 @@ The tracking issue for this feature is: [#97100] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "explicit_tail_calls", @@ -4951,28 +6042,9 @@ The tracking issue for this feature is: [#112788] ------------------------ "##, - }, - Lint { - label: "exposed_provenance", - description: r##"# `exposed_provenance` - -The tracking issue for this feature is: [#95228] - -[#95228]: https://github.com/rust-lang/rust/issues/95228 - ------------------------- -"##, - }, - Lint { - label: "expr_fragment_specifier_2024", - description: r##"# `expr_fragment_specifier_2024` - -The tracking issue for this feature is: [#123742] - -[#123742]: https://github.com/rust-lang/rust/issues/123742 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extend_one", @@ -4984,6 +6056,9 @@ The tracking issue for this feature is: [#72631] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extend_one_unchecked", @@ -4993,20 +6068,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "extended_varargs_abi_support", - description: r##"# `extended_varargs_abi_support` - -The tracking issue for this feature is: [#100189] - -[#100189]: https://github.com/rust-lang/rust/issues/100189 - ------------------------- - -This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling -conventions on functions with varargs. -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extern_types", @@ -5018,6 +6082,9 @@ The tracking issue for this feature is: [#43467] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "extract_if", @@ -5029,6 +6096,9 @@ The tracking issue for this feature is: [#43244] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "f128", @@ -5042,6 +6112,9 @@ The tracking issue for this feature is: [#116909] Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "f16", @@ -5055,6 +6128,9 @@ The tracking issue for this feature is: [#116909] Enable the `f16` type for IEEE 16-bit floating numbers (half precision). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fd", @@ -5064,6 +6140,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fd_read", @@ -5073,6 +6152,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_const", @@ -5129,6 +6211,9 @@ against are compatible with those of the `#[ffi_const]`. [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ffi_pure", @@ -5189,6 +6274,37 @@ against are compatible with those of the `#[ffi_pure]`. [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "file_buffered", + description: r##"# `file_buffered` + +The tracking issue for this feature is: [#130804] + +[#130804]: https://github.com/rust-lang/rust/issues/130804 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "file_lock", + description: r##"# `file_lock` + +The tracking issue for this feature is: [#130994] + +[#130994]: https://github.com/rust-lang/rust/issues/130994 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_gamma", @@ -5200,6 +6316,9 @@ The tracking issue for this feature is: [#99842] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_minimum_maximum", @@ -5211,6 +6330,9 @@ The tracking issue for this feature is: [#91079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "float_next_up_down", @@ -5222,6 +6344,9 @@ The tracking issue for this feature is: [#91399] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "flt2dec", @@ -5231,6 +6356,23 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "fmt_debug", + description: r##"# `fmt_debug` + +The tracking issue for this feature is: [#129709] + +[#129709]: https://github.com/rust-lang/rust/issues/129709 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fmt_helpers_for_derive", @@ -5240,6 +6382,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fmt_internals", @@ -5249,6 +6394,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_align", @@ -5260,6 +6408,9 @@ The tracking issue for this feature is: [#82232] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_delegation", @@ -5271,6 +6422,9 @@ The tracking issue for this feature is: [#118212] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_ptr_trait", @@ -5280,6 +6434,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fn_traits", @@ -5319,6 +6476,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "forget_unsized", @@ -5328,6 +6488,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "format_args_nl", @@ -5337,6 +6500,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "formatting_options", + description: r##"# `formatting_options` + +The tracking issue for this feature is: [#118117] + +[#118117]: https://github.com/rust-lang/rust/issues/118117 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "freeze", @@ -5348,6 +6528,9 @@ The tracking issue for this feature is: [#121675] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "freeze_impls", @@ -5359,6 +6542,9 @@ The tracking issue for this feature is: [#121675] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "fundamental", @@ -5370,6 +6556,9 @@ The tracking issue for this feature is: [#29635] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "future_join", @@ -5381,6 +6570,9 @@ The tracking issue for this feature is: [#91642] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "gen_blocks", @@ -5392,6 +6584,9 @@ The tracking issue for this feature is: [#117078] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "gen_future", @@ -5403,6 +6598,9 @@ The tracking issue for this feature is: [#50547] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_arg_infer", @@ -5414,6 +6612,9 @@ The tracking issue for this feature is: [#85077] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_assert", @@ -5423,6 +6624,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_assert_internals", @@ -5434,17 +6638,9 @@ The tracking issue for this feature is: [#44838] ------------------------ "##, - }, - Lint { - label: "generic_associated_types_extended", - description: r##"# `generic_associated_types_extended` - -The tracking issue for this feature is: [#95451] - -[#95451]: https://github.com/rust-lang/rust/issues/95451 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_const_exprs", @@ -5456,6 +6652,9 @@ The tracking issue for this feature is: [#76560] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "generic_const_items", @@ -5467,6 +6666,9 @@ The tracking issue for this feature is: [#113521] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "get_many_mut", @@ -5478,6 +6680,21 @@ The tracking issue for this feature is: [#104642] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "get_many_mut_helpers", + description: r##"# `get_many_mut_helpers` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "get_mut_unchecked", @@ -5489,6 +6706,9 @@ The tracking issue for this feature is: [#63292] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "global_registration", @@ -5500,6 +6720,23 @@ The tracking issue for this feature is: [#125119] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "guard_patterns", + description: r##"# `guard_patterns` + +The tracking issue for this feature is: [#129967] + +[#129967]: https://github.com/rust-lang/rust/issues/129967 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "half_open_range_patterns_in_slices", @@ -5533,6 +6770,9 @@ fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_extract_if", @@ -5544,6 +6784,9 @@ The tracking issue for this feature is: [#59618] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_raw_entry", @@ -5555,6 +6798,9 @@ The tracking issue for this feature is: [#56167] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hash_set_entry", @@ -5566,6 +6812,9 @@ The tracking issue for this feature is: [#60896] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hasher_prefixfree_extras", @@ -5577,6 +6826,9 @@ The tracking issue for this feature is: [#96762] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hashmap_internals", @@ -5586,6 +6838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hexagon_target_feature", @@ -5597,6 +6852,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "hint_must_use", @@ -5608,6 +6866,9 @@ The tracking issue for this feature is: [#94745] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "if_let_guard", @@ -5619,6 +6880,9 @@ The tracking issue for this feature is: [#51114] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_in_assoc_type", @@ -5630,6 +6894,9 @@ The tracking issue for this feature is: [#63063] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "impl_trait_in_fn_trait_return", @@ -5641,6 +6908,9 @@ The tracking issue for this feature is: [#99697] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inherent_associated_types", @@ -5652,6 +6922,9 @@ The tracking issue for this feature is: [#8995] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inline_const_pat", @@ -5678,6 +6951,9 @@ match some_int { [#76001]: https://github.com/rust-lang/rust/issues/76001 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "inplace_iteration", @@ -5687,6 +6963,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "int_roundings", @@ -5698,6 +6977,9 @@ The tracking issue for this feature is: [#88581] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "integer_atomics", @@ -5709,6 +6991,9 @@ The tracking issue for this feature is: [#99069] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "integer_sign_cast", @@ -5720,6 +7005,9 @@ The tracking issue for this feature is: [#125882] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "internal_impls_macro", @@ -5729,6 +7017,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "internal_output_capture", @@ -5738,6 +7029,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "intra_doc_pointers", @@ -5757,6 +7051,9 @@ raw pointers in intra-doc links are unstable until it does. //! [pointer::add] ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "intrinsics", @@ -5780,7 +7077,7 @@ All intrinsic fallback bodies are automatically made cross-crate inlineable (lik by the codegen backend, but not the MIR inliner. ```rust -#![feature(rustc_attrs)] +#![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -5790,7 +7087,7 @@ const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} Since these are just regular functions, it is perfectly ok to create the intrinsic twice: ```rust -#![feature(rustc_attrs)] +#![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -5852,105 +7149,159 @@ extern "rust-intrinsic" { As with any other FFI functions, these are by default always `unsafe` to call. You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "io_error_more", - description: r##"# `io_error_more` + label: "io_const_error", + description: r##"# `io_const_error` -The tracking issue for this feature is: [#86442] +The tracking issue for this feature is: [#133448] -[#86442]: https://github.com/rust-lang/rust/issues/86442 +[#133448]: https://github.com/rust-lang/rust/issues/133448 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "io_error_uncategorized", - description: r##"# `io_error_uncategorized` + label: "io_const_error_internals", + description: r##"# `io_const_error_internals` This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "ip", - description: r##"# `ip` + label: "io_error_inprogress", + description: r##"# `io_error_inprogress` -The tracking issue for this feature is: [#27709] +The tracking issue for this feature is: [#130840] -[#27709]: https://github.com/rust-lang/rust/issues/27709 +[#130840]: https://github.com/rust-lang/rust/issues/130840 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_ascii_octdigit", - description: r##"# `is_ascii_octdigit` + label: "io_error_more", + description: r##"# `io_error_more` -The tracking issue for this feature is: [#101288] +The tracking issue for this feature is: [#86442] -[#101288]: https://github.com/rust-lang/rust/issues/101288 +[#86442]: https://github.com/rust-lang/rust/issues/86442 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_none_or", - description: r##"# `is_none_or` + label: "io_error_uncategorized", + description: r##"# `io_error_uncategorized` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "io_slice_as_bytes", + description: r##"# `io_slice_as_bytes` -The tracking issue for this feature is: [#126383] +The tracking issue for this feature is: [#132818] -[#126383]: https://github.com/rust-lang/rust/issues/126383 +[#132818]: https://github.com/rust-lang/rust/issues/132818 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_riscv_feature_detected", - description: r##"# `is_riscv_feature_detected` + label: "ip", + description: r##"# `ip` -The tracking issue for this feature is: [#111192] +The tracking issue for this feature is: [#27709] -[#111192]: https://github.com/rust-lang/rust/issues/111192 +[#27709]: https://github.com/rust-lang/rust/issues/27709 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_sorted", - description: r##"# `is_sorted` + label: "ip_from", + description: r##"# `ip_from` -The tracking issue for this feature is: [#53485] +The tracking issue for this feature is: [#131360] -[#53485]: https://github.com/rust-lang/rust/issues/53485 +[#131360]: https://github.com/rust-lang/rust/issues/131360 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "is_ascii_octdigit", + description: r##"# `is_ascii_octdigit` + +The tracking issue for this feature is: [#101288] -Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`; -add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to -`Iterator`. +[#101288]: https://github.com/rust-lang/rust/issues/101288 + +------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "is_val_statically_known", - description: r##"# `is_val_statically_known` + label: "is_loongarch_feature_detected", + description: r##"# `is_loongarch_feature_detected` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#117425] + +[#117425]: https://github.com/rust-lang/rust/issues/117425 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "isqrt", - description: r##"# `isqrt` + label: "is_riscv_feature_detected", + description: r##"# `is_riscv_feature_detected` -The tracking issue for this feature is: [#116226] +The tracking issue for this feature is: [#111192] -[#116226]: https://github.com/rust-lang/rust/issues/116226 +[#111192]: https://github.com/rust-lang/rust/issues/111192 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_advance_by", @@ -5962,6 +7313,9 @@ The tracking issue for this feature is: [#77404] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_array_chunks", @@ -5973,6 +7327,9 @@ The tracking issue for this feature is: [#100450] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_chain", @@ -5984,6 +7341,9 @@ The tracking issue for this feature is: [#125964] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_collect_into", @@ -5995,6 +7355,9 @@ The tracking issue for this feature is: [#94780] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_from_coroutine", @@ -6006,6 +7369,9 @@ The tracking issue for this feature is: [#43122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_intersperse", @@ -6017,6 +7383,9 @@ The tracking issue for this feature is: [#79524] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_is_partitioned", @@ -6028,6 +7397,9 @@ The tracking issue for this feature is: [#62544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_map_windows", @@ -6039,6 +7411,9 @@ The tracking issue for this feature is: [#87155] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_next_chunk", @@ -6050,6 +7425,9 @@ The tracking issue for this feature is: [#98326] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_order_by", @@ -6061,6 +7439,9 @@ The tracking issue for this feature is: [#64295] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iter_partition_in_place", @@ -6072,17 +7453,9 @@ The tracking issue for this feature is: [#62543] ------------------------ "##, - }, - Lint { - label: "iter_repeat_n", - description: r##"# `iter_repeat_n` - -The tracking issue for this feature is: [#104434] - -[#104434]: https://github.com/rust-lang/rust/issues/104434 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iterator_try_collect", @@ -6094,6 +7467,9 @@ The tracking issue for this feature is: [#94047] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "iterator_try_reduce", @@ -6105,6 +7481,9 @@ The tracking issue for this feature is: [#87053] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "junction_point", @@ -6116,6 +7495,9 @@ The tracking issue for this feature is: [#121709] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lahfsahf_target_feature", @@ -6127,6 +7509,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lang_items", @@ -6246,6 +7631,9 @@ An up-to-date list of all language items can be found [here] in the compiler cod [here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "large_assignments", @@ -6257,6 +7645,9 @@ The tracking issue for this feature is: [#83518] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "layout_for_ptr", @@ -6268,6 +7659,9 @@ The tracking issue for this feature is: [#69835] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lazy_cell_into_inner", @@ -6279,6 +7673,23 @@ The tracking issue for this feature is: [#125623] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "lazy_get", + description: r##"# `lazy_get` + +The tracking issue for this feature is: [#129333] + +[#129333]: https://github.com/rust-lang/rust/issues/129333 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lazy_type_alias", @@ -6290,6 +7701,21 @@ The tracking issue for this feature is: [#112792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "legacy_receiver_trait", + description: r##"# `legacy_receiver_trait` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "let_chains", @@ -6301,6 +7727,9 @@ The tracking issue for this feature is: [#53667] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "liballoc_internals", @@ -6310,6 +7739,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "libstd_sys_internals", @@ -6319,6 +7751,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "lifetime_capture_rules_2024", @@ -6328,6 +7763,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_arg_attribute", @@ -6353,6 +7791,9 @@ extern "C" {} [#99427]: https://github.com/rust-lang/rust/issues/99427 "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_cfg", @@ -6362,6 +7803,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "link_llvm_intrinsics", @@ -6373,6 +7817,9 @@ The tracking issue for this feature is: [#29602] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linkage", @@ -6384,6 +7831,9 @@ The tracking issue for this feature is: [#29603] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_cursors", @@ -6395,6 +7845,9 @@ The tracking issue for this feature is: [#58533] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_remove", @@ -6406,6 +7859,9 @@ The tracking issue for this feature is: [#69210] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linked_list_retain", @@ -6417,6 +7873,9 @@ The tracking issue for this feature is: [#114135] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "linux_pidfd", @@ -6428,6 +7887,9 @@ The tracking issue for this feature is: [#82971] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "local_waker", @@ -6439,6 +7901,9 @@ The tracking issue for this feature is: [#118959] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "log_syntax", @@ -6450,6 +7915,9 @@ The tracking issue for this feature is: [#29598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "loongarch_target_feature", @@ -6461,6 +7929,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_metavar_expr", @@ -6472,6 +7943,9 @@ The tracking issue for this feature is: [#83527] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "macro_metavar_expr_concat", @@ -6483,17 +7957,9 @@ The tracking issue for this feature is: [#124225] ------------------------ "##, - }, - Lint { - label: "map_entry_replace", - description: r##"# `map_entry_replace` - -The tracking issue for this feature is: [#44286] - -[#44286]: https://github.com/rust-lang/rust/issues/44286 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_many_mut", @@ -6505,6 +7971,9 @@ The tracking issue for this feature is: [#97601] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "map_try_insert", @@ -6516,6 +7985,9 @@ The tracking issue for this feature is: [#82766] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mapped_lock_guards", @@ -6527,6 +7999,9 @@ The tracking issue for this feature is: [#117108] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "marker_trait_attr", @@ -6566,6 +8041,9 @@ fn cheap_clone(t: T) -> T { This is expected to replace the unstable `overlapping_marker_traits` feature, which applied to all empty traits (without needing an opt-in). "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_array_assume_init", @@ -6577,6 +8055,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_as_bytes", @@ -6588,6 +8069,9 @@ The tracking issue for this feature is: [#93092] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_fill", @@ -6599,6 +8083,9 @@ The tracking issue for this feature is: [#117428] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_slice", @@ -6610,6 +8097,9 @@ The tracking issue for this feature is: [#63569] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_uninit_array", @@ -6621,6 +8111,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_uninit_array_transpose", @@ -6632,6 +8125,9 @@ The tracking issue for this feature is: [#96097] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "maybe_uninit_write_slice", @@ -6643,6 +8139,9 @@ The tracking issue for this feature is: [#79995] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mem_copy_fn", @@ -6654,17 +8153,23 @@ The tracking issue for this feature is: [#98262] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "min_exhaustive_patterns", - description: r##"# `min_exhaustive_patterns` + label: "min_generic_const_args", + description: r##"# `min_generic_const_args` -The tracking issue for this feature is: [#119612] +The tracking issue for this feature is: [#132980] -[#119612]: https://github.com/rust-lang/rust/issues/119612 +[#132980]: https://github.com/rust-lang/rust/issues/132980 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "min_specialization", @@ -6676,6 +8181,9 @@ The tracking issue for this feature is: [#31844] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mips_target_feature", @@ -6687,6 +8195,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "mixed_integer_ops_unsigned_sub", + description: r##"# `mixed_integer_ops_unsigned_sub` + +The tracking issue for this feature is: [#126043] + +[#126043]: https://github.com/rust-lang/rust/issues/126043 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "more_float_constants", @@ -6698,6 +8223,21 @@ The tracking issue for this feature is: [#103883] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "more_maybe_bounds", + description: r##"# `more_maybe_bounds` + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "more_qualified_paths", @@ -6706,6 +8246,10 @@ The tracking issue for this feature is: [#103883] The `more_qualified_paths` feature can be used in order to enable the use of qualified paths in patterns. +The tracking issue for this feature is: [#86935](https://github.com/rust-lang/rust/issues/86935). + +------------------------ + ## Example ```rust @@ -6731,6 +8275,23 @@ impl A for Foo { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "mpmc_channel", + description: r##"# `mpmc_channel` + +The tracking issue for this feature is: [#126840] + +[#126840]: https://github.com/rust-lang/rust/issues/126840 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "multiple_supertrait_upcastable", @@ -6740,6 +8301,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "must_not_suspend", @@ -6751,6 +8315,9 @@ The tracking issue for this feature is: [#83310] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "mut_ref", @@ -6762,6 +8329,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "naked_functions", @@ -6773,6 +8343,9 @@ The tracking issue for this feature is: [#90957] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "native_link_modifiers_as_needed", @@ -6795,6 +8368,9 @@ The modifier does nothing for linkers that don't support it (e.g. `link.exe`). The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "needs_panic_runtime", @@ -6806,6 +8382,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "negative_bounds", @@ -6815,6 +8394,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "negative_impls", @@ -6876,6 +8458,9 @@ This serves two purposes: * For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists. * It prevents downstream crates from creating such impls. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_patterns", @@ -6887,6 +8472,9 @@ The tracking issue for this feature is: [#118155] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_type", @@ -6898,6 +8486,9 @@ The tracking issue for this feature is: [#35121] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "never_type_fallback", @@ -6909,6 +8500,9 @@ The tracking issue for this feature is: [#65992] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "new_range_api", @@ -6920,17 +8514,23 @@ The tracking issue for this feature is: [#125687] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "new_uninit", - description: r##"# `new_uninit` + label: "new_zeroed_alloc", + description: r##"# `new_zeroed_alloc` -The tracking issue for this feature is: [#63291] +The tracking issue for this feature is: [#129396] -[#63291]: https://github.com/rust-lang/rust/issues/63291 +[#129396]: https://github.com/rust-lang/rust/issues/129396 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "no_core", @@ -6942,6 +8542,9 @@ The tracking issue for this feature is: [#29639] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "no_sanitize", @@ -6975,6 +8578,9 @@ fn foo() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_exhaustive_omitted_patterns_lint", @@ -6986,6 +8592,9 @@ The tracking issue for this feature is: [#89554] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_lifetime_binders", @@ -6997,6 +8606,23 @@ The tracking issue for this feature is: [#108185] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_null_from_ref", + description: r##"# `non_null_from_ref` + +The tracking issue for this feature is: [#130823] + +[#130823]: https://github.com/rust-lang/rust/issues/130823 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "non_zero_count_ones", @@ -7008,6 +8634,23 @@ The tracking issue for this feature is: [#120287] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonzero_bitwise", + description: r##"# `nonzero_bitwise` + +The tracking issue for this feature is: [#128281] + +[#128281]: https://github.com/rust-lang/rust/issues/128281 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_from_mut", @@ -7019,6 +8662,9 @@ The tracking issue for this feature is: [#106290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_internals", @@ -7028,6 +8674,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "nonzero_ops", @@ -7039,21 +8688,13 @@ The tracking issue for this feature is: [#84186] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "noop_waker", - description: r##"# `noop_waker` - -The tracking issue for this feature is: [#98286] - -[#98286]: https://github.com/rust-lang/rust/issues/98286 - ------------------------- -"##, - }, - Lint { - label: "num_midpoint", - description: r##"# `num_midpoint` + label: "num_midpoint_signed", + description: r##"# `num_midpoint_signed` The tracking issue for this feature is: [#110840] @@ -7061,6 +8702,9 @@ The tracking issue for this feature is: [#110840] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "numfmt", @@ -7070,17 +8714,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "dyn_compatible_for_dispatch", - description: r##"# `dyn_compatible_for_dispatch` - -The tracking issue for this feature is: [#43561] - -[#43561]: https://github.com/rust-lang/rust/issues/43561 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "offset_of_enum", @@ -7092,17 +8728,9 @@ The tracking issue for this feature is: [#120141] ------------------------ "##, - }, - Lint { - label: "offset_of_nested", - description: r##"# `offset_of_nested` - -The tracking issue for this feature is: [#120140] - -[#120140]: https://github.com/rust-lang/rust/issues/120140 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "offset_of_slice", @@ -7114,6 +8742,9 @@ The tracking issue for this feature is: [#126151] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "omit_gdb_pretty_printer_section", @@ -7123,6 +8754,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_get_mut", @@ -7134,6 +8768,9 @@ The tracking issue for this feature is: [#121641] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_try", @@ -7145,6 +8782,9 @@ The tracking issue for this feature is: [#109737] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "once_cell_try_insert", @@ -7156,6 +8796,23 @@ The tracking issue for this feature is: [#116693] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "once_wait", + description: r##"# `once_wait` + +The tracking issue for this feature is: [#127527] + +[#127527]: https://github.com/rust-lang/rust/issues/127527 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "one_sided_range", @@ -7167,6 +8824,9 @@ The tracking issue for this feature is: [#69780] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "optimize_attribute", @@ -7178,17 +8838,23 @@ The tracking issue for this feature is: [#54882] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "option_get_or_insert_default", - description: r##"# `option_get_or_insert_default` + label: "option_array_transpose", + description: r##"# `option_array_transpose` -The tracking issue for this feature is: [#82901] +The tracking issue for this feature is: [#130828] -[#82901]: https://github.com/rust-lang/rust/issues/82901 +[#130828]: https://github.com/rust-lang/rust/issues/130828 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "option_zip", @@ -7200,6 +8866,9 @@ The tracking issue for this feature is: [#70086] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_str_display", @@ -7211,6 +8880,9 @@ The tracking issue for this feature is: [#120048] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_str_slice", @@ -7222,6 +8894,9 @@ The tracking issue for this feature is: [#118485] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "os_string_pathbuf_leak", @@ -7233,6 +8908,23 @@ The tracking issue for this feature is: [#125965] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "os_string_truncate", + description: r##"# `os_string_truncate` + +The tracking issue for this feature is: [#133262] + +[#133262]: https://github.com/rust-lang/rust/issues/133262 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_abort", @@ -7244,6 +8936,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_always_abort", @@ -7255,6 +8950,9 @@ The tracking issue for this feature is: [#84438] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_backtrace_config", @@ -7266,6 +8964,9 @@ The tracking issue for this feature is: [#93346] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_can_unwind", @@ -7277,6 +8978,9 @@ The tracking issue for this feature is: [#92988] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_internals", @@ -7286,6 +8990,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_payload_as_str", @@ -7297,6 +9004,9 @@ The tracking issue for this feature is: [#125175] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_runtime", @@ -7308,6 +9018,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_unwind", @@ -7319,6 +9032,9 @@ The tracking issue for this feature is: [#32837] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "panic_update_hook", @@ -7330,6 +9046,9 @@ The tracking issue for this feature is: [#92649] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "patchable_function_entry", @@ -7341,6 +9060,9 @@ The tracking issue for this feature is: [#123115] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "path_add_extension", @@ -7352,6 +9074,9 @@ The tracking issue for this feature is: [#127292] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "path_file_prefix", @@ -7363,6 +9088,9 @@ The tracking issue for this feature is: [#86319] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern", @@ -7374,15 +9102,35 @@ The tracking issue for this feature is: [#27721] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern_complexity", description: r##"# `pattern_complexity` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pattern_type_macro", + description: r##"# `pattern_type_macro` + +The tracking issue for this feature is: [#123646] + +[#123646]: https://github.com/rust-lang/rust/issues/123646 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pattern_types", @@ -7394,6 +9142,9 @@ The tracking issue for this feature is: [#123646] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "peer_credentials_unix_socket", @@ -7405,17 +9156,37 @@ The tracking issue for this feature is: [#42839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pin_coerce_unsized_trait", + description: r##"# `pin_coerce_unsized_trait` + +The tracking issue for this feature is: [#123430] + +[#123430]: https://github.com/rust-lang/rust/issues/123430 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "pin_deref_mut", - description: r##"# `pin_deref_mut` + label: "pin_ergonomics", + description: r##"# `pin_ergonomics` -The tracking issue for this feature is: [#86918] +The tracking issue for this feature is: [#130494] -[#86918]: https://github.com/rust-lang/rust/issues/86918 +[#130494]: https://github.com/rust-lang/rust/issues/130494 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pointer_is_aligned_to", @@ -7427,6 +9198,9 @@ The tracking issue for this feature is: [#96284] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pointer_like_trait", @@ -7436,6 +9210,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "portable_simd", @@ -7447,6 +9224,9 @@ The tracking issue for this feature is: [#86656] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "postfix_match", @@ -7455,6 +9235,10 @@ The tracking issue for this feature is: [#86656] `postfix-match` adds the feature for matching upon values postfix the expressions that generate the values. +The tracking issue for this feature is: [#121618](https://github.com/rust-lang/rust/issues/121618). + +------------------------ + ```rust,edition2021 #![feature(postfix_match)] @@ -7473,6 +9257,9 @@ get_foo().match { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "powerpc_target_feature", @@ -7484,17 +9271,23 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "precise_capturing", - description: r##"# `precise_capturing` + label: "precise_capturing_in_traits", + description: r##"# `precise_capturing_in_traits` -The tracking issue for this feature is: [#123432] +The tracking issue for this feature is: [#130044] -[#123432]: https://github.com/rust-lang/rust/issues/123432 +[#130044]: https://github.com/rust-lang/rust/issues/130044 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prelude_2024", @@ -7506,6 +9299,9 @@ The tracking issue for this feature is: [#121042] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prelude_import", @@ -7515,6 +9311,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "prfchw_target_feature", @@ -7526,6 +9325,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "print_internals", @@ -7535,6 +9337,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_def_site", @@ -7546,6 +9351,9 @@ The tracking issue for this feature is: [#54724] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_diagnostic", @@ -7557,6 +9365,9 @@ The tracking issue for this feature is: [#54140] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_expand", @@ -7568,6 +9379,9 @@ The tracking issue for this feature is: [#90765] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_hygiene", @@ -7579,6 +9393,9 @@ The tracking issue for this feature is: [#54727] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_internals", @@ -7590,6 +9407,9 @@ The tracking issue for this feature is: [#27812] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_quote", @@ -7601,6 +9421,9 @@ The tracking issue for this feature is: [#54722] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_span", @@ -7612,6 +9435,23 @@ The tracking issue for this feature is: [#54725] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "proc_macro_totokens", + description: r##"# `proc_macro_totokens` + +The tracking issue for this feature is: [#130977] + +[#130977]: https://github.com/rust-lang/rust/issues/130977 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "proc_macro_tracked_env", @@ -7623,6 +9463,9 @@ The tracking issue for this feature is: [#99515] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "process_exitcode_internals", @@ -7632,6 +9475,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "process_internals", @@ -7641,6 +9487,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "profiler_runtime", @@ -7650,6 +9499,9 @@ The tracking issue for this feature is: [#42524](https://github.com/rust-lang/ru ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "profiler_runtime_lib", @@ -7659,6 +9511,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_alignment_type", @@ -7670,6 +9525,9 @@ The tracking issue for this feature is: [#102070] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_as_ref_unchecked", @@ -7681,6 +9539,9 @@ The tracking issue for this feature is: [#122034] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_as_uninit", @@ -7692,6 +9553,9 @@ The tracking issue for this feature is: [#75402] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_internals", @@ -7701,6 +9565,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_mask", @@ -7712,6 +9579,9 @@ The tracking issue for this feature is: [#98290] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_metadata", @@ -7723,6 +9593,9 @@ The tracking issue for this feature is: [#81513] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ptr_sub_ptr", @@ -7734,6 +9607,9 @@ The tracking issue for this feature is: [#95892] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "pub_crate_should_not_need_unstable_attr", @@ -7743,28 +9619,37 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "raw_os_error_ty", - description: r##"# `raw_os_error_ty` + label: "random", + description: r##"# `random` -The tracking issue for this feature is: [#107792] +The tracking issue for this feature is: [#130703] -[#107792]: https://github.com/rust-lang/rust/issues/107792 +[#130703]: https://github.com/rust-lang/rust/issues/130703 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "raw_ref_op", - description: r##"# `raw_ref_op` + label: "raw_os_error_ty", + description: r##"# `raw_os_error_ty` -The tracking issue for this feature is: [#64490] +The tracking issue for this feature is: [#107792] -[#64490]: https://github.com/rust-lang/rust/issues/64490 +[#107792]: https://github.com/rust-lang/rust/issues/107792 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "raw_slice_split", @@ -7776,6 +9661,9 @@ The tracking issue for this feature is: [#95595] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "raw_vec_internals", @@ -7785,6 +9673,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "read_buf", @@ -7796,26 +9687,9 @@ The tracking issue for this feature is: [#78485] ------------------------ "##, - }, - Lint { - label: "ready_into_inner", - description: r##"# `ready_into_inner` - -The tracking issue for this feature is: [#101196] - -[#101196]: https://github.com/rust-lang/rust/issues/101196 - ------------------------- -"##, - }, - Lint { - label: "receiver_trait", - description: r##"# `receiver_trait` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "reentrant_lock", @@ -7827,6 +9701,9 @@ The tracking issue for this feature is: [#121440] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ref_pat_eat_one_layer_2024", @@ -7838,6 +9715,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ref_pat_eat_one_layer_2024_structural", @@ -7849,6 +9729,9 @@ The tracking issue for this feature is: [#123076] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "register_tool", @@ -7860,6 +9743,9 @@ The tracking issue for this feature is: [#66079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "repr128", @@ -7882,6 +9768,9 @@ enum Foo { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "repr_simd", @@ -7893,6 +9782,9 @@ The tracking issue for this feature is: [#27731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "restricted_std", @@ -7902,24 +9794,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, - }, - Lint { - label: "result_ffi_guarantees", - description: r##"# `result_ffi_guarantees` - -The tracking issue for this feature is: [#110503] - -[#110503]: https://github.com/rust-lang/rust/issues/110503 - ------------------------- - -This feature adds the possibility of using `Result` in FFI if T's niche -value can be used to describe E or vise-versa. - -See [RFC 3391] for more information. - -[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "result_flattening", @@ -7931,6 +9808,9 @@ The tracking issue for this feature is: [#70142] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "return_type_notation", @@ -7942,6 +9822,9 @@ The tracking issue for this feature is: [#109417] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "riscv_target_feature", @@ -7953,6 +9836,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "round_char_boundary", @@ -7964,6 +9850,9 @@ The tracking issue for this feature is: [#93743] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rt", @@ -7973,6 +9862,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rtm_target_feature", @@ -7984,6 +9876,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rust_cold_cc", @@ -7995,6 +9890,9 @@ The tracking issue for this feature is: [#97544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_allow_const_fn_unstable", @@ -8006,6 +9904,9 @@ The tracking issue for this feature is: [#69399] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_attrs", @@ -8063,6 +9964,9 @@ error: size: Size { raw: 16 } error: aborting due to 2 previous errors ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_encodable_decodable", @@ -8072,6 +9976,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustc_private", @@ -8082,7 +9989,14 @@ The tracking issue for this feature is: [#27812] [#27812]: https://github.com/rust-lang/rust/issues/27812 ------------------------ + +This feature allows access to unstable internal compiler crates. + +Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc_internals", @@ -8094,6 +10008,9 @@ The tracking issue for this feature is: [#90418] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "rustdoc_missing_doc_code_examples", @@ -8105,6 +10022,23 @@ The tracking issue for this feature is: [#101730] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rwlock_downgrade", + description: r##"# `rwlock_downgrade` + +The tracking issue for this feature is: [#128203] + +[#128203]: https://github.com/rust-lang/rust/issues/128203 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "s390x_target_feature", @@ -8116,6 +10050,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sealed", @@ -8125,6 +10062,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "seek_stream_len", @@ -8136,6 +10076,9 @@ The tracking issue for this feature is: [#59359] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "set_ptr_value", @@ -8147,6 +10090,9 @@ The tracking issue for this feature is: [#75091] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "setgroups", @@ -8158,6 +10104,9 @@ The tracking issue for this feature is: [#90747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sgx_platform", @@ -8169,17 +10118,23 @@ The tracking issue for this feature is: [#56975] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "shorter_tail_lifetimes", - description: r##"# `shorter_tail_lifetimes` + label: "sha512_sm_x86", + description: r##"# `sha512_sm_x86` -The tracking issue for this feature is: [#123739] +The tracking issue for this feature is: [#126624] -[#123739]: https://github.com/rust-lang/rust/issues/123739 +[#126624]: https://github.com/rust-lang/rust/issues/126624 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "simd_ffi", @@ -8191,6 +10146,9 @@ The tracking issue for this feature is: [#27731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sized_type_properties", @@ -8200,6 +10158,23 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "slice_as_array", + description: r##"# `slice_as_array` + +The tracking issue for this feature is: [#133508] + +[#133508]: https://github.com/rust-lang/rust/issues/133508 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_as_chunks", @@ -8211,6 +10186,9 @@ The tracking issue for this feature is: [#74985] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_concat_ext", @@ -8222,6 +10200,9 @@ The tracking issue for this feature is: [#27747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_concat_trait", @@ -8233,6 +10214,9 @@ The tracking issue for this feature is: [#27747] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_from_ptr_range", @@ -8244,6 +10228,9 @@ The tracking issue for this feature is: [#89792] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_index_methods", @@ -8253,6 +10240,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_internals", @@ -8262,6 +10252,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_iter_mut_as_mut_slice", @@ -8273,6 +10266,9 @@ The tracking issue for this feature is: [#93079] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_partition_dedup", @@ -8284,6 +10280,9 @@ The tracking issue for this feature is: [#54279] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_pattern", @@ -8295,6 +10294,9 @@ The tracking issue for this feature is: [#56345] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_ptr_get", @@ -8306,6 +10308,9 @@ The tracking issue for this feature is: [#74265] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_range", @@ -8317,6 +10322,9 @@ The tracking issue for this feature is: [#76393] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_split_once", @@ -8328,6 +10336,9 @@ The tracking issue for this feature is: [#112811] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_swap_unchecked", @@ -8339,6 +10350,9 @@ The tracking issue for this feature is: [#88539] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "slice_take", @@ -8350,6 +10364,9 @@ The tracking issue for this feature is: [#62280] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "solid_ext", @@ -8359,6 +10376,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sort_floats", @@ -8370,6 +10390,23 @@ The tracking issue for this feature is: [#93396] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "sparc_target_feature", + description: r##"# `sparc_target_feature` + +The tracking issue for this feature is: [#132783] + +[#132783]: https://github.com/rust-lang/rust/issues/132783 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "specialization", @@ -8381,6 +10418,9 @@ The tracking issue for this feature is: [#31844] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "split_array", @@ -8392,6 +10432,9 @@ The tracking issue for this feature is: [#90091] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "split_as_slice", @@ -8403,6 +10446,9 @@ The tracking issue for this feature is: [#96137] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sse4a_target_feature", @@ -8414,6 +10460,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "staged_api", @@ -8423,6 +10472,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "start", @@ -8486,6 +10538,9 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "std_internals", @@ -8495,6 +10550,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_arm_feature_detection", @@ -8506,6 +10564,9 @@ The tracking issue for this feature is: [#111190] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_mips_feature_detection", @@ -8517,6 +10578,9 @@ The tracking issue for this feature is: [#111188] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdarch_powerpc_feature_detection", @@ -8528,6 +10592,9 @@ The tracking issue for this feature is: [#111191] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stdio_makes_pipe", @@ -8539,6 +10606,9 @@ The tracking issue for this feature is: [#98288] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "step_trait", @@ -8550,6 +10620,9 @@ The tracking issue for this feature is: [#42168] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "stmt_expr_attributes", @@ -8561,6 +10634,23 @@ The tracking issue for this feature is: [#15701] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "str_as_str", + description: r##"# `str_as_str` + +The tracking issue for this feature is: [#130366] + +[#130366]: https://github.com/rust-lang/rust/issues/130366 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_from_raw_parts", @@ -8572,6 +10662,9 @@ The tracking issue for this feature is: [#119206] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_from_utf16_endian", @@ -8583,6 +10676,9 @@ The tracking issue for this feature is: [#116258] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_internals", @@ -8592,6 +10688,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_lines_remainder", @@ -8603,6 +10702,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_inclusive_remainder", @@ -8614,6 +10716,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_remainder", @@ -8625,6 +10730,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "str_split_whitespace_remainder", @@ -8636,6 +10744,9 @@ The tracking issue for this feature is: [#77998] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "strict_overflow_ops", @@ -8647,24 +10758,40 @@ The tracking issue for this feature is: [#118260] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "strict_provenance_atomic_ptr", + description: r##"# `strict_provenance_atomic_ptr` + +The tracking issue for this feature is: [#99108] + +[#99108]: https://github.com/rust-lang/rust/issues/99108 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "strict_provenance", - description: r##"# `strict_provenance` + label: "strict_provenance_lints", + description: r##"# `strict_provenance_lints` The tracking issue for this feature is: [#95228] [#95228]: https://github.com/rust-lang/rust/issues/95228 ----- -The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints. +The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints. These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model. -The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`). ## Example ```rust -#![feature(strict_provenance)] +#![feature(strict_provenance_lints)] #![warn(fuzzy_provenance_casts)] fn main() { @@ -8673,17 +10800,9 @@ fn main() { } ``` "##, - }, - Lint { - label: "strict_provenance_atomic_ptr", - description: r##"# `strict_provenance_atomic_ptr` - -The tracking issue for this feature is: [#99108] - -[#99108]: https://github.com/rust-lang/rust/issues/99108 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_deref_patterns", @@ -8733,6 +10852,9 @@ pub fn is_it_the_answer(value: Value) -> bool { [its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_extend_from_within", @@ -8744,6 +10866,23 @@ The tracking issue for this feature is: [#103806] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "string_from_utf8_lossy_owned", + description: r##"# `string_from_utf8_lossy_owned` + +The tracking issue for this feature is: [#129436] + +[#129436]: https://github.com/rust-lang/rust/issues/129436 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "string_remove_matches", @@ -8755,6 +10894,9 @@ The tracking issue for this feature is: [#72826] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "structural_match", @@ -8766,6 +10908,23 @@ The tracking issue for this feature is: [#31434] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "substr_range", + description: r##"# `substr_range` + +The tracking issue for this feature is: [#126769] + +[#126769]: https://github.com/rust-lang/rust/issues/126769 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "sync_unsafe_cell", @@ -8777,6 +10936,9 @@ The tracking issue for this feature is: [#95439] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "target_feature_11", @@ -8788,6 +10950,9 @@ The tracking issue for this feature is: [#69098] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tbm_target_feature", @@ -8799,6 +10964,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_deferaccept", @@ -8810,6 +10978,9 @@ The tracking issue for this feature is: [#119639] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_linger", @@ -8821,6 +10992,9 @@ The tracking issue for this feature is: [#88494] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcp_quickack", @@ -8832,6 +11006,9 @@ The tracking issue for this feature is: [#96256] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tcplistener_into_incoming", @@ -8843,6 +11020,9 @@ The tracking issue for this feature is: [#88373] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test", @@ -9005,6 +11185,9 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured However, the optimizer can still modify a testcase in an undesirable manner even when using either of the above. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "test_unstable_lint", @@ -9014,6 +11197,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thin_box", @@ -9025,6 +11211,9 @@ The tracking issue for this feature is: [#92791] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_id_value", @@ -9036,6 +11225,9 @@ The tracking issue for this feature is: [#67939] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_local", @@ -9047,6 +11239,9 @@ The tracking issue for this feature is: [#29594] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_local_internals", @@ -9056,6 +11251,23 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "thread_raw", + description: r##"# `thread_raw` + +The tracking issue for this feature is: [#97523] + +[#97523]: https://github.com/rust-lang/rust/issues/97523 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "thread_sleep_until", @@ -9067,17 +11279,23 @@ The tracking issue for this feature is: [#113752] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "thread_spawn_unchecked", - description: r##"# `thread_spawn_unchecked` + label: "thread_spawn_hook", + description: r##"# `thread_spawn_hook` -The tracking issue for this feature is: [#55132] +The tracking issue for this feature is: [#132951] -[#55132]: https://github.com/rust-lang/rust/issues/55132 +[#132951]: https://github.com/rust-lang/rust/issues/132951 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trace_macros", @@ -9121,6 +11339,9 @@ note: trace_macro Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "track_path", @@ -9132,6 +11353,9 @@ The tracking issue for this feature is: [#99515] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trait_alias", @@ -9170,6 +11394,9 @@ pub fn main() { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trait_upcasting", @@ -9187,7 +11414,6 @@ so long as `Bar: Foo`. ```rust,edition2018 #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo {} @@ -9201,6 +11427,9 @@ let bar: &dyn Bar = &123; let foo: &dyn Foo = bar; ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transmutability", @@ -9212,6 +11441,9 @@ The tracking issue for this feature is: [#99571] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transmute_generic_consts", @@ -9223,6 +11455,9 @@ The tracking issue for this feature is: [#109929] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "transparent_unions", @@ -9310,6 +11545,9 @@ it is transparent). The Rust compiler is free to perform this optimization if possible, but is not required to, and different compiler versions may differ in their application of these optimizations. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trivial_bounds", @@ -9321,6 +11559,9 @@ The tracking issue for this feature is: [#48214] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_fused", @@ -9330,6 +11571,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_len", @@ -9341,6 +11585,9 @@ The tracking issue for this feature is: [#37572] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_len_next_unchecked", @@ -9352,6 +11599,9 @@ The tracking issue for this feature is: [#37572] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_random_access", @@ -9361,6 +11611,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "trusted_step", @@ -9372,6 +11625,9 @@ The tracking issue for this feature is: [#85731] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_blocks", @@ -9406,6 +11662,9 @@ let result: Result = try { assert!(result.is_err()); ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_find", @@ -9417,6 +11676,9 @@ The tracking issue for this feature is: [#63178] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_reserve_kind", @@ -9428,6 +11690,9 @@ The tracking issue for this feature is: [#48043] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2", @@ -9439,6 +11704,9 @@ The tracking issue for this feature is: [#84277] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2_residual", @@ -9450,6 +11718,9 @@ The tracking issue for this feature is: [#91285] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_trait_v2_yeet", @@ -9461,6 +11732,9 @@ The tracking issue for this feature is: [#96374] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "try_with_capacity", @@ -9472,6 +11746,9 @@ The tracking issue for this feature is: [#91913] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "tuple_trait", @@ -9481,6 +11758,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_alias_impl_trait", @@ -9492,6 +11772,9 @@ The tracking issue for this feature is: [#63063] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_ascription", @@ -9503,6 +11786,9 @@ The tracking issue for this feature is: [#23416] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "type_changing_struct_update", @@ -9540,6 +11826,9 @@ fn main () { } ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "ub_checks", @@ -9549,6 +11838,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "uefi_std", @@ -9560,6 +11852,23 @@ The tracking issue for this feature is: [#100499] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unbounded_shifts", + description: r##"# `unbounded_shifts` + +The tracking issue for this feature is: [#129375] + +[#129375]: https://github.com/rust-lang/rust/issues/129375 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unboxed_closures", @@ -9589,6 +11898,9 @@ extern "rust-call" fn add_args(args: (u32, u32)) -> u32 { fn main() {} ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unchecked_neg", @@ -9600,6 +11912,9 @@ The tracking issue for this feature is: [#85122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unchecked_shifts", @@ -9611,6 +11926,9 @@ The tracking issue for this feature is: [#85122] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unicode_internals", @@ -9620,6 +11938,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unique_rc_arc", @@ -9631,6 +11952,9 @@ The tracking issue for this feature is: [#112566] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_file_vectored_at", @@ -9642,6 +11966,9 @@ The tracking issue for this feature is: [#89517] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_set_mark", @@ -9653,6 +11980,9 @@ The tracking issue for this feature is: [#96467] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_socket_ancillary_data", @@ -9664,6 +11994,9 @@ The tracking issue for this feature is: [#76915] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unix_socket_peek", @@ -9675,59 +12008,89 @@ The tracking issue for this feature is: [#76923] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unnamed_fields", - description: r##"# `unnamed_fields` - -The tracking issue for this feature is: [#49804] + label: "unqualified_local_imports", + description: r##"# `unqualified_local_imports` -[#49804]: https://github.com/rust-lang/rust/issues/49804 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_attributes", - description: r##"# `unsafe_attributes` + label: "unsafe_fields", + description: r##"# `unsafe_fields` + +The tracking issue for this feature is: [#132922] -The tracking issue for this feature is: [#123757] +[#132922]: https://github.com/rust-lang/rust/issues/132922 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unsafe_pin_internals", + description: r##"# `unsafe_pin_internals` -[#123757]: https://github.com/rust-lang/rust/issues/123757 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_cell_from_mut", - description: r##"# `unsafe_cell_from_mut` + label: "unsigned_is_multiple_of", + description: r##"# `unsigned_is_multiple_of` -The tracking issue for this feature is: [#111645] +The tracking issue for this feature is: [#128101] -[#111645]: https://github.com/rust-lang/rust/issues/111645 +[#128101]: https://github.com/rust-lang/rust/issues/128101 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_extern_blocks", - description: r##"# `unsafe_extern_blocks` + label: "unsigned_nonzero_div_ceil", + description: r##"# `unsigned_nonzero_div_ceil` -The tracking issue for this feature is: [#123743] +The tracking issue for this feature is: [#132968] -[#123743]: https://github.com/rust-lang/rust/issues/123743 +[#132968]: https://github.com/rust-lang/rust/issues/132968 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "unsafe_pin_internals", - description: r##"# `unsafe_pin_internals` + label: "unsigned_signed_diff", + description: r##"# `unsigned_signed_diff` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +The tracking issue for this feature is: [#126041] + +[#126041]: https://github.com/rust-lang/rust/issues/126041 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsize", @@ -9739,6 +12102,9 @@ The tracking issue for this feature is: [#18598] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_const_params", @@ -9750,6 +12116,9 @@ The tracking issue for this feature is: [#95174] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_fn_params", @@ -9761,6 +12130,9 @@ The tracking issue for this feature is: [#48055] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_locals", @@ -9940,6 +12312,9 @@ fn main() { will unnecessarily extend the stack frame. "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unsized_tuple_coercion", @@ -9971,6 +12346,9 @@ fn main() { [RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "unwrap_infallible", @@ -9982,6 +12360,9 @@ The tracking issue for this feature is: [#61695] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "update_panic_count", @@ -9991,6 +12372,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "used_with_arg", @@ -10002,6 +12386,9 @@ The tracking issue for this feature is: [#93798] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "utf16_extra", @@ -10013,28 +12400,37 @@ The tracking issue for this feature is: [#94919] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "utf16_extra_const", - description: r##"# `utf16_extra_const` + label: "variant_count", + description: r##"# `variant_count` -The tracking issue for this feature is: [#94919] +The tracking issue for this feature is: [#73662] -[#94919]: https://github.com/rust-lang/rust/issues/94919 +[#73662]: https://github.com/rust-lang/rust/issues/73662 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { - label: "variant_count", - description: r##"# `variant_count` + label: "vec_deque_iter_as_slices", + description: r##"# `vec_deque_iter_as_slices` -The tracking issue for this feature is: [#73662] +The tracking issue for this feature is: [#123947] -[#73662]: https://github.com/rust-lang/rust/issues/73662 +[#123947]: https://github.com/rust-lang/rust/issues/123947 ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_into_raw_parts", @@ -10046,6 +12442,9 @@ The tracking issue for this feature is: [#65816] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_pop_if", @@ -10057,6 +12456,9 @@ The tracking issue for this feature is: [#122741] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_push_within_capacity", @@ -10068,6 +12470,9 @@ The tracking issue for this feature is: [#100486] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "vec_split_at_spare", @@ -10079,17 +12484,9 @@ The tracking issue for this feature is: [#81944] ------------------------ "##, - }, - Lint { - label: "waker_getters", - description: r##"# `waker_getters` - -The tracking issue for this feature is: [#96992] - -[#96992]: https://github.com/rust-lang/rust/issues/96992 - ------------------------- -"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wasi_ext", @@ -10101,6 +12498,9 @@ The tracking issue for this feature is: [#71213] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wasm_target_feature", @@ -10112,6 +12512,9 @@ The tracking issue for this feature is: [#44839] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_by_handle", @@ -10123,6 +12526,9 @@ The tracking issue for this feature is: [#63010] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_c", @@ -10132,6 +12538,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_change_time", @@ -10143,6 +12552,9 @@ The tracking issue for this feature is: [#121478] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_handle", @@ -10152,6 +12564,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_net", @@ -10161,6 +12576,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_exit_code_from", @@ -10172,6 +12590,9 @@ The tracking issue for this feature is: [#111688] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_async_pipes", @@ -10183,6 +12604,9 @@ The tracking issue for this feature is: [#98289] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_force_quotes", @@ -10194,6 +12618,9 @@ The tracking issue for this feature is: [#82227] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_main_thread_handle", @@ -10205,6 +12632,9 @@ The tracking issue for this feature is: [#96723] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_raw_attribute", @@ -10216,6 +12646,9 @@ The tracking issue for this feature is: [#114854] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_process_extensions_show_window", @@ -10227,6 +12660,9 @@ The tracking issue for this feature is: [#127544] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "windows_stdio", @@ -10236,6 +12672,9 @@ This feature is internal to the Rust compiler and is not intended for general us ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "with_negative_coherence", @@ -10245,6 +12684,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wrapping_int_impl", @@ -10256,6 +12698,9 @@ The tracking issue for this feature is: [#32463] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "wrapping_next_power_of_two", @@ -10267,6 +12712,9 @@ The tracking issue for this feature is: [#32463] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "write_all_vectored", @@ -10278,6 +12726,9 @@ The tracking issue for this feature is: [#70436] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "x86_amx_intrinsics", @@ -10289,6 +12740,9 @@ The tracking issue for this feature is: [#126622] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "xop_target_feature", @@ -10300,6 +12754,9 @@ The tracking issue for this feature is: [#127208] ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "yeet_desugar_details", @@ -10309,6 +12766,9 @@ This feature has no tracking issue, and is therefore likely internal to the comp ------------------------ "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "yeet_expr", @@ -10339,6 +12799,9 @@ fn bar() -> Option { assert_eq!(bar(), None); ``` "##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; @@ -10346,6 +12809,9 @@ pub const CLIPPY_LINTS: &[Lint] = &[ Lint { label: "clippy::absolute_paths", description: r##"Checks for usage of items through absolute paths, like `std::env::current_dir`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::absurd_extreme_comparisons", @@ -10353,10 +12819,16 @@ pub const CLIPPY_LINTS: &[Lint] = &[ either the minimum or maximum value for its type and warns if it involves a case that is always true or always false. Only integer and boolean types are checked."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::alloc_instead_of_core", description: r##"Finds items imported through `alloc` when available through `core`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::allow_attributes", @@ -10365,19 +12837,31 @@ the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reaso This lint only warns outer attributes (`#[allow]`), as inner attributes (`#![allow]`) are usually used to enable or disable lints on a global scale."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::allow_attributes_without_reason", description: r##"Checks for attributes that allow lints without a reason."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::almost_complete_range", description: r##"Checks for ranges which almost include the entire range of letters from 'a' to 'z' or digits from '0' to '9', but don't because they're a half open range."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::almost_swapped", description: r##"Checks for `foo = bar; bar = foo` sequences."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::approx_constant", @@ -10387,11 +12871,17 @@ constants which are defined in or [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), respectively, suggesting to use the predefined constant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::arc_with_non_send_sync", description: r##". This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::arithmetic_side_effects", @@ -10403,6 +12893,9 @@ or can panic (`/`, `%`). Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant environments, allowed types and non-constant operations that won't overflow are ignored."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_conversions", @@ -10415,54 +12908,90 @@ If you want more precise lints for `as`, please consider using these separate li `fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`. There is a good explanation the reason why this lint should work in this way and how it is useful [in this issue](https://github.com/rust-lang/rust-clippy/issues/5122)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_ptr_cast_mut", description: r##"Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::as_underscore", description: r##"Checks for the usage of `as _` conversion using inferred type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assertions_on_constants", description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assertions_on_result_states", description: r##"Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assign_op_pattern", description: r##"Checks for `a = a op b` or `a = b commutative_op a` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assign_ops", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::assigning_clones", description: r##"Checks for code like `foo = bar.clone();`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::async_yields_async", description: r##"Checks for async blocks that yield values of types that can themselves be awaited."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_invalid_type", description: r##"Allows users to configure types which should not be held across await suspension points."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_lock", description: r##"Checks for calls to `await` while holding a non-async-aware `MutexGuard`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::await_holding_refcell_ref", description: r##"Checks for calls to `await` while holding a `RefCell`, `Ref`, or `RefMut`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bad_bit_mask", @@ -10481,126 +13010,210 @@ table: |`==` or `!=`| `\\|` |`x \\| 1 == 0`|`false` |`c \\| m != c` | |`<` or `>=`| `\\|` |`x \\| 1 < 1` |`false` |`m >= c` | |`<=` or `>` | `\\|` |`x \\| 1 > 0` |`true` |`m > c` |"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::big_endian_bytes", description: r##"Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bind_instead_of_map", description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or `_.or_else(|x| Err(y))`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::blanket_clippy_restriction_lints", description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::blocks_in_conditions", description: r##"Checks for `if` and `match` conditions that use blocks containing an expression, statements or conditions that use closures with blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_assert_comparison", description: r##"This lint warns about boolean comparisons in assert-like macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_comparison", description: r##"Checks for expressions of the form `x == true`, `x != true` and order comparisons such as `x < true` (or vice versa) and suggest using the variable directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bool_to_int_with_if", description: r##"Instead of using an if statement to convert a bool to an int, this lint suggests using a `from()` function or an `as` coercion."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::borrow_as_ptr", description: r##"Checks for the usage of `&expr as *const T` or `&mut expr as *mut T`, and suggest using `ptr::addr_of` or `ptr::addr_of_mut` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::borrow_deref_ref", + description: r##"Checks for `&*(&T)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::borrow_deref_ref", description: r##"Checks for `&*(&T)`."## }, Lint { label: "clippy::borrow_interior_mutable_const", description: r##"Checks if `const` items which is interior mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::borrowed_box", description: r##"Checks for usage of `&Box` anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::box_collection", description: r##"Checks for usage of `Box` where T is a collection such as Vec anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::box_default", description: r##"checks for `Box::new(Default::default())`, which can be written as `Box::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::boxed_local", description: r##"Checks for usage of `Box` where an unboxed `T` would work fine."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::branches_sharing_code", description: r##"Checks if the `if` and `else` block contain shared code that can be moved out of the blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::builtin_type_shadow", description: r##"Warns if a generic shadows a built-in type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::byte_char_slices", description: r##"Checks for hard to read slices of byte characters, that could be more easily expressed as a byte string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bytes_count_to_len", description: r##"It checks for `str::bytes().count()` and suggests replacing it with `str::len()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::bytes_nth", description: r##"Checks for the use of `.bytes().nth()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cargo_common_metadata", description: r##"Checks to see if all common metadata is defined in `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::case_sensitive_file_extension_comparisons", description: r##"Checks for calls to `ends_with` with possible file extensions and suggests to use a case-insensitive approach instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_abs_to_unsigned", description: r##"Checks for usage of the `abs()` method that cast the result to unsigned."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_enum_constructor", description: r##"Checks for casts from an enum tuple constructor to an integer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_enum_truncation", description: r##"Checks for casts from an enum type to an integral type that will definitely truncate the value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_lossless", description: r##"Checks for casts between numeric types that can be replaced by safe conversion functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_nan_to_int", description: r##"Checks for a known NaN float being cast to an integer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_possible_truncation", @@ -10608,6 +13221,9 @@ conversion functions."##, truncate large values. This is expected behavior, so the cast is `Allow` by default. It suggests user either explicitly ignore the lint, or use `try_from()` and handle the truncation, default, or panic explicitly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_possible_wrap", @@ -10618,6 +13234,9 @@ changed at the bit level), and the binary representation of the value is reinterpreted. This can cause wrapping if the value is too big for the target signed type. However, the cast works as defined, so this lint is `Allow` by default."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_precision_loss", @@ -10628,11 +13247,17 @@ rounding errors. This possible rounding is to be expected, so this lint is Basically, this warns on casting any integer with 32 or more bits to `f32` or any 64-bit integer to `f64`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_ptr_alignment", description: r##"Checks for casts, using `as` or `pointer::cast`, from a less strictly aligned pointer to a more strictly aligned pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_sign_loss", @@ -10640,79 +13265,130 @@ less strictly aligned pointer to a more strictly aligned pointer."##, type. In this case, negative values wrap around to large positive values, which can be quite surprising in practice. However, since the cast works as defined, this lint is `Allow` by default."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_slice_different_sizes", description: r##"Checks for `as` casts between raw pointers to slices with differently sized elements."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cast_slice_from_raw_parts", description: r##"Checks for a raw slice being cast to a slice pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cfg_not_test", - description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#{cfg(not(test))]`)"##, + description: r##"Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::char_lit_as_u8", description: r##"Checks for expressions where a character literal is cast to `u8` and suggests using a byte literal instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::chars_last_cmp", description: r##"Checks for usage of `_.chars().last()` or `_.chars().next_back()` on a `str` to check if it ends with a given char."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::chars_next_cmp", description: r##"Checks for usage of `.chars().next()` on a `str` to check if it starts with a given char."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::checked_conversions", description: r##"Checks for explicit bounds checking when casting."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clear_with_drain", description: r##"Checks for usage of `.drain(..)` for the sole purpose of clearing a container."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clone_on_copy", description: r##"Checks for usage of `.clone()` on a `Copy` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::clone_on_ref_ptr", description: r##"Checks for usage of `.clone()` on a ref-counted pointer, (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified function syntax instead (e.g., `Rc::clone(foo)`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cloned_instead_of_copied", description: r##"Checks for usage of `cloned()` on an `Iterator` or `Option` where `copied()` could be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cmp_null", description: r##"This lint checks for equality comparisons with `ptr::null`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cmp_owned", description: r##"Checks for conversions to owned values just for the sake of a comparison."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::cognitive_complexity", description: r##"Checks for methods with high cognitive complexity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_else_if", description: r##"Checks for collapsible `else { if ... }` expressions that can be collapsed to `else if ...`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_if", description: r##"Checks for nested `if` statements which can be collapsed by `&&`-combining their conditions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_match", @@ -10721,73 +13397,121 @@ without adding any branches. Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only cases where merging would most likely make the code more readable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collapsible_str_replace", description: r##"Checks for consecutive calls to `str::replace` (2 or more) that can be collapsed into a single call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::collection_is_never_read", description: r##"Checks for collections that are never queried."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::comparison_chain", description: r##"Checks comparison chains written with `if` that can be rewritten with `match` and `cmp`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::comparison_to_empty", description: r##"Checks for comparing to an empty slice such as `` or `[]`, and suggests using `.is_empty()` where applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::const_is_empty", description: r##"It identifies calls to `.is_empty()` on constant values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::copy_iterator", description: r##"Checks for types that implement `Copy` as well as `Iterator`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::crate_in_macro_def", description: r##"Checks for usage of `crate` as opposed to `$crate` in a macro definition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::create_dir", description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::crosspointer_transmute", description: r##"Checks for transmutes between a type `T` and `*T`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::dbg_macro", description: r##"Checks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::debug_assert_with_mut_call", description: r##"Checks for function/method calls with a mutable parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::decimal_literal_representation", description: r##"Warns if there is a better representation for a numeric literal."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::declare_interior_mutable_const", description: r##"Checks for declaration of `const` items which is interior mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_constructed_unit_structs", description: r##"Checks for construction on unit struct using `default`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_instead_of_iter_empty", description: r##"It checks for `std::iter::Empty::default()` and suggests replacing it with `std::iter::empty()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_numeric_fallback", @@ -10799,58 +13523,94 @@ types at the end of type inference, then integer type is bound to `i32`, and sim floating type is bound to `f64`. See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_trait_access", description: r##"Checks for literal calls to `Default::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::default_union_representation", description: r##"Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_cfg_attr", description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it with `#[rustfmt::skip]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_clippy_cfg_attr", description: r##"Checks for `#[cfg_attr(feature = cargo-clippy, ...)]` and for `#[cfg(feature = cargo-clippy)]` and suggests to replace it with `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deprecated_semver", description: r##"Checks for `#[deprecated]` annotations with a `since` field that is not a valid semantic version. Also allows TBD to signal future deprecation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deref_addrof", description: r##"Checks for usage of `*&` and `*&mut` in expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::deref_by_slicing", description: r##"Checks for slicing expressions which are equivalent to dereferencing the value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derivable_impls", description: r##"Detects manual `std::default::Default` implementations that are identical to a derived implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derive_ord_xor_partial_ord", description: r##"Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord` or `PartialOrd` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derive_partial_eq_without_eq", description: r##"Checks for types that derive `PartialEq` and could implement `Eq`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::derived_hash_with_manual_eq", description: r##"Lints against manual `PartialEq` implementations for types with a derived `Hash` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_macros", @@ -10858,6 +13618,9 @@ implementation."##, Note: Even though this lint is warn-by-default, it will only trigger if macros are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_methods", @@ -10865,11 +13628,17 @@ macros are defined in the clippy.toml file."##, Note: Even though this lint is warn-by-default, it will only trigger if methods are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_names", description: r##"Checks for usage of disallowed names for variables, such as `foo`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_script_idents", @@ -10885,6 +13654,9 @@ See also: [`non_ascii_idents`]. [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::disallowed_types", @@ -10892,11 +13664,17 @@ See also: [`non_ascii_idents`]. Note: Even though this lint is warn-by-default, it will only trigger if types are defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::diverging_sub_expression", description: r##"Checks for diverging calls that are not match arms or statements."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_lazy_continuation", @@ -10904,34 +13682,55 @@ statements."##, paragraph nested within a list or block quote does not need any line after the first one to be indented or marked. The specification calls this a lazy paragraph continuation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_link_with_quotes", description: r##"Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks) outside of code blocks"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::doc_markdown", description: r##"Checks for the presence of `_`, `::` or camel-case words outside ticks in documentation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_comparisons", description: r##"Checks for double comparisons that could be simplified to a single expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_must_use", description: r##"Checks for a `#[must_use]` attribute without further information on functions and methods that return a type already marked as `#[must_use]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_neg", description: r##"Detects expressions of the form `--x`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::double_parens", description: r##"Checks for unnecessary double parentheses."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::drain_collect", @@ -10939,43 +13738,76 @@ marked as `#[must_use]`."##, > Collection in this context refers to any type with a `drain` method: > `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::drop_non_drop", description: r##"Checks for calls to `std::mem::drop` with a value that does not implement `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicate_mod", description: r##"Checks for files that are included as modules multiple times."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicate_underscore_argument", description: r##"Checks for function arguments having the similar names differing by an underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duplicated_attributes", description: r##"Checks for attributes that appear two or more times."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::duration_subsec", description: r##"Checks for calculation of subsecond microseconds or milliseconds from other `Duration` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::eager_transmute", description: r##"Checks for integer validity checks, followed by a transmute that is (incorrectly) evaluated eagerly (e.g. using `bool::then_some`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::else_if_without_else", description: r##"Checks for usage of if expressions with an `else if` branch, but without a final `else` branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::empty_docs", + description: r##"Detects documentation that is empty."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::empty_docs", description: r##"Detects documentation that is empty."## }, Lint { label: "clippy::empty_drop", description: r##"Checks for empty `Drop` implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_enum", @@ -10984,271 +13816,458 @@ but without a final `else` branch."##, As of this writing, the `never_type` is still a nightly-only experimental API. Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_enum_variants_with_brackets", description: r##"Finds enum variants without fields that are declared with empty brackets."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_line_after_doc_comments", - description: r##"Checks for empty lines after documentation comments."##, + description: r##"Checks for empty lines after doc comments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::empty_line_after_outer_attr", description: r##"Checks for empty lines after outer attributes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::empty_loop", + description: r##"Checks for empty `loop` expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::empty_loop", description: r##"Checks for empty `loop` expressions."## }, Lint { label: "clippy::empty_structs_with_brackets", description: r##"Finds structs without fields (a so-called empty struct) that are declared with brackets."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::enum_clike_unportable_variant", description: r##"Checks for C-like enumerations that are `repr(isize/usize)` and have values that don't fit into an `i32`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::enum_glob_use", + description: r##"Checks for `use Enum::*`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::enum_glob_use", description: r##"Checks for `use Enum::*`."## }, Lint { label: "clippy::enum_variant_names", description: r##"Detects enumeration variants that are prefixed or suffixed by the same characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::eq_op", description: r##"Checks for equal operands to comparison, logical and bitwise, difference and division binary operators (`==`, `>`, etc., `&&`, `||`, `&`, `|`, `^`, `-` and `/`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::equatable_if_let", description: r##"Checks for pattern matchings that can be expressed using equality."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::erasing_op", description: r##"Checks for erasing operations, e.g., `x * 0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::err_expect", description: r##"Checks for `.err().expect()` calls on the `Result` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::error_impl_error", description: r##"Checks for types named `Error` that implement `Error`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::excessive_nesting", description: r##"Checks for blocks which are nested beyond a certain threshold. Note: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::excessive_precision", description: r##"Checks for float literals with a precision greater than that supported by the underlying type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exhaustive_enums", description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exhaustive_structs", description: r##"Warns on any exported `struct`s that are not tagged `#[non_exhaustive]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::exit", description: r##"Detects calls to the `exit()` function which terminates the program."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expect_fun_call", description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, etc., and suggests to use `unwrap_or_else` instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expect_used", description: r##"Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::expl_impl_clone_on_copy", description: r##"Checks for explicit `Clone` implementations for `Copy` types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_auto_deref", description: r##"Checks for dereferencing expressions which would be covered by auto-deref."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_counter_loop", description: r##"Checks `for` loops over slices with an explicit counter and suggests the use of `.enumerate()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_deref_methods", description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_into_iter_loop", description: r##"Checks for loops on `y.into_iter()` where `y` will do, and suggests the latter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_iter_loop", description: r##"Checks for loops on `x.iter()` where `&x` will do, and suggests the latter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::explicit_write", description: r##"Checks for usage of `write!()` / `writeln()!` which can be replaced with `(e)print!()` / `(e)println!()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extend_from_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extend_with_drain", description: r##"Checks for occurrences where one vector gets extended instead of append"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extra_unused_lifetimes", description: r##"Checks for lifetimes in generics that are never used anywhere else."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::extra_unused_type_parameters", description: r##"Checks for type parameters in generics that are never used anywhere else."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fallible_impl_from", description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::field_reassign_with_default", description: r##"Checks for immediate reassignment of fields initialized with Default::default()."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::field_scoped_visibility_modifiers", description: r##"Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These make a field visible within a scope between public and private."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filetype_is_file", description: r##"Checks for `FileType::is_file()`."##, - }, - Lint { - label: "clippy::filter_map", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_bool_then", description: r##"Checks for usage of `bool::then` in `Iterator::filter_map`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_identity", description: r##"Checks for usage of `filter_map(|x| x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_map_next", description: r##"Checks for usage of `_.filter_map(_).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::filter_next", description: r##"Checks for usage of `_.filter(_).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::find_map", description: r##"Nothing. This lint has been deprecated."## }, Lint { label: "clippy::flat_map_identity", description: r##"Checks for usage of `flat_map(|x| x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::flat_map_option", description: r##"Checks for usage of `Iterator::flat_map()` where `filter_map()` could be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::float_arithmetic", + description: r##"Checks for float arithmetic."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::float_arithmetic", description: r##"Checks for float arithmetic."## }, Lint { label: "clippy::float_cmp", description: r##"Checks for (in-)equality comparisons on floating-point values (apart from zero), except in functions called `*eq*` (which probably implement equality for a type involving floats)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::float_cmp_const", description: r##"Checks for (in-)equality comparisons on constant floating-point values (apart from zero), except in functions called `*eq*` (which probably implement equality for a type involving floats)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::float_equality_without_abs", description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or `(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_address_comparisons", description: r##"Checks for comparisons with an address of a function item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_params_excessive_bools", description: r##"Checks for excessive use of bools in function definitions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast", description: r##"Checks for casts of function pointers to something other than `usize`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast_any", description: r##"Checks for casts of a function pointer to any integer type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::fn_to_numeric_cast_with_truncation", description: r##"Checks for casts of a function pointer to a numeric type not wide enough to store an address."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::for_kv_map", description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and ignoring either the keys or values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::forget_non_drop", description: r##"Checks for calls to `std::mem::forget` with a value that does not implement `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_collect", description: r##"Checks for usage of `.map(|_| format!(..)).collect::()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_in_format_args", description: r##"Detects `format!` within the arguments of another macro that does formatting such as `format!` itself, `write!` or `println!`. Suggests inlining the `format!` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::format_push_string", description: r##"Detects cases where the result of a `format!` call is appended to an existing `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::four_forward_slashes", description: r##"Checks for outer doc comments written with 4 forward slashes (`////`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_iter_instead_of_collect", description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator` trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_over_into", description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_raw_with_void_ptr", description: r##"Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::from_str_radix_10", description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::future_not_send", @@ -11256,60 +14275,92 @@ trait."##, functions and methods to implement the `Send` marker trait. It is mostly used by library authors (public and internal) that target an audience where multithreaded executors are likely to be used for running these Futures."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_first", description: r##"Checks for usage of `x.get(0)` instead of `x.first()` or `x.front()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_last_with_len", description: r##"Checks for usage of `x.get(x.len() - 1)` instead of `x.last()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::get_unwrap", description: r##"Checks for usage of `.get().unwrap()` (or `.get_mut().unwrap`) on a standard library type which implements `Index`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::host_endian_bytes", description: r##"Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::identity_op", description: r##"Checks for identity operations, e.g., `x + 0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_let_mutex", description: r##"Checks for `Mutex::lock` calls in `if let` expression with lock calls in any of the else blocks."##, - }, - Lint { - label: "clippy::if_let_redundant_pattern_matching", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_not_else", description: r##"Checks for usage of `!` or `!=` in an if condition with an else branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_same_then_else", description: r##"Checks for `if/else` with the same body as the *then* part and the *else* part."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::if_then_some_else_none", description: r##"Checks for if-else that could be written using either `bool::then` or `bool::then_some`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ifs_same_cond", description: r##"Checks for consecutive `if`s with the same condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ignored_unit_patterns", description: r##"Checks for usage of `_` in patterns of type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impl_hash_borrow_with_str_and_bytes", @@ -11317,32 +14368,53 @@ and the *else* part."##, type that implements all three of `Hash`, `Borrow` and `Borrow<[u8]>` as it is impossible to satisfy the semantics of Borrow and `Hash` for both `Borrow` and `Borrow<[u8]>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impl_trait_in_params", description: r##"Lints when `impl Trait` is being used in a function's parameters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_clone", description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_hasher", description: r##"Checks for public `impl` or `fn` missing generalization over different hashers and implicitly defaulting to the default hashing algorithm (`SipHash`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_return", description: r##"Checks for missing return statements at the end of a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_saturating_add", description: r##"Checks for implicit saturating addition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implicit_saturating_sub", description: r##"Checks for implicit saturating subtraction."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::implied_bounds_in_impls", @@ -11350,43 +14422,67 @@ algorithm (`SipHash`)."##, This can happen when a trait is specified that another trait already has as a supertrait (e.g. `fn() -> impl Deref + DerefMut` has an unnecessary `Deref` bound, because `Deref` is a supertrait of `DerefMut`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::impossible_comparisons", description: r##"Checks for double comparisons that can never succeed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::imprecise_flops", description: r##"Looks for floating-point expressions that can be expressed using built-in methods to improve accuracy at the cost of performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::incompatible_msrv", description: r##"This lint checks that no function newer than the defined MSRV (minimum supported rust version) is used in the crate."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inconsistent_digit_grouping", description: r##"Warns if an integral or floating-point constant is grouped inconsistently with underscores."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inconsistent_struct_constructor", description: r##"Checks for struct constructors where all fields are shorthand and the order of the field init shorthand in the constructor is inconsistent with the order in the struct definition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::index_refutable_slice", description: r##"The lint checks for slice bindings in patterns that are only used to access individual slice values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::indexing_slicing", description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint does report on arrays if we can tell that slicing operations are in bounds and does not lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ineffective_bit_mask", @@ -11398,241 +14494,417 @@ following table: |----------|----------|------------|-------| |`>` / `<=`|`\\|` / `^`|`x \\| 2 > 3`|`x > 3`| |`<` / `>=`|`\\|` / `^`|`x ^ 1 < 4` |`x < 4`|"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ineffective_open_options", description: r##"Checks if both `.write(true)` and `.append(true)` methods are called on a same `OpenOptions`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inefficient_to_string", description: r##"Checks for usage of `.to_string()` on an `&&T` where `T` implements `ToString` directly (like `&&str` or `&&String`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infallible_destructuring_match", description: r##"Checks for matches being used to destructure a single-variant enum or tuple struct where a `let` will suffice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infinite_iter", description: r##"Checks for iteration that is guaranteed to be infinite."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::infinite_loop", description: r##"Checks for infinite loops in a function where the return type is not `!` and lint accordingly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inherent_to_string", description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inherent_to_string_shadow_display", description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::init_numbered_fields", description: r##"Checks for tuple structs initialized with field syntax. It will however not lint if a base initializer is present. The lint will also ignore code in macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_always", description: r##"Checks for items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_asm_x86_att_syntax", description: r##"Checks for usage of AT&T x86 assembly syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_asm_x86_intel_syntax", description: r##"Checks for usage of Intel x86 assembly syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inline_fn_without_body", description: r##"Checks for `#[inline]` on trait methods without bodies"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::inspect_for_each", description: r##"Checks for usage of `inspect().for_each()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::int_plus_one", description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::integer_division", + description: r##"Checks for division of integers"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::integer_division", description: r##"Checks for division of integers"## }, Lint { label: "clippy::integer_division_remainder_used", description: r##"Checks for the usage of division (`/`) and remainder (`%`) operations when performed on any integer types using the default `Div` and `Rem` trait implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::into_iter_on_ref", description: r##"Checks for `into_iter` calls on references which should be replaced by `iter` or `iter_mut`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::into_iter_without_iter", description: r##"This is the opposite of the `iter_without_into_iter` lint. It looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method on the type or on any of the types in its `Deref` chain."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_null_ptr_usage", description: r##"This lint checks for invalid usages of `ptr::null`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_regex", description: r##"Checks [regex](https://crates.io/crates/regex) creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct regex syntax."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invalid_upcast_comparisons", description: r##"Checks for comparisons where the relation is always either true or false, but where one side has been upcast so that the comparison is necessary. Only integer types are checked."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::inverted_saturating_sub", + description: r##"Checks for comparisons between integers, followed by subtracting the greater value from the +lower one."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::invisible_characters", description: r##"Checks for invisible Unicode characters in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::is_digit_ascii_radix", description: r##"Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or [`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::items_after_statements", description: r##"Checks for items declared after some statement in a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::items_after_test_module", description: r##"Triggers if an item is declared after the testing module marked with `#[cfg(test)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_cloned_collect", description: r##"Checks for the use of `.cloned().collect()` on slice to create a `Vec`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_count", description: r##"Checks for the use of `.iter().count()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_filter_is_ok", description: r##"Checks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call. This lint will require additional changes to the follow-up calls as it affects the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_filter_is_some", description: r##"Checks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call. This lint will require additional changes to the follow-up calls as it affects the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_kv_map", description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and ignoring either the keys or values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::iter_next_loop", + description: r##"Checks for loops on `x.next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::iter_next_loop", description: r##"Checks for loops on `x.next()`."## }, Lint { label: "clippy::iter_next_slice", description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_not_returning_iterator", description: r##"Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_nth", description: r##"Checks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have equivalent `.get()`/`.get_mut()` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_nth_zero", description: r##"Checks for the use of `iter.nth(0)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_on_empty_collections", description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_on_single_items", description: r##"Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_out_of_bounds", description: r##"Looks for iterator combinator calls such as `.take(x)` or `.skip(x)` where `x` is greater than the amount of items that an iterator will produce."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_over_hash_type", description: r##"This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_overeager_cloned", description: r##"Checks for usage of `_.cloned().()` where call to `.cloned()` can be postponed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_skip_next", description: r##"Checks for usage of `.skip(x).next()` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_skip_zero", description: r##"Checks for usage of `.skip(0)` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_with_drain", description: r##"Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iter_without_into_iter", description: r##"Looks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::iterator_step_by_zero", description: r##"Checks for calling `.step_by(0)` on iterators which panics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::join_absolute_paths", description: r##"Checks for calls to `Path::join` that start with a path separator (`\\\\` or `/`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::just_underscores_and_digits", description: r##"Checks if you have variables whose name consists of just underscores and digits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_const_arrays", description: r##"Checks for large `const` arrays that should be defined as `static` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_digit_groups", description: r##"Warns if the digits of an integral or floating-point constant are grouped into groups that are too large."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_enum_variant", description: r##"Checks for large size differences between variants on `enum`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_futures", description: r##"It checks for the size of a `Future` created by `async fn` or `async {}`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_include_file", description: r##"Checks for the inclusion of large files via `include_bytes!()` or `include_str!()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_stack_arrays", description: r##"Checks for local arrays that may be too large."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_stack_frames", @@ -11643,6 +14915,9 @@ or constructing *many* smaller-but-still-large structs, or copying around a lot This lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays) that is intended to look at functions as a whole instead of only individual array expressions inside of a function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::large_types_passed_by_value", @@ -11651,60 +14926,102 @@ the argument type is `Copy` and large enough to be worth considering passing by reference. Does not trigger if the function is being exported, because that might induce API breakage, if the parameter is declared as mutable, or if the argument is a `self`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::legacy_numeric_constants", description: r##"Checks for usage of `::max_value()`, `std::::MAX`, `std::::EPSILON`, etc."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::len_without_is_empty", description: r##"Checks for items that implement `.len()` but not `.is_empty()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::len_zero", description: r##"Checks for getting the length of something via `.len()` just to compare to zero, and suggests using `.is_empty()` where applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_and_return", description: r##"Checks for `let`-bindings, which are subsequently returned."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_future", description: r##"Checks for `let _ = ` where the resulting type of expr implements `Future`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_lock", description: r##"Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in `parking_lot`. For `std` locks see the `rustc` lint [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_must_use", description: r##"Checks for `let _ = ` where expr is `#[must_use]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::let_underscore_untyped", description: r##"Checks for `let _ = ` without a type annotation, and suggests to either provide one, or remove the `let` keyword altogether."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::let_unit_value", + description: r##"Checks for binding a unit value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::let_unit_value", description: r##"Checks for binding a unit value."## }, Lint { label: "clippy::let_with_type_underscore", description: r##"Detects when a variable is declared with an explicit type of `_`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lines_filter_map_ok", description: r##"Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` when `lines` has type `std::io::Lines`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::linkedlist", description: r##"Checks for usage of any `LinkedList`, suggesting to use a `Vec` or a `VecDeque` (formerly called `RingBuf`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lint_groups_priority", @@ -11713,286 +15030,488 @@ when `lines` has type `std::io::Lines`."##, This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918) is resolved."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::little_endian_bytes", description: r##"Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::lossy_float_literal", description: r##"Checks for whole number float literals that cannot be represented as the underlying type without loss."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::macro_metavars_in_unsafe", description: r##"Looks for macros that expand metavariables in an unsafe block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::macro_use_imports", description: r##"Checks for `#[macro_use] use...`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::main_recursion", description: r##"Checks for recursion using the entrypoint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_assert", description: r##"Detects `if`-then-`panic!` that can be replaced with `assert!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_async_fn", description: r##"It checks for manual implementations of `async` functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_bits", description: r##"Checks for usage of `std::mem::size_of::() * 8` when `T::BITS` is available."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_c_str_literals", description: r##"Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()` on a (byte) string literal with a hardcoded `\\0` byte at the end."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_clamp", description: r##"Identifies good opportunities for a clamp function from std or core, and suggests using it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::manual_div_ceil", + description: r##"Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation +of `x.div_ceil(y)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_filter", description: r##"Checks for usage of `match` which could be implemented using `filter`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_filter_map", description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply as `filter_map(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_find", description: r##"Checks for manual implementations of Iterator::find"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_find_map", description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply as `find_map(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_flatten", description: r##"Checks for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the iterator element is used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_hash_one", description: r##"Checks for cases where [`BuildHasher::hash_one`] can be used. [`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_inspect", description: r##"Checks for uses of `map` which return the original item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_instant_elapsed", description: r##"Lints subtraction between `Instant::now()` and another `Instant`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_ascii_check", description: r##"Suggests to use dedicated built-in methods, `is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding ascii range"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_finite", description: r##"Checks for manual `is_finite` reimplementations (i.e., `x != ::INFINITY && x != ::NEG_INFINITY`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_infinite", description: r##"Checks for manual `is_infinite` reimplementations (i.e., `x == ::INFINITY || x == ::NEG_INFINITY`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::manual_is_power_of_two", + description: r##"Checks for expressions like `x.count_ones() == 1` or `x & (x - 1) == 0`, with x and unsigned integer, which are manual +reimplementations of `x.is_power_of_two()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_is_variant_and", description: r##"Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_let_else", description: r##"Warn of cases where `let...else` could be used"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_main_separator_str", description: r##"Checks for references on `std::path::MAIN_SEPARATOR.to_string()` used to build a `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_map", description: r##"Checks for usage of `match` which could be implemented using `map`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_memcpy", description: r##"Checks for for-loops that manually copy items between slices that could be optimized by having a memcpy."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_next_back", description: r##"Checks for `.rev().next()` on a `DoubleEndedIterator`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_non_exhaustive", description: r##"Checks for manual implementations of the non-exhaustive pattern."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_ok_or", description: r##"Finds patterns that reimplement `Option::ok_or`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_pattern_char_comparison", description: r##"Checks for manual `char` comparison in string patterns"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_range_contains", description: r##"Checks for expressions like `x >= 3 && x < 8` that could be more readably expressed as `(3..8).contains(x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_range_patterns", description: r##"Looks for combined OR patterns that are all contained in a specific range, e.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_rem_euclid", description: r##"Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation of `x.rem_euclid(4)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_retain", description: r##"Checks for code to be replaced by `.retain()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_rotate", description: r##"It detects manual bit rotations that could be rewritten using standard functions `rotate_left` or `rotate_right`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_saturating_arithmetic", description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_slice_size_calculation", description: r##"When `a` is `&[T]`, detect `a.len() * size_of::()` and suggest `size_of_val(a)` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_split_once", description: r##"Checks for usage of `str::splitn(2, _)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_str_repeat", description: r##"Checks for manual implementations of `str::repeat`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_string_new", description: r##"Checks for usage of `` to create a `String`, such as `.to_string()`, `.to_owned()`, `String::from()` and others."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_strip", description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using the pattern's length."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_swap", description: r##"Checks for manual swapping. Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_try_fold", description: r##"Checks for usage of `Iterator::fold` with a type that implements `Try`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_unwrap_or", description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_unwrap_or_default", description: r##"Checks if a `match` or `if let` expression can be simplified using `.unwrap_or_default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::manual_while_let_some", description: r##"Looks for loops that check for emptiness of a `Vec` in the condition and pop an element in the body as a separate operation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::many_single_char_names", description: r##"Checks for too many variables whose name consists of a single character."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_clone", description: r##"Checks for usage of `map(|x| x.clone())` or dereferencing closures for `Copy` types, on `Iterator` or `Option`, and suggests `cloned()` or `copied()` instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_collect_result_unit", description: r##"Checks for usage of `_.map(_).collect::()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_entry", description: r##"Checks for usage of `contains_key` + `insert` on `HashMap` or `BTreeMap`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_err_ignore", description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_flatten", description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_identity", description: r##"Checks for instances of `map(f)` where `f` is the identity function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::map_unwrap_or", description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or `result.map(_).unwrap_or_else(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_as_ref", description: r##"Checks for match which is used to add a reference to an `Option` value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_bool", description: r##"Checks for matches where match expression is a `bool`. It suggests to replace the expression with an `if...else` block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_like_matches_macro", description: r##"Checks for `match` or `if let` expressions producing a `bool` that could be written using `matches!`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_on_vec_items", description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_overlapping_arm", description: r##"Checks for overlapping match arms."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_ref_pats", description: r##"Checks for matches where all arms match a reference, suggesting to remove the reference and deref the matched expression instead. It also checks for `if let &foo = bar` blocks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_result_ok", description: r##"Checks for unnecessary `ok()` in `while let`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_same_arms", @@ -12000,51 +15519,77 @@ instead. It also checks for `if let &foo = bar` blocks."##, Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is enabled and disallowed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_single_binding", description: r##"Checks for useless match that binds to only one value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_str_case_mismatch", description: r##"Checks for `match` expressions modifying the case of a string with non-compliant arms"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_wild_err_arm", description: r##"Checks for arm which matches all errors with `Err(_)` and take drastic actions like `panic!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::match_wildcard_for_single_variants", description: r##"Checks for wildcard enum matches for a single variant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::maybe_infinite_iter", description: r##"Checks for iteration that may be infinite."##, - }, - Lint { - label: "clippy::maybe_misused_cfg", - description: r##"Nothing. This lint has been deprecated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_forget", description: r##"Checks for usage of `std::mem::forget(t)` where `t` is `Drop` or has a field that implements `Drop`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_option_with_none", description: r##"Checks for `mem::replace()` on an `Option` with `None`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_with_default", description: r##"Checks for `std::mem::replace` on a value of type `T` with `T::default()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mem_replace_with_uninit", description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())` and `mem::replace(&mut _, mem::zeroed())`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::min_ident_chars", @@ -12052,19 +15597,24 @@ and `mem::replace(&mut _, mem::zeroed())`."##, Note: This lint can be very noisy when enabled; it may be desirable to only enable it temporarily."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::min_max", description: r##"Checks for expressions where `std::cmp::min` and `max` are used to clamp values, but switched so that the result is constant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misaligned_transmute", - description: r##"Nothing. This lint has been deprecated."##, - }, - Lint { - label: "clippy::mismatched_target_os", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mismatching_type_param_order", @@ -12072,36 +15622,60 @@ used to clamp values, but switched so that the result is constant."##, a type definition and impl block. Specifically, a parameter in an impl block which has the same name as a parameter in the type def, but is in a different place."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misnamed_getters", description: r##"Checks for getter methods that return a field that doesn't correspond to the name of the method, when there is a field's whose name matches that of the method."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::misrefactored_assign_op", description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_assert_message", description: r##"Checks assertions without a custom panic message."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_asserts_for_indexing", description: r##"Checks for repeated slice indexing without asserting beforehand that the length is greater than the largest index used to index into the slice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_const_for_fn", description: r##"Suggests the use of `const` in functions and methods where possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_const_for_thread_local", description: r##"Suggests to use `const` in `thread_local!` macro if possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_docs_in_private_items", description: r##"Warns if there is missing documentation for any private documentable item."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_enforced_import_renames", @@ -12110,108 +15684,192 @@ in the `enforced-import-renames` config option. Note: Even though this lint is warn-by-default, it will only trigger if import renames are defined in the `clippy.toml` file."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_errors_doc", description: r##"Checks the doc comments of publicly visible functions that return a `Result` type and warns if there is no `# Errors` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_fields_in_debug", description: r##"Checks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_inline_in_public_items", description: r##"It lints if an exported function, method, trait method with default impl, or trait method impl is not `#[inline]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_panics_doc", description: r##"Checks the doc comments of publicly visible functions that may panic and warns if there is no `# Panics` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_safety_doc", description: r##"Checks for the doc comments of publicly visible unsafe functions and warns if there is no `# Safety` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::missing_spin_loop", + description: r##"Checks for empty spin loops"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::missing_spin_loop", description: r##"Checks for empty spin loops"## }, Lint { label: "clippy::missing_trait_methods", description: r##"Checks if a provided method is used implicitly by a trait implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::missing_transmute_annotations", description: r##"Checks if transmute calls have all generics specified."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mistyped_literal_suffixes", description: r##"Warns for mistyped suffix in literals"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_attributes_style", description: r##"Checks for items that have the same kind of attributes with mixed styles (inner/outer)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_case_hex_literals", description: r##"Warns on hexadecimal literals with mixed-case letter digits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mixed_read_write_in_expression", description: r##"Checks for a read and a write to the same variable where whether the read occurs before or after the write depends on the evaluation order of sub-expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mod_module_files", description: r##"Checks that module layout uses only self named module files; bans `mod.rs` files."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::module_inception", description: r##"Checks for modules that have the same name as their parent module"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::module_name_repetitions", description: r##"Detects type names that are prefixed or suffixed by the containing module's name."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::modulo_arithmetic", + description: r##"Checks for modulo arithmetic."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::modulo_arithmetic", description: r##"Checks for modulo arithmetic."## }, Lint { label: "clippy::modulo_one", description: r##"Checks for getting the remainder of integer division by one or minus one."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::multi_assignments", + description: r##"Checks for nested assignments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::multi_assignments", description: r##"Checks for nested assignments."## }, Lint { label: "clippy::multiple_bound_locations", description: r##"Check if a generic is defined both in the bound predicate and in the `where` clause."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_crate_versions", description: r##"Checks to see if multiple versions of a crate are being used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_inherent_impl", description: r##"Checks for multiple inherent implementations of a struct"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::multiple_unsafe_ops_per_block", description: r##"Checks for `unsafe` blocks that contain more than one unsafe operation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::must_use_candidate", description: r##"Checks for public functions that have no `#[must_use]` attribute, but return something not already marked must-use, have no mutable arg and mutate no statics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::must_use_unit", description: r##"Checks for a `#[must_use]` attribute on unit-returning functions and methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_from_ref", @@ -12221,77 +15879,131 @@ are multiple safe functions which will do this transformation To be on the conservative side, if there's at least one mutable reference with the output lifetime, this lint will not trigger."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_mut", description: r##"Checks for instances of `mut mut` references."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_mutex_lock", description: r##"Checks for `&mut Mutex::lock` calls"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mut_range_bound", description: r##"Checks for loops with a range bound that is a mutable variable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutable_key_type", description: r##"Checks for sets/maps with mutable key types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutex_atomic", description: r##"Checks for usage of `Mutex` where an atomic will do."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::mutex_integer", description: r##"Checks for usage of `Mutex` where `X` is an integral type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::naive_bytecount", + description: r##"Checks for naive byte counts"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::naive_bytecount", description: r##"Checks for naive byte counts"## }, Lint { label: "clippy::needless_arbitrary_self_type", description: r##"The lint checks for `self` in fn parameters that specify the `Self`-type explicitly"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bitwise_bool", description: r##"Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using a lazy and."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bool", description: r##"Checks for expressions of the form `if c { true } else { false }` (or vice versa) and suggests using the condition directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_bool_assign", description: r##"Checks for expressions of the form `if c { x = true } else { x = false }` (or vice versa) and suggest assigning the variable directly from the condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrow", description: r##"Checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrowed_reference", description: r##"Checks for bindings that needlessly destructure a reference and borrow the inner value with `&ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_borrows_for_generic_args", description: r##"Checks for borrow operations (`&`) that are used as a generic argument to a function when the borrowed value could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_character_iteration", description: r##"Checks if an iterator is used to check if a string is ascii."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_collect", description: r##"Checks for functions collecting an iterator when collect is not needed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_continue", @@ -12299,53 +16011,92 @@ is not needed."##, that contain a `continue` statement in either their main blocks or their `else`-blocks, when omitting the `else`-block possibly with some rearrangement of code can make the code easier to understand."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_doctest_main", description: r##"Checks for `fn main() { .. }` in doctests"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::needless_else", + description: r##"Checks for empty `else` branches."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::needless_else", description: r##"Checks for empty `else` branches."## }, Lint { label: "clippy::needless_for_each", description: r##"Checks for usage of `for_each` that would be more simply written as a `for` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_if", description: r##"Checks for empty `if` branches with no else branch."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_late_init", description: r##"Checks for late initializations that can be replaced by a `let` statement with an initializer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_lifetimes", description: r##"Checks for lifetime annotations which can be removed by relying on lifetime elision."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_match", description: r##"Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result` when function signatures are the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_maybe_sized", description: r##"Lints `?Sized` bounds applied to type parameters that cannot be unsized"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_option_as_deref", description: r##"Checks for no-op uses of `Option::{as_deref, as_deref_mut}`, for example, `Option<&T>::as_deref()` returns the same type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_option_take", description: r##"Checks for calling `take` function after `as_ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_parens_on_range_literals", description: r##"The lint checks for parenthesis on literals in range statements that are superfluous."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pass_by_ref_mut", @@ -12353,45 +16104,75 @@ superfluous."##, Be careful if the function is publicly reexported as it would break compatibility with users of this function, when the users pass this function as an argument."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pass_by_value", description: r##"Checks for functions taking arguments by value, but not consuming them in its body."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_pub_self", description: r##"Checks for usage of `pub(self)` and `pub(in self)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_question_mark", description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_range_loop", description: r##"Checks for looping over the range of `0..len` of some collection just to get the values by index."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_raw_string_hashes", description: r##"Checks for raw string literals with an unnecessary amount of hashes around them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_raw_strings", description: r##"Checks for raw string literals where a string literal can be used instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_return", description: r##"Checks for return statements at the end of a block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_return_with_question_mark", description: r##"Checks for return statements on `Err` paired with the `?` operator."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_splitn", description: r##"Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::needless_update", @@ -12400,70 +16181,118 @@ when all fields are changed anyway. This lint is not applied to structs marked with [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::neg_cmp_op_on_partial_ord", description: r##"Checks for the usage of negated comparison operators on types which only implement `PartialOrd` (e.g., `f64`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::neg_multiply", description: r##"Checks for multiplication by -1 as a form of negation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::negative_feature_names", description: r##"Checks for negative feature names with prefix `no-` or `not-`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::never_loop", description: r##"Checks for loops that will always `break`, `return` or `continue` an outer loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::new_ret_no_self", description: r##"Checks for `new` not returning a type that contains `Self`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::new_without_default", description: r##"Checks for public types with a `pub fn new() -> Self` method and no implementation of [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect", description: r##"Checks for statements which have no effect."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect_replace", description: r##"Checks for `replace` statements which have no effect."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_effect_underscore_binding", description: r##"Checks for binding to underscore prefixed variable without side-effects."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::no_mangle_with_rust_abi", description: r##"Checks for Rust ABI functions with the `#[no_mangle]` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_ascii_literal", description: r##"Checks for non-ASCII characters in string and char literals."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_canonical_clone_impl", description: r##"Checks for non-canonical implementations of `Clone` when `Copy` is already implemented."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_canonical_partial_ord_impl", description: r##"Checks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_minimal_cfg", description: r##"Checks for `any` and `all` combinators in `cfg` with only one condition."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_octal_unix_permissions", description: r##"Checks for non-octal values used to set Unix file permissions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::non_send_fields_in_send_ty", @@ -12472,63 +16301,116 @@ contains fields that are not safe to be sent across threads. It tries to detect fields that can cause a soundness issue when sent to another thread (e.g., `Rc`) while allowing `!Send` fields that are expected to exist in a `Send` type, such as raw pointers."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::non_zero_suggestions", + description: r##"Checks for conversions from `NonZero` types to regular integer types, +and suggests using `NonZero` types for the target as well."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonminimal_bool", description: r##"Checks for boolean expressions that can be written more concisely."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonsensical_open_options", description: r##"Checks for duplicate open options as well as combinations that make no sense."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::nonstandard_macro_braces", description: r##"Checks that common macros are used with consistent bracing."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::not_unsafe_ptr_arg_deref", description: r##"Checks for public functions that dereference raw pointer arguments but are not marked `unsafe`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::obfuscated_if_else", description: r##"Checks for usage of `.then_some(..).unwrap_or(..)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::octal_escapes", description: r##"Checks for `\\0` escapes in string and byte literals that look like octal character escapes in C."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ok_expect", + description: r##"Checks for usage of `ok().expect(..)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::ok_expect", description: r##"Checks for usage of `ok().expect(..)`."## }, Lint { label: "clippy::only_used_in_recursion", description: r##"Checks for arguments that are only used in recursion with no side-effects."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::op_ref", description: r##"Checks for arguments to `==` which have their address taken to satisfy a bound and suggests to dereference the other argument instead"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_as_ref_cloned", description: r##"Checks for usage of `.as_ref().cloned()` and `.as_mut().cloned()` on `Option`s"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_as_ref_deref", description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_env_unwrap", description: r##"Checks for usage of `option_env!(...).unwrap()` and suggests usage of the `env!` macro."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_filter_map", description: r##"Checks for iterators of `Option`s using `.filter(Option::is_some).map(Option::unwrap)` that may be replaced with a `.flatten()` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_if_let_else", @@ -12537,24 +16419,39 @@ be replaced with a `.flatten()` call."##, idiomatically done with `Option::map_or` (if the else bit is a pure expression) or `Option::map_or_else` (if the else bit is an impure expression)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_or_err_ok", description: r##"Checks for usage of `_.map_or(Err(_), Ok)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_or_none", description: r##"Checks for usage of `_.map_or(None, _)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_map_unit_fn", description: r##"Checks for usage of `option.map(f)` where f is a function or closure that returns the unit type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::option_option", description: r##"Checks for usage of `Option>` in function signatures and type definitions"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::or_fun_call", @@ -12562,52 +16459,91 @@ definitions"##, `.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`, `.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()` etc. instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::or_then_unwrap", description: r##"Checks for `.or(…).unwrap()` calls to Options and Results."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::out_of_bounds_indexing", description: r##"Checks for out of bounds array indexing with a constant index."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::overly_complex_bool_expr", description: r##"Checks for boolean expressions that contain terminals that can be eliminated."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::panic", + description: r##"Checks for usage of `panic!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## }, Lint { label: "clippy::panic_in_result_fn", description: r##"Checks for usage of `panic!` or assertions in a function whose return type is `Result`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::panicking_overflow_checks", description: r##"Detects C-style underflow/overflow checks."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::panicking_unwrap", description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partial_pub_fields", description: r##"Checks whether some but not all fields of a `struct` are public. Either make all fields of a type public, or make none of them public"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partialeq_ne_impl", description: r##"Checks for manual re-implementations of `PartialEq::ne`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::partialeq_to_none", description: r##"Checks for binary comparisons to a literal `Option::None`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::path_buf_push_overwrite", description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push) calls on `PathBuf` that can cause overwrites."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::path_ends_with_ext", @@ -12617,10 +16553,16 @@ By default, Clippy has a short list of known filenames that start with a dot but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default. The `allowed-dotfiles` configuration can be used to allow additional file extensions that Clippy should not lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pathbuf_init_then_push", description: r##"Checks for calls to `push` immediately after creating a new `PathBuf`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pattern_type_mismatch", @@ -12642,90 +16584,157 @@ and reference semantics in your code. The available tooling would expose these t in a general way even outside of the various pattern matching mechanics. Of course this lint can still be used to highlight areas of interest and ensure a good understanding of ownership semantics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::permissions_set_readonly_false", description: r##"Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::pointers_in_nomem_asm_block", + description: r##"Checks if any pointer is being passed to an asm! block with `nomem` option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::possible_missing_comma", description: r##"Checks for possible missing comma in an array. It lints if an array element is a binary operator expression and it lies on two lines."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::precedence", description: r##"Checks for operations where precedence may be unclear and suggests to add parentheses. Currently it catches the following: * mixed usage of arithmetic and bit shifting/combining operators without -parentheses -* a negative numeric literal (which is really a unary `-` followed by a -numeric literal) - followed by a method call"##, +parentheses"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_in_format_impl", description: r##"Checks for usage of `println`, `print`, `eprintln` or `eprint` in an implementation of a formatting trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_literal", description: r##"This lint warns about the use of literals as `print!`/`println!` args."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_stderr", description: r##"Checks for printing on *stderr*. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_stdout", description: r##"Checks for printing on *stdout*. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::print_with_newline", description: r##"This lint warns when you use `print!()` with a format string that ends in a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::println_empty_string", description: r##"This lint warns when you use `println!()` to print a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_arg", description: r##"This lint checks for function arguments of type `&String`, `&Vec`, `&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()` calls."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_as_ptr", description: r##"Checks for `as` casts between raw pointers that don't change their constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ptr_cast_constness", description: r##"Checks for `as` casts between raw pointers that change their constness, namely `*const T` to `*mut T` and `*mut T` to `*const T`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ptr_eq", + description: r##"Use `std::ptr::eq` when applicable"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::ptr_eq", description: r##"Use `std::ptr::eq` when applicable"## }, Lint { label: "clippy::ptr_offset_with_cast", description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an `isize`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_enum_variant_names", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_underscore_fields", description: r##"Checks whether any field of the struct is prefixed with an `_` (underscore) and also marked `pub` (public)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::pub_use", + description: r##"Restricts the usage of `pub use ...`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::pub_use", description: r##"Restricts the usage of `pub use ...`"## }, Lint { label: "clippy::pub_with_shorthand", description: r##"Checks for usage of `pub()` with `in`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::pub_without_shorthand", @@ -12733,180 +16742,310 @@ constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`."##, Note: As you cannot write a module's path in `pub()`, this will only trigger on `pub(super)` and the like."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::question_mark", description: r##"Checks for expressions that could be replaced by the question mark operator."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::question_mark_used", description: r##"Checks for expressions that use the question mark operator and rejects them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_minus_one", description: r##"Checks for inclusive ranges where 1 is subtracted from the upper bound, e.g., `x..=(y-1)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_plus_one", description: r##"Checks for exclusive ranges where 1 is added to the upper bound, e.g., `x..(y+1)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_step_by_zero", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::range_zip_with_len", description: r##"Checks for zipping a collection with the range of `0.._.len()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rc_buffer", description: r##"Checks for `Rc` and `Arc` when `T` is a mutable buffer type such as `String` or `Vec`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rc_clone_in_vec_init", description: r##"Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`) in `vec![elem; len]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::rc_mutex", + description: r##"Checks for `Rc>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::rc_mutex", description: r##"Checks for `Rc>`."## }, Lint { label: "clippy::read_line_without_trim", description: r##"Looks for calls to [`Stdin::read_line`] to read a line from the standard input into a string, then later attempting to use that string for an operation that will never work for strings with a trailing newline character in it (e.g. parsing into a `i32`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::read_zero_byte_vec", description: r##"This lint catches reads into a zero-length `Vec`. Especially in the case of a call to `with_capacity`, this lint warns that read gets the number of bytes from the `Vec`'s length, not its capacity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::readonly_write_lock", description: r##"Looks for calls to `RwLock::write` where the lock is only used for reading."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::recursive_format_impl", description: r##"Checks for format trait implementations (e.g. `Display`) with a recursive call to itself which uses `self` as a parameter. This is typically done indirectly with the `write!` macro or with `to_string()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_allocation", description: r##"Checks for usage of redundant allocations anywhere in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_as_str", description: r##"Checks for usage of `as_str()` on a `String` chained with a method available on the `String` itself."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_async_block", description: r##"Checks for `async` block that only returns `await` on a future."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_at_rest_pattern", description: r##"Checks for `[all @ ..]` patterns."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_clone", description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned value that is going to be dropped without further use."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure", description: r##"Checks for closures which just call another function where the function can be called directly. `unsafe` functions, calls where types get adjusted or where the callee is marked `#[track_caller]` are ignored."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure_call", description: r##"Detects closures called in the same expression where they are defined."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_closure_for_method_calls", description: r##"Checks for closures which only invoke a method on the closure argument and can be replaced by referencing the method directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_comparisons", description: r##"Checks for ineffective double comparisons against constants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_else", description: r##"Checks for `else` blocks that can be removed without changing semantics."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_feature_names", description: r##"Checks for feature names with prefix `use-`, `with-` or suffix `-support`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_field_names", description: r##"Checks for fields in struct literals where shorthands could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_guards", description: r##"Checks for unnecessary guards in match expressions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_locals", description: r##"Checks for redundant redefinitions of local bindings."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pattern", description: r##"Checks for patterns in the form `name @ _`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pattern_matching", description: r##"Lint for redundant pattern matching over `Result`, `Option`, `std::task::Poll`, `std::net::IpAddr` or `bool`s"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_pub_crate", description: r##"Checks for items declared `pub(crate)` that are not crate visible because they are inside a private module."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_slicing", description: r##"Checks for redundant slicing expressions which use the full range, and do not change the type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_static_lifetimes", description: r##"Checks for constants and statics with an explicit `'static` lifetime."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::redundant_type_annotations", description: r##"Warns about needless / redundant type annotations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_as_ptr", description: r##"Checks for casts of references to pointer using `as` and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_binding_to_reference", description: r##"Checks for `ref` bindings which create a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::ref_option", + description: r##"Warns when a function signature uses `&Option` instead of `Option<&T>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_option_ref", description: r##"Checks for usage of `&Option<&T>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::ref_patterns", description: r##"Checks for usages of the `ref` keyword."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::regex_macro", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::renamed_function_params", description: r##"Lints when the name of function parameters from trait impl is different than its default implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::repeat_once", @@ -12917,152 +17056,248 @@ different than its default implementation."##, The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::repeat_vec_with_capacity", description: r##"Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::replace_consts", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::reserve_after_initialization", description: r##"Informs the user about a more concise way to create a vector with a known capacity."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::rest_pat_in_fully_bound_structs", description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_filter_map", description: r##"Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may be replaced with a `.flatten()` call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_large_err", description: r##"Checks for functions that return `Result` with an unusually large `Err`-variant."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_map_or_into_option", description: r##"Checks for usage of `_.map_or(None, Some)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_map_unit_fn", description: r##"Checks for usage of `result.map(f)` where f is a function or closure that returns the unit type `()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::result_unit_err", description: r##"Checks for public functions that return a `Result` with an `Err` type of `()`. It suggests using a custom type that implements `std::error::Error`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::return_self_not_must_use", description: r##"This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::reversed_empty_ranges", description: r##"Checks for range expressions `x..y` where both `x` and `y` are constant and `x` is greater to `y`. Also triggers if `x` is equal to `y` when they are conditions to a `for` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_functions_in_if_condition", description: r##"Checks for consecutive `if`s with the same function call."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_item_push", description: r##"Checks whether a for loop is being used to push a constant value into a Vec."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::same_name_method", description: r##"It lints if a struct has two methods with the same name: one from a trait, another not from a trait."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::search_is_some", description: r##"Checks for an iterator or string search (such as `find()`, `position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::seek_from_current", description: r##"Checks if the `seek` method of the `Seek` trait is called with `SeekFrom::Current(0)`, and if it is, suggests using `stream_position` instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::seek_to_start_instead_of_rewind", description: r##"Checks for jumps to the start of a stream that implements `Seek` and uses the `seek` method providing `Start` as parameter."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_assignment", description: r##"Checks for explicit self-assignments."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_named_constructors", description: r##"Warns when constructors have the same name as their types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::self_named_module_files", description: r##"Checks that module layout uses only `mod.rs` files."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_if_nothing_returned", description: r##"Looks for blocks of expressions and fires if the last expression returns `()` but is not followed by a semicolon."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_inside_block", description: r##"Suggests moving the semicolon after a block to the inside of the block, after its last expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::semicolon_outside_block", description: r##"Suggests moving the semicolon from a block's final expression outside of the block."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::separated_literal_suffix", description: r##"Warns if literal suffixes are separated by an underscore. To enforce separated literal suffix style, see the `unseparated_literal_suffix` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::serde_api_misuse", description: r##"Checks for misuses of the serde API."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::set_contains_or_insert", - description: r##"Checks for usage of `contains` to see if a value is not -present on `HashSet` followed by a `insert`."##, + description: r##"Checks for usage of `contains` to see if a value is not present +in a set like `HashSet` or `BTreeSet`, followed by an `insert`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_reuse", description: r##"Checks for bindings that shadow other bindings already in scope, while reusing the original value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_same", description: r##"Checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::shadow_unrelated", description: r##"Checks for bindings that shadow other bindings already in scope, either without an initialization or with one that does not even use the original value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::short_circuit_statement", description: r##"Checks for the use of short circuit boolean conditions as a statement."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_assert_eq", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_implement_trait", @@ -13070,21 +17305,33 @@ statement."##, implementation of a `std` trait (see [llogiq's blog post](http://llogiq.github.io/2015/07/30/traits.html) for further information) instead of an inherent implementation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::should_panic_without_expect", description: r##"Checks for `#[should_panic]` attributes without specifying the expected panic message."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::significant_drop_in_scrutinee", description: r##"Checks for temporaries returned from function calls in a match scrutinee that have the `clippy::has_significant_drop` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::significant_drop_tightening", description: r##"Searches for elements marked with `#[clippy::has_significant_drop]` that could be early dropped but are in fact dropped at the end of their scopes. In other words, enforces the tightening of their possible lifetimes."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::similar_names", @@ -13093,33 +17340,54 @@ tightening of their possible lifetimes."##, Note: this lint looks for similar names throughout each scope. To allow it, you need to allow it on the scope level, not on the name that is reported."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_call_fn", description: r##"Checks for functions that are only used once. Does not lint tests."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_add_str", description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal where `push`/`insert` with a `char` would work fine."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_lifetime_names", description: r##"Checks for lifetimes with names which are one character long."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_char_pattern", description: r##"Checks for string methods that receive a single-character `str` as an argument, e.g., `_.split(x)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_component_path_imports", description: r##"Checking for imports with single component use path."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_element_loop", description: r##"Checks whether a for loop has a single element."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_match", @@ -13130,337 +17398,572 @@ This intentionally does not lint if there are comments inside of the other arm, so as to allow the user to document why having another explicit pattern with an empty body is necessary, or because the comments need to be preserved for other reasons."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_match_else", description: r##"Checks for matches with two arms where an `if let else` will usually suffice."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::single_range_in_vec_init", description: r##"Checks for `Vec` or array initializations that contain only one range."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::size_of_in_element_count", description: r##"Detects expressions where `size_of::` or `size_of_val::` is used as a count of elements of type `T`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::size_of_ref", description: r##"Checks for calls to `std::mem::size_of_val()` where the argument is a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::skip_while_next", description: r##"Checks for usage of `_.skip_while(condition).next()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::slow_vector_initialization", description: r##"Checks slow zero-filled vector initialization"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::stable_sort_primitive", description: r##"When sorting primitive values (integers, bools, chars, as well as arrays, slices, and tuples of such items), it is typically better to use an unstable sort than a stable sort."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::std_instead_of_alloc", description: r##"Finds items imported through `std` when available through `alloc`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::std_instead_of_core", description: r##"Finds items imported through `std` when available through `core`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::str_split_at_newline", description: r##"Checks for usages of `str.trim().split(\ )` and `str.trim().split(\\ )`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::str_to_string", description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_add", description: r##"Checks for all instances of `x + _` where `x` is of type `String`, but only if [`string_add_assign`](#string_add_assign) does *not* match."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_add_assign", description: r##"Checks for string appends of the form `x = x + y` (without `let`!)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_extend_chars", description: r##"Checks for the use of `.extend(s.chars())` where s is a `&str` or `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_from_utf8_as_bytes", description: r##"Check if the string is transformed to byte array and casted back to string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_lit_as_bytes", description: r##"Checks for the `as_bytes` method called on string literals that contain only ASCII characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_lit_chars_any", description: r##"Checks for `.chars().any(|i| i == c)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_slice", description: r##"Checks for slice operations on strings"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::string_to_string", description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::strlen_on_c_strings", description: r##"Checks for usage of `libc::strlen` on a `CString` or `CStr` value, and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::struct_excessive_bools", description: r##"Checks for excessive use of bools in structs."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::struct_field_names", description: r##"Detects struct fields that are prefixed or suffixed by the same characters or the name of the struct itself."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suboptimal_flops", description: r##"Looks for floating-point expressions that can be expressed using built-in methods to improve both accuracy and performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_arithmetic_impl", description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g. subtracting elements in an Add impl."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_assignment_formatting", description: r##"Checks for usage of the non-existent `=*`, `=!` and `=-` operators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_command_arg_space", description: r##"Checks for `Command::arg()` invocations that look like they should be multiple arguments instead, such as `arg(-t ext2)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_doc_comments", description: r##"Detects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_else_formatting", description: r##"Checks for formatting of `else`. It lints if the `else` is followed immediately by a newline or the `else` seems to be missing."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_map", description: r##"Checks for calls to `map` followed by a `count`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_op_assign_impl", description: r##"Lints for suspicious operations in impls of OpAssign, e.g. subtracting elements in an AddAssign impl."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_open_options", description: r##"Checks for the suspicious use of `OpenOptions::create()` without an explicit `OpenOptions::truncate()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_operation_groupings", description: r##"Checks for unlikely usages of binary operators that are almost certainly typos and/or copy/paste errors, given the other usages of binary operators nearby."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_splitn", description: r##"Checks for calls to [`splitn`] (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and related functions with either zero or one splits."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_to_owned", description: r##"Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_unary_op_formatting", description: r##"Checks the formatting of a unary operator on the right hand side of a binary operator. It lints if there is no space between the binary and unary operators, but there is a space between the unary and its operand."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::suspicious_xor_used_as_pow", description: r##"Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::swap_ptr_to_ref", description: r##"Checks for calls to `core::mem::swap` where either parameter is derived from a pointer"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::tabs_in_doc_comments", description: r##"Checks doc comments for usage of tab characters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::temporary_assignment", description: r##"Checks for construction of a structure or tuple just to assign a value in it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::test_attr_in_doctest", description: r##"Checks for `#[test]` in doctests unless they are marked with either `ignore`, `no_run` or `compile_fail`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::tests_outside_test_module", description: r##"Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module (marked with `#[cfg(test)]`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_digit_is_some", description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_string_in_format_args", description: r##"Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string) applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html) in a macro that does formatting."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::to_string_trait_impl", description: r##"Checks for direct implementations of `ToString`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::todo", + description: r##"Checks for usage of `todo!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::too_long_first_doc_paragraph", + description: r##"Checks if the first line in the documentation of items listed in module page is too long."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## }, Lint { label: "clippy::too_many_arguments", description: r##"Checks for functions with too many parameters."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::too_many_lines", description: r##"Checks for functions with a large amount of lines."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::toplevel_ref_arg", description: r##"Checks for function arguments and let bindings denoted as `ref`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trailing_empty_array", description: r##"Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trait_duplication_in_bounds", description: r##"Checks for cases where generics or trait objects are being used and multiple syntax specifications for trait bounds are used simultaneously."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_bytes_to_str", description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_float_to_int", description: r##"Checks for transmutes from a float to an integer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_bool", description: r##"Checks for transmutes from an integer to a `bool`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_char", description: r##"Checks for transmutes from an integer to a `char`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_float", description: r##"Checks for transmutes from an integer to a float."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_int_to_non_zero", description: r##"Checks for transmutes from `T` to `NonZero`, and suggests the `new_unchecked` method instead."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_null_to_fn", description: r##"Checks for null function pointer creation through transmute."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_num_to_bytes", description: r##"Checks for transmutes from a number to an array of `u8`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_ptr_to_ptr", description: r##"Checks for transmutes from a pointer to a pointer, or from a reference to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_ptr_to_ref", description: r##"Checks for transmutes from a pointer to a reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmute_undefined_repr", description: r##"Checks for transmutes between types which do not have a representation defined relative to each other."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmutes_expressible_as_ptr_casts", description: r##"Checks for transmutes that could be a pointer cast."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::transmuting_null", description: r##"Checks for transmute calls which would receive a null pointer."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trim_split_whitespace", description: r##"Warns about calling `str::trim` (or variants) before `str::split_whitespace`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trivial_regex", description: r##"Checks for trivial [regex](https://crates.io/crates/regex) creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::trivially_copy_pass_by_ref", description: r##"Checks for functions taking arguments by reference, where the argument type is `Copy` and small enough to be more efficient to always pass by value."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::try_err", + description: r##"Checks for usage of `Err(x)?`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::try_err", description: r##"Checks for usage of `Err(x)?`."## }, Lint { label: "clippy::tuple_array_conversions", description: r##"Checks for tuple<=>array conversions that are not done with `.into()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_complexity", description: r##"Checks for types used in structs, parameters and `let` declarations above a certain complexity threshold."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_id_on_box", description: r##"Looks for calls to `.type_id()` on a `Box`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::type_repetition_in_bounds", description: r##"This lint warns about unnecessary type repetitions in trait bounds"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unchecked_duration_subtraction", description: r##"Lints subtraction between an `Instant` and a `Duration`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unconditional_recursion", description: r##"Checks that there isn't an infinite recursion in trait implementations."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::undocumented_unsafe_blocks", @@ -13485,53 +17988,89 @@ foo( /* SAFETY: Neither is this */ unsafe { *x }, ); ```"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unicode_not_nfc", description: r##"Checks for string literals that contain Unicode in a form that is not equal to its [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unimplemented", description: r##"Checks for usage of `unimplemented!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninhabited_references", description: r##"It detects references to uninhabited types, such as `!` and warns when those are either dereferenced or returned from a function."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninit_assumed_init", description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninit_vec", description: r##"Checks for `set_len()` call that creates `Vec` with uninitialized elements. This is commonly caused by calling `set_len()` right after allocating or reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::uninlined_format_args", description: r##"Detect when a variable is not inlined in a format string, and suggests to inline it."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unit_arg", description: r##"Checks for passing a unit value as an argument to a function without using a unit literal (`()`)."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unit_cmp", description: r##"Checks for comparisons to unit. This includes all binary comparisons (like `==` and `<`) and asserts."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unit_hash", + description: r##"Detects `().hash(_)`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::unit_hash", description: r##"Detects `().hash(_)`."## }, Lint { label: "clippy::unit_return_expecting_ord", description: r##"Checks for functions that expect closures of type Fn(...) -> Ord where the implemented closure returns the unit type. The lint also suggests to remove the semi-colon at the end of the statement if present."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_box_returns", @@ -13539,48 +18078,83 @@ The lint also suggests to remove the semi-colon at the end of the statement if p The lint ignores `Box` where `T` is larger than `unnecessary_box_size`, as returning a large `T` directly may be detrimental to performance."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_cast", description: r##"Checks for casts to the same type, casts of int literals to integer types, casts of float literals to float types, and casts between raw pointers that don't change type or constness."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_clippy_cfg", description: r##"Checks for `#[cfg_attr(clippy, allow(clippy::lint))]` and suggests to replace it with `#[allow(clippy::lint)]`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_fallible_conversions", description: r##"Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts could be used."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_filter_map", description: r##"Checks for `filter_map` calls that could be replaced by `filter` or `map`. More specifically it checks if the closure provided is only performing one of the filter or map operations and suggests the appropriate option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_find_map", description: r##"Checks for `find_map` calls that could be replaced by `find` or `map`. More specifically it checks if the closure provided is only performing one of the find or map operations and suggests the appropriate option."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unnecessary_first_then_check", + description: r##"Checks the usage of `.first().is_some()` or `.first().is_none()` to check if a slice is +empty."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_fold", description: r##"Checks for usage of `fold` when a more succinct alternative exists. Specifically, this checks for `fold`s which could be replaced by `any`, `all`, `sum` or `product`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_get_then_check", description: r##"Checks the usage of `.get().is_some()` or `.get().is_none()` on std map types."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_join", description: r##"Checks for usage of `.collect::>().join()` on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_lazy_evaluations", @@ -13595,80 +18169,131 @@ simpler code: - `get_or_insert_with` to `get_or_insert` - `ok_or_else` to `ok_or` - `then` to `then_some` (for msrv >= 1.62.0)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_literal_unwrap", description: r##"Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_map_on_constructor", description: r##"Suggests removing the use of a `map()` (or `map_err()`) method when an `Option` or `Result` is being constructed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_min_or_max", description: r##"Checks for unnecessary calls to `min()` or `max()` in the following cases - Either both side is constant - One side is clearly larger than the other, like i32::MIN and an i32 variable"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_mut_passed", description: r##"Detects passing a mutable reference to a function that only requires an immutable reference."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_operation", description: r##"Checks for expression statements that can be reduced to a sub-expression."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_owned_empty_strings", description: r##"Detects cases of owned empty strings being passed as an argument to a function expecting `&str`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_result_map_or_else", description: r##"Checks for usage of `.map_or_else()` map closure for `Result` type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_safety_comment", description: r##"Checks for `// SAFETY: ` comments on safe code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_safety_doc", description: r##"Checks for the doc comments of publicly visible safe functions and traits and warns if there is a `# Safety` section."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_self_imports", description: r##"Checks for imports ending in `::{self}`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_sort_by", description: r##"Checks for usage of `Vec::sort_by` passing in a closure which compares the two arguments, either directly or indirectly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_struct_initialization", description: r##"Checks for initialization of an identical `struct` from another instance of the type, either by copying a base without setting any field or by moving all fields individually."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_to_owned", description: r##"Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned) and other `to_owned`-like functions."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_unwrap", description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnecessary_wraps", description: r##"Checks for private functions that only return `Ok` or `Some`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unneeded_field_pattern", description: r##"Checks for structure field patterns bound to wildcards."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unneeded_wildcard_pattern", @@ -13679,6 +18304,9 @@ _NOTE_: While `_, ..` means there is at least one element left, `..` means there are 0 or more elements left. This can make a difference when refactoring, but shouldn't result in errors in the refactored code, since the wildcard pattern isn't used anyway."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unnested_or_patterns", @@ -13687,26 +18315,47 @@ suggests replacing the pattern with a nested one, `Some(0 | 2)`. Another way to think of this is that it rewrites patterns in *disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unreachable", + description: r##"Checks for usage of `unreachable!`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::unreachable", description: r##"Checks for usage of `unreachable!`."## }, Lint { label: "clippy::unreadable_literal", description: r##"Warns if a long integral or floating-point constant does not contain underscores."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_derive_deserialize", description: r##"Checks for deriving `serde::Deserialize` on a type that has methods using `unsafe`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_removed_from_name", description: r##"Checks for imports that remove unsafe from an item's name."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsafe_vector_initialization", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unseparated_literal_suffix", @@ -13714,66 +18363,125 @@ name."##, underscore. To enforce unseparated literal suffix style, see the `separated_literal_suffix` lint."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unsound_collection_transmute", description: r##"Checks for transmutes between collections whose types have different ABI, size or alignment."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unstable_as_mut_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unstable_as_slice", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_async", description: r##"Checks for functions that are declared `async` but have no `.await`s inside of them."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_collect", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_enumerate_index", description: r##"Checks for uses of the `enumerate` method where the index is unused (`_`)"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_format_specs", description: r##"Detects [formatting parameters] that have no effect on the output of `format!()`, `println!()` or similar macros."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_io_amount", description: r##"Checks for unused written/read amount."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_peekable", description: r##"Checks for the creation of a `peekable` iterator that is never `.peek()`ed"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unused_result_ok", + description: r##"Checks for calls to `Result::ok()` without using the returned `Option`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_rounding", description: r##"Detects cases where a whole-number literal float is being rounded, using the `floor`, `ceil`, or `round` methods."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_self", description: r##"Checks methods that contain a `self` argument but don't use it"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::unused_trait_names", + description: r##"Checks for `use Trait` where the Trait is only used for its methods and not referenced by a path directly."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unused_unit", description: r##"Checks for unit (`()`) expressions that can be removed."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unusual_byte_groupings", description: r##"Warns if hexadecimal or binary literals are not grouped by nibble or byte."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_in_result", description: r##"Checks for functions of type `Result` that contain `expect()` or `unwrap()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_or_default", @@ -13783,34 +18491,63 @@ by nibble or byte."##, - `unwrap_or_else` - `or_insert` - `or_insert_with`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::unwrap_used", description: r##"Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::upper_case_acronyms", description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::use_debug", description: r##"Checks for usage of `Debug` formatting. The purpose of this lint is to catch debugging remnants."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::use_self", description: r##"Checks for unnecessary repetition of structure name when a replacement with `Self` is applicable."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::used_underscore_binding", description: r##"Checks for the use of bindings with a single leading underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::used_underscore_items", + description: r##"Checks for the use of item with a single leading +underscore."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_asref", description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the types before and after the call are the same."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_attribute", @@ -13838,36 +18575,57 @@ For `use` items these lints are: For `extern crate` items these lints are: * `unused_imports` on items with `#[macro_use]`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_conversion", description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls which uselessly convert to the same type."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_format", description: r##"Checks for the use of `format!(string literal with no argument)` and `format!({}, foo)` where `foo` is a string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_let_if_seq", description: r##"Checks for variable declarations immediately followed by a conditional affectation."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_transmute", description: r##"Checks for transmutes to the original type of the object and transmutes that could be a cast."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::useless_vec", description: r##"Checks for usage of `vec![..]` when using `[..]` would be possible."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_box", description: r##"Checks for usage of `Vec>` where T: Sized anywhere in the code. Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_init_then_push", @@ -13879,76 +18637,127 @@ constant and the number of pushes is greater than or equal to the initial capaci If the `Vec` is extended after the initial sequence of pushes and it was default initialized then this will only lint after there were at least four pushes. This number may change in the future."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::vec_resize_to_zero", description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::verbose_bit_mask", description: r##"Checks for bit masks that can be replaced by a call to `trailing_zeros`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::verbose_file_reads", description: r##"Checks for usage of File::read_to_end and File::read_to_string."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::waker_clone_wake", description: r##"Checks for usage of `waker.clone().wake()`"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_float", description: r##"Checks for while loops comparing floating point values."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_immutable_condition", description: r##"Checks whether variables used within while loop condition can be (and are) mutated in the body."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_let_loop", description: r##"Detects `loop + match` combinations that are easier written as a `while let` loop."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::while_let_on_iterator", description: r##"Checks for `while let` expressions on iterators."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_dependencies", description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_enum_match_arm", description: r##"Checks for wildcard enum matches using `_`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_imports", description: r##"Checks for wildcard imports `use _::*`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wildcard_in_or_patterns", description: r##"Checks for wildcard pattern used with others patterns in same match arm."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::write_literal", description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::write_with_newline", description: r##"This lint warns when you use `write!()` with a format string that ends in a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::writeln_empty_string", description: r##"This lint warns when you use `writeln!(buf, )` to print a newline."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_pub_self_convention", - description: r##"Nothing. This lint has been deprecated."##, + description: r##"Nothing. This lint has been deprecated"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_self_convention", @@ -13977,34 +18786,68 @@ Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is re Please find more info here: https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::wrong_transmute", description: r##"Checks for transmutes that can't ever be correct on any architecture."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::zero_divided_by_zero", + description: r##"Checks for `0.0 / 0.0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, - Lint { label: "clippy::zero_divided_by_zero", description: r##"Checks for `0.0 / 0.0`."## }, Lint { label: "clippy::zero_prefixed_literal", description: r##"Warns if an integral constant literal starts with `0`."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_ptr", description: r##"Catch casts from `0` to some pointer type"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_repeat_side_effects", description: r##"Checks for array or vec initializations which call a function or method, but which have a repeat count of zero."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zero_sized_map_values", description: r##"Checks for maps with zero-sized value types anywhere in the code."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clippy::zombie_processes", + description: r##"Looks for code that spawns a process but never calls `wait()` on the child."##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, Lint { label: "clippy::zst_offset", description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to zero-sized types"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, ]; pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ @@ -14012,6 +18855,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "clippy::cargo", description: r##"lint group for: clippy::cargo_common_metadata, clippy::multiple_crate_versions, clippy::negative_feature_names, clippy::redundant_feature_names, clippy::wildcard_dependencies"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::cargo_common_metadata", @@ -14024,7 +18870,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::complexity", - description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_clamp, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##, + description: r##"lint group for: clippy::bind_instead_of_map, clippy::bool_comparison, clippy::borrow_deref_ref, clippy::borrowed_box, clippy::bytes_count_to_len, clippy::char_lit_as_u8, clippy::clone_on_copy, clippy::crosspointer_transmute, clippy::default_constructed_unit_structs, clippy::deprecated_cfg_attr, clippy::deref_addrof, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::double_comparisons, clippy::double_parens, clippy::duration_subsec, clippy::excessive_nesting, clippy::explicit_auto_deref, clippy::explicit_counter_loop, clippy::explicit_write, clippy::extra_unused_lifetimes, clippy::extra_unused_type_parameters, clippy::filter_map_identity, clippy::filter_next, clippy::flat_map_identity, clippy::get_last_with_len, clippy::identity_op, clippy::implied_bounds_in_impls, clippy::inspect_for_each, clippy::int_plus_one, clippy::iter_count, clippy::iter_kv_map, clippy::let_with_type_underscore, clippy::manual_c_str_literals, clippy::manual_clamp, clippy::manual_div_ceil, clippy::manual_filter, clippy::manual_filter_map, clippy::manual_find, clippy::manual_find_map, clippy::manual_flatten, clippy::manual_hash_one, clippy::manual_inspect, clippy::manual_is_power_of_two, clippy::manual_main_separator_str, clippy::manual_range_patterns, clippy::manual_rem_euclid, clippy::manual_slice_size_calculation, clippy::manual_split_once, clippy::manual_strip, clippy::manual_swap, clippy::manual_unwrap_or, clippy::map_flatten, clippy::map_identity, clippy::match_as_ref, clippy::match_single_binding, clippy::needless_arbitrary_self_type, clippy::needless_bool, clippy::needless_bool_assign, clippy::needless_borrowed_reference, clippy::needless_if, clippy::needless_lifetimes, clippy::needless_match, clippy::needless_option_as_deref, clippy::needless_option_take, clippy::needless_question_mark, clippy::needless_splitn, clippy::needless_update, clippy::neg_cmp_op_on_partial_ord, clippy::no_effect, clippy::nonminimal_bool, clippy::only_used_in_recursion, clippy::option_as_ref_deref, clippy::option_filter_map, clippy::option_map_unit_fn, clippy::or_then_unwrap, clippy::partialeq_ne_impl, clippy::precedence, clippy::ptr_offset_with_cast, clippy::range_zip_with_len, clippy::redundant_as_str, clippy::redundant_async_block, clippy::redundant_at_rest_pattern, clippy::redundant_closure_call, clippy::redundant_guards, clippy::redundant_slicing, clippy::repeat_once, clippy::reserve_after_initialization, clippy::result_filter_map, clippy::result_map_unit_fn, clippy::search_is_some, clippy::seek_from_current, clippy::seek_to_start_instead_of_rewind, clippy::short_circuit_statement, clippy::single_element_loop, clippy::skip_while_next, clippy::string_from_utf8_as_bytes, clippy::strlen_on_c_strings, clippy::temporary_assignment, clippy::too_many_arguments, clippy::transmute_bytes_to_str, clippy::transmute_float_to_int, clippy::transmute_int_to_bool, clippy::transmute_int_to_char, clippy::transmute_int_to_float, clippy::transmute_int_to_non_zero, clippy::transmute_num_to_bytes, clippy::transmute_ptr_to_ref, clippy::transmutes_expressible_as_ptr_casts, clippy::type_complexity, clippy::unit_arg, clippy::unnecessary_cast, clippy::unnecessary_filter_map, clippy::unnecessary_find_map, clippy::unnecessary_first_then_check, clippy::unnecessary_literal_unwrap, clippy::unnecessary_map_on_constructor, clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_sort_by, clippy::unnecessary_unwrap, clippy::unneeded_wildcard_pattern, clippy::unused_format_specs, clippy::useless_asref, clippy::useless_conversion, clippy::useless_format, clippy::useless_transmute, clippy::vec_box, clippy::while_let_loop, clippy::wildcard_in_or_patterns, clippy::zero_divided_by_zero, clippy::zero_prefixed_literal"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::bind_instead_of_map", @@ -14060,7 +18909,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::iter_count", "clippy::iter_kv_map", "clippy::let_with_type_underscore", + "clippy::manual_c_str_literals", "clippy::manual_clamp", + "clippy::manual_div_ceil", "clippy::manual_filter", "clippy::manual_filter_map", "clippy::manual_find", @@ -14068,6 +18919,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::manual_flatten", "clippy::manual_hash_one", "clippy::manual_inspect", + "clippy::manual_is_power_of_two", "clippy::manual_main_separator_str", "clippy::manual_range_patterns", "clippy::manual_rem_euclid", @@ -14138,6 +18990,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unnecessary_cast", "clippy::unnecessary_filter_map", "clippy::unnecessary_find_map", + "clippy::unnecessary_first_then_check", "clippy::unnecessary_literal_unwrap", "clippy::unnecessary_map_on_constructor", "clippy::unnecessary_min_or_max", @@ -14160,7 +19013,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::correctness", - description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##, + description: r##"lint group for: clippy::absurd_extreme_comparisons, clippy::almost_swapped, clippy::approx_constant, clippy::async_yields_async, clippy::bad_bit_mask, clippy::cast_slice_different_sizes, clippy::deprecated_semver, clippy::derive_ord_xor_partial_ord, clippy::derived_hash_with_manual_eq, clippy::eager_transmute, clippy::enum_clike_unportable_variant, clippy::eq_op, clippy::erasing_op, clippy::fn_address_comparisons, clippy::if_let_mutex, clippy::ifs_same_cond, clippy::impl_hash_borrow_with_str_and_bytes, clippy::impossible_comparisons, clippy::ineffective_bit_mask, clippy::infinite_iter, clippy::inherent_to_string_shadow_display, clippy::inline_fn_without_body, clippy::invalid_null_ptr_usage, clippy::invalid_regex, clippy::inverted_saturating_sub, clippy::invisible_characters, clippy::iter_next_loop, clippy::iter_skip_zero, clippy::iterator_step_by_zero, clippy::let_underscore_lock, clippy::lint_groups_priority, clippy::match_str_case_mismatch, clippy::mem_replace_with_uninit, clippy::min_max, clippy::mistyped_literal_suffixes, clippy::modulo_one, clippy::mut_from_ref, clippy::never_loop, clippy::non_octal_unix_permissions, clippy::nonsensical_open_options, clippy::not_unsafe_ptr_arg_deref, clippy::option_env_unwrap, clippy::out_of_bounds_indexing, clippy::overly_complex_bool_expr, clippy::panicking_overflow_checks, clippy::panicking_unwrap, clippy::possible_missing_comma, clippy::read_line_without_trim, clippy::recursive_format_impl, clippy::redundant_comparisons, clippy::redundant_locals, clippy::reversed_empty_ranges, clippy::self_assignment, clippy::serde_api_misuse, clippy::size_of_in_element_count, clippy::suspicious_splitn, clippy::transmute_null_to_fn, clippy::transmuting_null, clippy::uninit_assumed_init, clippy::uninit_vec, clippy::unit_cmp, clippy::unit_hash, clippy::unit_return_expecting_ord, clippy::unsound_collection_transmute, clippy::unused_io_amount, clippy::useless_attribute, clippy::vec_resize_to_zero, clippy::while_immutable_condition, clippy::wrong_transmute, clippy::zst_offset"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::absurd_extreme_comparisons", @@ -14187,6 +19043,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::inline_fn_without_body", "clippy::invalid_null_ptr_usage", "clippy::invalid_regex", + "clippy::inverted_saturating_sub", "clippy::invisible_characters", "clippy::iter_next_loop", "clippy::iter_skip_zero", @@ -14237,17 +19094,15 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::deprecated", - description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::filter_map, clippy::find_map, clippy::if_let_redundant_pattern_matching, clippy::maybe_misused_cfg, clippy::misaligned_transmute, clippy::mismatched_target_os, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##, + description: r##"lint group for: clippy::assign_ops, clippy::extend_from_slice, clippy::misaligned_transmute, clippy::pub_enum_variant_names, clippy::range_step_by_zero, clippy::regex_macro, clippy::replace_consts, clippy::should_assert_eq, clippy::unsafe_vector_initialization, clippy::unstable_as_mut_slice, clippy::unstable_as_slice, clippy::unused_collect, clippy::wrong_pub_self_convention"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assign_ops", "clippy::extend_from_slice", - "clippy::filter_map", - "clippy::find_map", - "clippy::if_let_redundant_pattern_matching", - "clippy::maybe_misused_cfg", "clippy::misaligned_transmute", - "clippy::mismatched_target_os", "clippy::pub_enum_variant_names", "clippy::range_step_by_zero", "clippy::regex_macro", @@ -14263,7 +19118,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::nursery", - description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##, + description: r##"lint group for: clippy::as_ptr_cast_mut, clippy::branches_sharing_code, clippy::clear_with_drain, clippy::cognitive_complexity, clippy::collection_is_never_read, clippy::debug_assert_with_mut_call, clippy::derive_partial_eq_without_eq, clippy::equatable_if_let, clippy::fallible_impl_from, clippy::future_not_send, clippy::imprecise_flops, clippy::iter_on_empty_collections, clippy::iter_on_single_items, clippy::iter_with_drain, clippy::large_stack_frames, clippy::missing_const_for_fn, clippy::mutex_integer, clippy::needless_collect, clippy::needless_pass_by_ref_mut, clippy::non_send_fields_in_send_ty, clippy::nonstandard_macro_braces, clippy::option_if_let_else, clippy::or_fun_call, clippy::path_buf_push_overwrite, clippy::read_zero_byte_vec, clippy::redundant_clone, clippy::redundant_pub_crate, clippy::set_contains_or_insert, clippy::significant_drop_in_scrutinee, clippy::significant_drop_tightening, clippy::string_lit_as_bytes, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::trailing_empty_array, clippy::trait_duplication_in_bounds, clippy::transmute_undefined_repr, clippy::trivial_regex, clippy::tuple_array_conversions, clippy::type_repetition_in_bounds, clippy::uninhabited_references, clippy::unnecessary_struct_initialization, clippy::unused_peekable, clippy::unused_rounding, clippy::use_self, clippy::useless_let_if_seq, clippy::while_float"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::as_ptr_cast_mut", @@ -14273,8 +19131,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::collection_is_never_read", "clippy::debug_assert_with_mut_call", "clippy::derive_partial_eq_without_eq", - "clippy::empty_line_after_doc_comments", - "clippy::empty_line_after_outer_attr", "clippy::equatable_if_let", "clippy::fallible_impl_from", "clippy::future_not_send", @@ -14319,7 +19175,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::pedantic", - description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_c_str_literals, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, + description: r##"lint group for: clippy::assigning_clones, clippy::bool_to_int_with_if, clippy::borrow_as_ptr, clippy::case_sensitive_file_extension_comparisons, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::checked_conversions, clippy::cloned_instead_of_copied, clippy::copy_iterator, clippy::default_trait_access, clippy::doc_link_with_quotes, clippy::doc_markdown, clippy::empty_enum, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_deref_methods, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::flat_map_option, clippy::float_cmp, clippy::fn_params_excessive_bools, clippy::from_iter_instead_of_collect, clippy::if_not_else, clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::implicit_hasher, clippy::inconsistent_struct_constructor, clippy::index_refutable_slice, clippy::inefficient_to_string, clippy::inline_always, clippy::into_iter_without_iter, clippy::invalid_upcast_comparisons, clippy::items_after_statements, clippy::iter_filter_is_ok, clippy::iter_filter_is_some, clippy::iter_not_returning_iterator, clippy::iter_without_into_iter, clippy::large_digit_groups, clippy::large_futures, clippy::large_stack_arrays, clippy::large_types_passed_by_value, clippy::linkedlist, clippy::macro_use_imports, clippy::manual_assert, clippy::manual_instant_elapsed, clippy::manual_is_variant_and, clippy::manual_let_else, clippy::manual_ok_or, clippy::manual_string_new, clippy::many_single_char_names, clippy::map_unwrap_or, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wild_err_arm, clippy::match_wildcard_for_single_variants, clippy::maybe_infinite_iter, clippy::mismatching_type_param_order, clippy::missing_errors_doc, clippy::missing_fields_in_debug, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::mut_mut, clippy::naive_bytecount, clippy::needless_bitwise_bool, clippy::needless_continue, clippy::needless_for_each, clippy::needless_pass_by_value, clippy::needless_raw_string_hashes, clippy::no_effect_underscore_binding, clippy::no_mangle_with_rust_abi, clippy::option_as_ref_cloned, clippy::option_option, clippy::ptr_as_ptr, clippy::ptr_cast_constness, clippy::pub_underscore_fields, clippy::range_minus_one, clippy::range_plus_one, clippy::redundant_closure_for_method_calls, clippy::redundant_else, clippy::ref_as_ptr, clippy::ref_binding_to_reference, clippy::ref_option, clippy::ref_option_ref, clippy::return_self_not_must_use, clippy::same_functions_in_if_condition, clippy::semicolon_if_nothing_returned, clippy::should_panic_without_expect, clippy::similar_names, clippy::single_char_pattern, clippy::single_match_else, clippy::stable_sort_primitive, clippy::str_split_at_newline, clippy::string_add_assign, clippy::struct_excessive_bools, clippy::struct_field_names, clippy::too_many_lines, clippy::transmute_ptr_to_ptr, clippy::trivially_copy_pass_by_ref, clippy::unchecked_duration_subtraction, clippy::unicode_not_nfc, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_join, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::unreadable_literal, clippy::unsafe_derive_deserialize, clippy::unused_async, clippy::unused_self, clippy::used_underscore_binding, clippy::used_underscore_items, clippy::verbose_bit_mask, clippy::wildcard_imports, clippy::zero_sized_map_values"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assigning_clones", @@ -14371,7 +19230,6 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::linkedlist", "clippy::macro_use_imports", "clippy::manual_assert", - "clippy::manual_c_str_literals", "clippy::manual_instant_elapsed", "clippy::manual_is_variant_and", "clippy::manual_let_else", @@ -14411,6 +19269,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::redundant_else", "clippy::ref_as_ptr", "clippy::ref_binding_to_reference", + "clippy::ref_option", "clippy::ref_option_ref", "clippy::return_self_not_must_use", "clippy::same_functions_in_if_condition", @@ -14439,6 +19298,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unused_async", "clippy::unused_self", "clippy::used_underscore_binding", + "clippy::used_underscore_items", "clippy::verbose_bit_mask", "clippy::wildcard_imports", "clippy::zero_sized_map_values", @@ -14448,6 +19308,9 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ lint: Lint { label: "clippy::perf", description: r##"lint group for: clippy::box_collection, clippy::boxed_local, clippy::cmp_owned, clippy::collapsible_str_replace, clippy::drain_collect, clippy::expect_fun_call, clippy::extend_with_drain, clippy::format_collect, clippy::format_in_format_args, clippy::iter_overeager_cloned, clippy::large_const_arrays, clippy::large_enum_variant, clippy::manual_memcpy, clippy::manual_retain, clippy::manual_str_repeat, clippy::manual_try_fold, clippy::map_entry, clippy::missing_const_for_thread_local, clippy::missing_spin_loop, clippy::readonly_write_lock, clippy::redundant_allocation, clippy::result_large_err, clippy::slow_vector_initialization, clippy::to_string_in_format_args, clippy::unnecessary_to_owned, clippy::useless_vec, clippy::vec_init_then_push, clippy::waker_clone_wake"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::box_collection", @@ -14483,7 +19346,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::restriction", - description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##, + description: r##"lint group for: clippy::absolute_paths, clippy::alloc_instead_of_core, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::arithmetic_side_effects, clippy::as_conversions, clippy::as_underscore, clippy::assertions_on_result_states, clippy::big_endian_bytes, clippy::cfg_not_test, clippy::clone_on_ref_ptr, clippy::create_dir, clippy::dbg_macro, clippy::decimal_literal_representation, clippy::default_numeric_fallback, clippy::default_union_representation, clippy::deref_by_slicing, clippy::disallowed_script_idents, clippy::else_if_without_else, clippy::empty_drop, clippy::empty_enum_variants_with_brackets, clippy::empty_structs_with_brackets, clippy::error_impl_error, clippy::exhaustive_enums, clippy::exhaustive_structs, clippy::exit, clippy::expect_used, clippy::field_scoped_visibility_modifiers, clippy::filetype_is_file, clippy::float_arithmetic, clippy::float_cmp_const, clippy::fn_to_numeric_cast_any, clippy::format_push_string, clippy::get_unwrap, clippy::host_endian_bytes, clippy::if_then_some_else_none, clippy::impl_trait_in_params, clippy::implicit_return, clippy::indexing_slicing, clippy::infinite_loop, clippy::inline_asm_x86_att_syntax, clippy::inline_asm_x86_intel_syntax, clippy::integer_division, clippy::integer_division_remainder_used, clippy::iter_over_hash_type, clippy::large_include_file, clippy::let_underscore_must_use, clippy::let_underscore_untyped, clippy::little_endian_bytes, clippy::lossy_float_literal, clippy::map_err_ignore, clippy::mem_forget, clippy::min_ident_chars, clippy::missing_assert_message, clippy::missing_asserts_for_indexing, clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::missing_trait_methods, clippy::mixed_read_write_in_expression, clippy::mod_module_files, clippy::modulo_arithmetic, clippy::multiple_inherent_impl, clippy::multiple_unsafe_ops_per_block, clippy::mutex_atomic, clippy::needless_raw_strings, clippy::non_ascii_literal, clippy::non_zero_suggestions, clippy::panic, clippy::panic_in_result_fn, clippy::partial_pub_fields, clippy::pathbuf_init_then_push, clippy::pattern_type_mismatch, clippy::print_stderr, clippy::print_stdout, clippy::pub_use, clippy::pub_with_shorthand, clippy::pub_without_shorthand, clippy::question_mark_used, clippy::rc_buffer, clippy::rc_mutex, clippy::redundant_type_annotations, clippy::ref_patterns, clippy::renamed_function_params, clippy::rest_pat_in_fully_bound_structs, clippy::same_name_method, clippy::self_named_module_files, clippy::semicolon_inside_block, clippy::semicolon_outside_block, clippy::separated_literal_suffix, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_call_fn, clippy::single_char_lifetime_names, clippy::std_instead_of_alloc, clippy::std_instead_of_core, clippy::str_to_string, clippy::string_add, clippy::string_lit_chars_any, clippy::string_slice, clippy::string_to_string, clippy::suspicious_xor_used_as_pow, clippy::tests_outside_test_module, clippy::todo, clippy::try_err, clippy::undocumented_unsafe_blocks, clippy::unimplemented, clippy::unnecessary_safety_comment, clippy::unnecessary_safety_doc, clippy::unnecessary_self_imports, clippy::unneeded_field_pattern, clippy::unreachable, clippy::unseparated_literal_suffix, clippy::unused_result_ok, clippy::unused_trait_names, clippy::unwrap_in_result, clippy::unwrap_used, clippy::use_debug, clippy::verbose_file_reads, clippy::wildcard_enum_match_arm"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::absolute_paths", @@ -14552,6 +19418,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::mutex_atomic", "clippy::needless_raw_strings", "clippy::non_ascii_literal", + "clippy::non_zero_suggestions", "clippy::panic", "clippy::panic_in_result_fn", "clippy::partial_pub_fields", @@ -14598,6 +19465,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unneeded_field_pattern", "clippy::unreachable", "clippy::unseparated_literal_suffix", + "clippy::unused_result_ok", + "clippy::unused_trait_names", "clippy::unwrap_in_result", "clippy::unwrap_used", "clippy::use_debug", @@ -14608,7 +19477,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::style", - description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##, + description: r##"lint group for: clippy::assertions_on_constants, clippy::assign_op_pattern, clippy::blocks_in_conditions, clippy::bool_assert_comparison, clippy::borrow_interior_mutable_const, clippy::box_default, clippy::builtin_type_shadow, clippy::byte_char_slices, clippy::bytes_nth, clippy::chars_last_cmp, clippy::chars_next_cmp, clippy::cmp_null, clippy::collapsible_else_if, clippy::collapsible_if, clippy::collapsible_match, clippy::comparison_chain, clippy::comparison_to_empty, clippy::declare_interior_mutable_const, clippy::default_instead_of_iter_empty, clippy::disallowed_macros, clippy::disallowed_methods, clippy::disallowed_names, clippy::disallowed_types, clippy::doc_lazy_continuation, clippy::double_must_use, clippy::double_neg, clippy::duplicate_underscore_argument, clippy::enum_variant_names, clippy::err_expect, clippy::excessive_precision, clippy::field_reassign_with_default, clippy::filter_map_bool_then, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::for_kv_map, clippy::from_over_into, clippy::from_str_radix_10, clippy::get_first, clippy::if_same_then_else, clippy::implicit_saturating_add, clippy::implicit_saturating_sub, clippy::inconsistent_digit_grouping, clippy::infallible_destructuring_match, clippy::inherent_to_string, clippy::init_numbered_fields, clippy::into_iter_on_ref, clippy::is_digit_ascii_radix, clippy::items_after_test_module, clippy::iter_cloned_collect, clippy::iter_next_slice, clippy::iter_nth, clippy::iter_nth_zero, clippy::iter_skip_next, clippy::just_underscores_and_digits, clippy::legacy_numeric_constants, clippy::len_without_is_empty, clippy::len_zero, clippy::let_and_return, clippy::let_unit_value, clippy::main_recursion, clippy::manual_async_fn, clippy::manual_bits, clippy::manual_is_ascii_check, clippy::manual_is_finite, clippy::manual_is_infinite, clippy::manual_map, clippy::manual_next_back, clippy::manual_non_exhaustive, clippy::manual_pattern_char_comparison, clippy::manual_range_contains, clippy::manual_rotate, clippy::manual_saturating_arithmetic, clippy::manual_while_let_some, clippy::map_clone, clippy::map_collect_result_unit, clippy::match_like_matches_macro, clippy::match_overlapping_arm, clippy::match_ref_pats, clippy::match_result_ok, clippy::mem_replace_option_with_none, clippy::mem_replace_with_default, clippy::missing_enforced_import_renames, clippy::missing_safety_doc, clippy::mixed_attributes_style, clippy::mixed_case_hex_literals, clippy::module_inception, clippy::must_use_unit, clippy::mut_mutex_lock, clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::needless_doctest_main, clippy::needless_else, clippy::needless_late_init, clippy::needless_parens_on_range_literals, clippy::needless_pub_self, clippy::needless_range_loop, clippy::needless_return, clippy::needless_return_with_question_mark, clippy::neg_multiply, clippy::new_ret_no_self, clippy::new_without_default, clippy::non_minimal_cfg, clippy::obfuscated_if_else, clippy::ok_expect, clippy::op_ref, clippy::option_map_or_err_ok, clippy::option_map_or_none, clippy::partialeq_to_none, clippy::print_literal, clippy::print_with_newline, clippy::println_empty_string, clippy::ptr_arg, clippy::ptr_eq, clippy::question_mark, clippy::redundant_closure, clippy::redundant_field_names, clippy::redundant_pattern, clippy::redundant_pattern_matching, clippy::redundant_static_lifetimes, clippy::result_map_or_into_option, clippy::result_unit_err, clippy::same_item_push, clippy::self_named_constructors, clippy::should_implement_trait, clippy::single_char_add_str, clippy::single_component_path_imports, clippy::single_match, clippy::string_extend_chars, clippy::tabs_in_doc_comments, clippy::to_digit_is_some, clippy::to_string_trait_impl, clippy::too_long_first_doc_paragraph, clippy::toplevel_ref_arg, clippy::trim_split_whitespace, clippy::unnecessary_fallible_conversions, clippy::unnecessary_fold, clippy::unnecessary_lazy_evaluations, clippy::unnecessary_mut_passed, clippy::unnecessary_owned_empty_strings, clippy::unsafe_removed_from_name, clippy::unused_enumerate_index, clippy::unused_unit, clippy::unusual_byte_groupings, clippy::unwrap_or_default, clippy::upper_case_acronyms, clippy::while_let_on_iterator, clippy::write_literal, clippy::write_with_newline, clippy::writeln_empty_string, clippy::wrong_self_convention, clippy::zero_ptr"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::assertions_on_constants", @@ -14742,6 +19614,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::tabs_in_doc_comments", "clippy::to_digit_is_some", "clippy::to_string_trait_impl", + "clippy::too_long_first_doc_paragraph", "clippy::toplevel_ref_arg", "clippy::trim_split_whitespace", "clippy::unnecessary_fallible_conversions", @@ -14766,7 +19639,10 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "clippy::suspicious", - description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects"##, + description: r##"lint group for: clippy::almost_complete_range, clippy::arc_with_non_send_sync, clippy::await_holding_invalid_type, clippy::await_holding_lock, clippy::await_holding_refcell_ref, clippy::blanket_clippy_restriction_lints, clippy::cast_abs_to_unsigned, clippy::cast_enum_constructor, clippy::cast_enum_truncation, clippy::cast_nan_to_int, clippy::cast_slice_from_raw_parts, clippy::const_is_empty, clippy::crate_in_macro_def, clippy::deprecated_clippy_cfg_attr, clippy::drop_non_drop, clippy::duplicate_mod, clippy::duplicated_attributes, clippy::empty_docs, clippy::empty_line_after_doc_comments, clippy::empty_line_after_outer_attr, clippy::empty_loop, clippy::float_equality_without_abs, clippy::forget_non_drop, clippy::four_forward_slashes, clippy::from_raw_with_void_ptr, clippy::incompatible_msrv, clippy::ineffective_open_options, clippy::iter_out_of_bounds, clippy::join_absolute_paths, clippy::let_underscore_future, clippy::lines_filter_map_ok, clippy::macro_metavars_in_unsafe, clippy::manual_unwrap_or_default, clippy::misnamed_getters, clippy::misrefactored_assign_op, clippy::missing_transmute_annotations, clippy::multi_assignments, clippy::multiple_bound_locations, clippy::mut_range_bound, clippy::mutable_key_type, clippy::needless_character_iteration, clippy::needless_maybe_sized, clippy::no_effect_replace, clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, clippy::octal_escapes, clippy::path_ends_with_ext, clippy::permissions_set_readonly_false, clippy::pointers_in_nomem_asm_block, clippy::print_in_format_impl, clippy::rc_clone_in_vec_init, clippy::repeat_vec_with_capacity, clippy::single_range_in_vec_init, clippy::size_of_ref, clippy::suspicious_arithmetic_impl, clippy::suspicious_assignment_formatting, clippy::suspicious_command_arg_space, clippy::suspicious_doc_comments, clippy::suspicious_else_formatting, clippy::suspicious_map, clippy::suspicious_op_assign_impl, clippy::suspicious_open_options, clippy::suspicious_to_owned, clippy::suspicious_unary_op_formatting, clippy::swap_ptr_to_ref, clippy::test_attr_in_doctest, clippy::type_id_on_box, clippy::unconditional_recursion, clippy::unnecessary_clippy_cfg, clippy::unnecessary_get_then_check, clippy::unnecessary_result_map_or_else, clippy::zero_repeat_side_effects, clippy::zombie_processes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, }, children: &[ "clippy::almost_complete_range", @@ -14787,6 +19663,8 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::duplicate_mod", "clippy::duplicated_attributes", "clippy::empty_docs", + "clippy::empty_line_after_doc_comments", + "clippy::empty_line_after_outer_attr", "clippy::empty_loop", "clippy::float_equality_without_abs", "clippy::forget_non_drop", @@ -14815,6 +19693,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::octal_escapes", "clippy::path_ends_with_ext", "clippy::permissions_set_readonly_false", + "clippy::pointers_in_nomem_asm_block", "clippy::print_in_format_impl", "clippy::rc_clone_in_vec_init", "clippy::repeat_vec_with_capacity", @@ -14838,6 +19717,7 @@ pub const CLIPPY_LINT_GROUPS: &[LintGroup] = &[ "clippy::unnecessary_get_then_check", "clippy::unnecessary_result_map_or_else", "clippy::zero_repeat_side_effects", + "clippy::zombie_processes", ], }, ]; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 81260c3e080..1f77ea1ec66 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -327,3 +327,11 @@ impl<'a> Ranker<'a> { | ((no_tt_parent as usize) << 3) } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Severity { + Error, + Warning, + WeakWarning, + Allow, +} diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 2bfdda35659..dc3dee5c9ce 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -586,14 +586,47 @@ fn main() { } #[test] - fn unsafe_op_in_unsafe_fn_allowed_by_default() { + fn unsafe_op_in_unsafe_fn_allowed_by_default_in_edition_2021() { check_diagnostics( r#" +//- /lib.rs crate:foo edition:2021 unsafe fn foo(p: *mut i32) { *p = 123; } "#, - ) + ); + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2021 +#![deny(warnings)] +unsafe fn foo(p: *mut i32) { + *p = 123; +} + "#, + ); + } + + #[test] + fn unsafe_op_in_unsafe_fn_warn_by_default_in_edition_2024() { + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2024 +unsafe fn foo(p: *mut i32) { + *p = 123; + //^^💡 warn: dereference of raw pointer is unsafe and requires an unsafe function or block +} + "#, + ); + check_diagnostics( + r#" +//- /lib.rs crate:foo edition:2024 +#![deny(warnings)] +unsafe fn foo(p: *mut i32) { + *p = 123; + //^^💡 error: dereference of raw pointer is unsafe and requires an unsafe function or block +} + "#, + ); } #[test] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index ad339569081..1e99d7ad6e6 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -84,12 +84,12 @@ use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFi use ide_db::{ assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, base_db::SourceDatabase, - generated::lints::{LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS}, + generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS}, imports::insert_use::InsertUseConfig, label::Label, source_change::SourceChange, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, - EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, SnippetCap, + EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, }; use itertools::Itertools; use syntax::{ @@ -210,14 +210,6 @@ impl Diagnostic { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Severity { - Error, - Warning, - WeakWarning, - Allow, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum ExprFillDefaultMode { Todo, @@ -568,26 +560,35 @@ fn handle_diag_from_macros( // `__RA_EVERY_LINT` is a fake lint group to allow every lint in proc macros -static RUSTC_LINT_GROUPS_DICT: LazyLock>> = - LazyLock::new(|| build_group_dict(DEFAULT_LINT_GROUPS, &["warnings", "__RA_EVERY_LINT"], "")); +struct BuiltLint { + lint: &'static Lint, + groups: Vec<&'static str>, +} -static CLIPPY_LINT_GROUPS_DICT: LazyLock>> = - LazyLock::new(|| build_group_dict(CLIPPY_LINT_GROUPS, &["__RA_EVERY_LINT"], "clippy::")); +static RUSTC_LINTS: LazyLock> = + LazyLock::new(|| build_lints_map(DEFAULT_LINTS, DEFAULT_LINT_GROUPS, "")); + +static CLIPPY_LINTS: LazyLock> = LazyLock::new(|| { + build_lints_map(ide_db::generated::lints::CLIPPY_LINTS, CLIPPY_LINT_GROUPS, "clippy::") +}); // FIXME: Autogenerate this instead of enumerating by hand. static LINTS_TO_REPORT_IN_EXTERNAL_MACROS: LazyLock> = LazyLock::new(|| FxHashSet::from_iter([])); -fn build_group_dict( +fn build_lints_map( + lints: &'static [Lint], lint_group: &'static [LintGroup], - all_groups: &'static [&'static str], prefix: &'static str, -) -> FxHashMap<&'static str, Vec<&'static str>> { - let mut map_with_prefixes: FxHashMap<&str, Vec<&str>> = FxHashMap::default(); +) -> FxHashMap<&'static str, BuiltLint> { + let mut map_with_prefixes: FxHashMap<_, _> = lints + .iter() + .map(|lint| (lint.label, BuiltLint { lint, groups: vec![lint.label, "__RA_EVERY_LINT"] })) + .collect(); for g in lint_group { let mut add_children = |label: &'static str| { for child in g.children { - map_with_prefixes.entry(child).or_default().push(label); + map_with_prefixes.get_mut(child).unwrap().groups.push(label); } }; add_children(g.lint.label); @@ -597,18 +598,9 @@ fn build_group_dict( add_children("bad_style"); } } - for (lint, groups) in map_with_prefixes.iter_mut() { - groups.push(lint); - groups.extend_from_slice(all_groups); - } map_with_prefixes.into_iter().map(|(k, v)| (k.strip_prefix(prefix).unwrap(), v)).collect() } -/// Thd default severity for lints that are not warn by default. -// FIXME: Autogenerate this instead of write manually. -static LINTS_DEFAULT_SEVERITY: LazyLock> = - LazyLock::new(|| FxHashMap::from_iter([("unsafe_op_in_unsafe_fn", Severity::Allow)])); - fn handle_lints( sema: &Semantics<'_, RootDatabase>, cache: &mut FxHashMap>, @@ -618,10 +610,12 @@ fn handle_lints( ) { for (node, diag) in diagnostics { let lint = match diag.code { - DiagnosticCode::RustcLint(lint) | DiagnosticCode::Clippy(lint) => lint, + DiagnosticCode::RustcLint(lint) => RUSTC_LINTS[lint].lint, + DiagnosticCode::Clippy(lint) => CLIPPY_LINTS[lint].lint, _ => panic!("non-lint passed to `handle_lints()`"), }; - if let Some(&default_severity) = LINTS_DEFAULT_SEVERITY.get(lint) { + let default_severity = default_lint_severity(lint, edition); + if !(default_severity == Severity::Allow && diag.severity == Severity::WeakWarning) { diag.severity = default_severity; } @@ -639,6 +633,16 @@ fn handle_lints( } } +fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity { + if lint.deny_since.is_some_and(|e| edition >= e) { + Severity::Error + } else if lint.warn_since.is_some_and(|e| edition >= e) { + Severity::Warning + } else { + lint.default_severity + } +} + fn find_outline_mod_lint_severity( sema: &Semantics<'_, RootDatabase>, node: &InFile, @@ -654,14 +658,14 @@ fn find_outline_mod_lint_severity( let mod_def = sema.to_module_def(&mod_node)?; let module_source_file = sema.module_definition_node(mod_def); let mut result = None; - let lint_groups = lint_groups(&diag.code); + let lint_groups = lint_groups(&diag.code, edition); lint_attrs( sema, ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), edition, ) .for_each(|(lint, severity)| { - if lint_groups.contains(&&*lint) { + if lint_groups.contains(&lint) { result = Some(severity); } }); @@ -737,9 +741,9 @@ fn fill_lint_attrs( } }); - let all_matching_groups = lint_groups(&diag.code) + let all_matching_groups = lint_groups(&diag.code, edition) .iter() - .filter_map(|lint_group| cached.get(&**lint_group)); + .filter_map(|lint_group| cached.get(lint_group)); let cached_severity = all_matching_groups.min_by_key(|it| it.depth).map(|it| it.severity); @@ -751,7 +755,7 @@ fn fill_lint_attrs( // Insert this node's descendants' attributes into any outline descendant, but not including this node. // This must come before inserting this node's own attributes to preserve order. collected_lint_attrs.drain().for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity.severity); } @@ -774,7 +778,7 @@ fn fill_lint_attrs( if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) { // Insert this node's attributes into any outline descendant, including this node. lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity); } @@ -804,7 +808,7 @@ fn fill_lint_attrs( return diag_severity; } else if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) { lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| { - if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) { + if diag_severity.is_none() && lint_groups(&diag.code, edition).contains(&lint) { diag_severity = Some(severity); } @@ -905,16 +909,37 @@ fn cfg_attr_lint_attrs( } } -fn lint_groups(lint: &DiagnosticCode) -> &'static [&'static str] { - match lint { +#[derive(Debug)] +struct LintGroups { + groups: &'static [&'static str], + inside_warnings: bool, +} + +impl LintGroups { + fn contains(&self, group: &str) -> bool { + self.groups.contains(&group) || (self.inside_warnings && group == "warnings") + } + + fn iter(&self) -> impl Iterator { + self.groups.iter().copied().chain(self.inside_warnings.then_some("warnings")) + } +} + +fn lint_groups(lint: &DiagnosticCode, edition: Edition) -> LintGroups { + let (groups, inside_warnings) = match lint { DiagnosticCode::RustcLint(name) => { - RUSTC_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default() + let lint = &RUSTC_LINTS[name]; + let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning; + (&lint.groups, inside_warnings) } DiagnosticCode::Clippy(name) => { - CLIPPY_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default() + let lint = &CLIPPY_LINTS[name]; + let inside_warnings = default_lint_severity(lint.lint, edition) == Severity::Warning; + (&lint.groups, inside_warnings) } - _ => &[], - } + _ => panic!("non-lint passed to `handle_lints()`"), + }; + LintGroups { groups, inside_warnings } } fn fix(id: &'static str, label: &str, source_change: SourceChange, target: TextRange) -> Assist { diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index ea18b89c5c9..0139c04af89 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -6413,7 +6413,7 @@ fn hover_feature() { by the codegen backend, but not the MIR inliner. ```rust - #![feature(rustc_attrs)] + #![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] @@ -6423,7 +6423,7 @@ fn hover_feature() { Since these are just regular functions, it is perfectly ok to create the intrinsic twice: ```rust - #![feature(rustc_attrs)] + #![feature(intrinsics)] #![allow(internal_features)] #[rustc_intrinsic] diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index c960b88a3e9..d8dc9ca32a9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -132,11 +132,9 @@ pub use ide_db::{ search::{ReferenceCategory, SearchScope}, source_change::{FileSystemEdit, SnippetEdit, SourceChange}, symbol_index::Query, - FileId, FilePosition, FileRange, RootDatabase, SymbolKind, -}; -pub use ide_diagnostics::{ - Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode, Severity, + FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind, }; +pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode}; pub use ide_ssr::SsrError; pub use span::Edition; pub use syntax::{TextRange, TextSize}; diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml index d5255665b46..3629d275c0c 100644 --- a/src/tools/rust-analyzer/crates/parser/Cargo.toml +++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml @@ -18,6 +18,8 @@ ra-ap-rustc_lexer.workspace = true limit.workspace = true tracing = { workspace = true, optional = true } +edition.workspace = true + [dev-dependencies] expect-test = "1.4.0" diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/parser/src/edition.rs deleted file mode 100644 index 702b16252d4..00000000000 --- a/src/tools/rust-analyzer/crates/parser/src/edition.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! The edition of the Rust language used in a crate. -// Ideally this would be defined in the span crate, but the dependency chain is all over the place -// wrt to span, parser and syntax. -use std::fmt; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(u8)] -pub enum Edition { - Edition2015, - Edition2018, - Edition2021, - Edition2024, -} - -impl Edition { - pub const DEFAULT: Edition = Edition::Edition2015; - pub const LATEST: Edition = Edition::Edition2024; - pub const CURRENT: Edition = Edition::Edition2021; - /// The current latest stable edition, note this is usually not the right choice in code. - pub const CURRENT_FIXME: Edition = Edition::Edition2021; - - pub fn at_least_2024(self) -> bool { - self >= Edition::Edition2024 - } - - pub fn at_least_2021(self) -> bool { - self >= Edition::Edition2021 - } - - pub fn at_least_2018(self) -> bool { - self >= Edition::Edition2018 - } - - pub fn iter() -> impl Iterator { - [Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024] - .iter() - .copied() - } -} - -#[derive(Debug)] -pub struct ParseEditionError { - invalid_input: String, -} - -impl std::error::Error for ParseEditionError {} -impl fmt::Display for ParseEditionError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "invalid edition: {:?}", self.invalid_input) - } -} - -impl std::str::FromStr for Edition { - type Err = ParseEditionError; - - fn from_str(s: &str) -> Result { - let res = match s { - "2015" => Edition::Edition2015, - "2018" => Edition::Edition2018, - "2021" => Edition::Edition2021, - "2024" => Edition::Edition2024, - _ => return Err(ParseEditionError { invalid_input: s.to_owned() }), - }; - Ok(res) - } -} - -impl fmt::Display for Edition { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match self { - Edition::Edition2015 => "2015", - Edition::Edition2018 => "2018", - Edition::Edition2021 => "2021", - Edition::Edition2024 => "2024", - }) - } -} diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index 679492066a3..e461492cc6f 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -25,7 +25,6 @@ extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; -mod edition; mod event; mod grammar; mod input; @@ -41,8 +40,9 @@ mod tests; pub(crate) use token_set::TokenSet; +pub use edition::Edition; + pub use crate::{ - edition::Edition, input::Input, lexed_str::LexedStr, output::{Output, Step}, diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml index 4bc1821ee5e..01ad3336311 100644 --- a/src/tools/rust-analyzer/xtask/Cargo.toml +++ b/src/tools/rust-analyzer/xtask/Cargo.toml @@ -21,6 +21,7 @@ quote = "1.0.20" ungrammar = "1.16.1" either.workspace = true itertools.workspace = true +edition.workspace = true # Avoid adding more dependencies to this crate [lints] diff --git a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs index f097b5817be..b1a7c2fb27e 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs @@ -1,7 +1,15 @@ //! Generates descriptor structures for unstable features from the unstable book //! and lints from rustc, rustdoc, and clippy. -use std::{borrow::Cow, fs, path::Path}; +#![allow(clippy::disallowed_types)] +use std::{ + collections::{hash_map, HashMap}, + fs, + path::Path, + str::FromStr, +}; + +use edition::Edition; use stdx::format_to; use xshell::{cmd, Shell}; @@ -36,10 +44,17 @@ pub(crate) fn generate(check: bool) { let mut contents = String::from( r" +use span::Edition; + +use crate::Severity; + #[derive(Clone)] pub struct Lint { pub label: &'static str, pub description: &'static str, + pub default_severity: Severity, + pub warn_since: Option, + pub deny_since: Option, } pub struct LintGroup { @@ -68,7 +83,7 @@ pub struct LintGroup { let lints_json = project_root().join("./target/clippy_lints.json"); cmd!( sh, - "curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}" + "curl https://rust-lang.github.io/rust-clippy/stable/lints.json --output {lints_json}" ) .run() .unwrap(); @@ -85,6 +100,48 @@ pub struct LintGroup { ); } +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +enum Severity { + Allow, + Warn, + Deny, +} + +impl std::fmt::Display for Severity { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Severity::{}", + match self { + Severity::Allow => "Allow", + Severity::Warn => "Warning", + Severity::Deny => "Error", + } + ) + } +} + +impl FromStr for Severity { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "allow" => Ok(Self::Allow), + "warn" => Ok(Self::Warn), + "deny" => Ok(Self::Deny), + _ => Err("invalid severity"), + } + } +} + +#[derive(Debug)] +struct Lint { + description: String, + default_severity: Severity, + warn_since: Option, + deny_since: Option, +} + /// Parses the output of `rustdoc -Whelp` and prints `Lint` and `LintGroup` constants into `buf`. /// /// As of writing, the output of `rustc -Whelp` (not rustdoc) has the following format: @@ -108,52 +165,203 @@ pub struct LintGroup { /// `rustdoc -Whelp` (and any other custom `rustc` driver) adds another two /// tables after the `rustc` ones, with a different title but the same format. fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { - let stdout = cmd!(sh, "rustdoc -Whelp").read().unwrap(); - let lints_pat = "---- ------- -------\n"; - let lint_groups_pat = "---- ---------\n"; - let lints = find_and_slice(&stdout, lints_pat); - let lint_groups = find_and_slice(lints, lint_groups_pat); - let lints_rustdoc = find_and_slice(lint_groups, lints_pat); - let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat); + fn get_lints_as_text( + stdout: &str, + ) -> ( + impl Iterator + '_, + impl Iterator + '_)> + '_, + impl Iterator + '_, + impl Iterator + '_)> + '_, + ) { + let lints_pat = "---- ------- -------\n"; + let lint_groups_pat = "---- ---------\n"; + let lints = find_and_slice(stdout, lints_pat); + let lint_groups = find_and_slice(lints, lint_groups_pat); + let lints_rustdoc = find_and_slice(lint_groups, lints_pat); + let lint_groups_rustdoc = find_and_slice(lints_rustdoc, lint_groups_pat); + + let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); + let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap(); + (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap()) + }); + let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); + let label = name.trim().replace('-', "_"); + let lint = Lint { + description: format!("lint group for: {}", lints.trim()), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + let children = lints + .split_ascii_whitespace() + .map(|s| s.trim().trim_matches(',').replace('-', "_")); + (label, lint, children) + }); - buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#); - buf.push('\n'); + let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); + let (severity, description) = rest.trim().split_once(char::is_whitespace).unwrap(); + (name.trim().replace('-', "_"), description.trim(), severity.parse().unwrap()) + }); + let lint_groups_rustdoc = + lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { + let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); + let label = name.trim().replace('-', "_"); + let lint = Lint { + description: format!("lint group for: {}", lints.trim()), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + let children = lints + .split_ascii_whitespace() + .map(|s| s.trim().trim_matches(',').replace('-', "_")); + (label, lint, children) + }); - let lints = lints.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); - let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap(); - (name.trim(), Cow::Borrowed(description.trim()), vec![]) - }); - let lint_groups = lint_groups.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); - ( - name.trim(), - format!("lint group for: {}", lints.trim()).into(), - lints - .split_ascii_whitespace() - .map(|s| s.trim().trim_matches(',').replace('-', "_")) - .collect(), - ) - }); + (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) + } - let mut lints = lints.chain(lint_groups).collect::>(); - lints.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); + fn insert_lints<'a>( + edition: Edition, + lints_map: &mut HashMap, + lint_groups_map: &mut HashMap)>, + lints: impl Iterator, + lint_groups: impl Iterator)>, + ) { + for (lint_name, lint_description, lint_severity) in lints { + let lint = lints_map.entry(lint_name).or_insert_with(|| Lint { + description: lint_description.to_owned(), + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }); + if lint_severity == Severity::Warn + && lint.warn_since.is_none() + && lint.default_severity < Severity::Warn + { + lint.warn_since = Some(edition); + } + if lint_severity == Severity::Deny + && lint.deny_since.is_none() + && lint.default_severity < Severity::Deny + { + lint.deny_since = Some(edition); + } + } - for (name, description, ..) in &lints { - push_lint_completion(buf, &name.replace('-', "_"), description); + for (group_name, lint, children) in lint_groups { + match lint_groups_map.entry(group_name) { + hash_map::Entry::Vacant(entry) => { + entry.insert((lint, Vec::from_iter(children))); + } + hash_map::Entry::Occupied(mut entry) => { + // Overwrite, because some groups (such as edition incompatibility) are changed. + *entry.get_mut() = (lint, Vec::from_iter(children)); + } + } + } + } + + fn get_lints( + sh: &Shell, + edition: Edition, + lints_map: &mut HashMap, + lint_groups_map: &mut HashMap)>, + lints_rustdoc_map: &mut HashMap, + lint_groups_rustdoc_map: &mut HashMap)>, + ) { + let edition_str = edition.to_string(); + let stdout = cmd!(sh, "rustdoc +nightly -Whelp -Zunstable-options --edition={edition_str}") + .read() + .unwrap(); + let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&stdout); + + insert_lints(edition, lints_map, lint_groups_map, lints, lint_groups); + insert_lints( + edition, + lints_rustdoc_map, + lint_groups_rustdoc_map, + lints_rustdoc, + lint_groups_rustdoc, + ); + } + + let basic_lints = cmd!(sh, "rustdoc +nightly -Whelp --edition=2015").read().unwrap(); + let (lints, lint_groups, lints_rustdoc, lint_groups_rustdoc) = get_lints_as_text(&basic_lints); + + let mut lints = lints + .map(|(label, description, severity)| { + ( + label, + Lint { + description: description.to_owned(), + default_severity: severity, + warn_since: None, + deny_since: None, + }, + ) + }) + .collect::>(); + let mut lint_groups = lint_groups + .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children)))) + .collect::>(); + let mut lints_rustdoc = lints_rustdoc + .map(|(label, description, severity)| { + ( + label, + Lint { + description: description.to_owned(), + default_severity: severity, + warn_since: None, + deny_since: None, + }, + ) + }) + .collect::>(); + let mut lint_groups_rustdoc = lint_groups_rustdoc + .map(|(label, lint, children)| (label, (lint, Vec::from_iter(children)))) + .collect::>(); + + for edition in Edition::iter().skip(1) { + get_lints( + sh, + edition, + &mut lints, + &mut lint_groups, + &mut lints_rustdoc, + &mut lint_groups_rustdoc, + ); + } + + let mut lints = Vec::from_iter(lints); + lints.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lint_groups = Vec::from_iter(lint_groups); + lint_groups.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lints_rustdoc = Vec::from_iter(lints_rustdoc); + lints_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + let mut lint_groups_rustdoc = Vec::from_iter(lint_groups_rustdoc); + lint_groups_rustdoc.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + + buf.push_str(r#"pub const DEFAULT_LINTS: &[Lint] = &["#); + buf.push('\n'); + + for (name, lint) in &lints { + push_lint_completion(buf, name, lint); + } + for (name, (group, _)) in &lint_groups { + push_lint_completion(buf, name, group); } buf.push_str("];\n\n"); buf.push_str(r#"pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &["#); - for (name, description, children) in &lints { - if !children.is_empty() { - // HACK: warnings is emitted with a general description, not with its members - if name == &"warnings" { - push_lint_group(buf, name, description, &Vec::new()); - continue; - } - push_lint_group(buf, &name.replace('-', "_"), description, children); + for (name, (lint, children)) in &lint_groups { + if name == "warnings" { + continue; } + push_lint_group(buf, name, lint, children); } buf.push('\n'); buf.push_str("];\n"); @@ -164,37 +372,17 @@ fn generate_lint_descriptor(sh: &Shell, buf: &mut String) { buf.push_str(r#"pub const RUSTDOC_LINTS: &[Lint] = &["#); buf.push('\n'); - let lints_rustdoc = lints_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, rest) = line.trim().split_once(char::is_whitespace).unwrap(); - let (_default_level, description) = rest.trim().split_once(char::is_whitespace).unwrap(); - (name.trim(), Cow::Borrowed(description.trim()), vec![]) - }); - let lint_groups_rustdoc = - lint_groups_rustdoc.lines().take_while(|l| !l.is_empty()).map(|line| { - let (name, lints) = line.trim().split_once(char::is_whitespace).unwrap(); - ( - name.trim(), - format!("lint group for: {}", lints.trim()).into(), - lints - .split_ascii_whitespace() - .map(|s| s.trim().trim_matches(',').replace('-', "_")) - .collect(), - ) - }); - - let mut lints_rustdoc = lints_rustdoc.chain(lint_groups_rustdoc).collect::>(); - lints_rustdoc.sort_by(|(ident, ..), (ident2, ..)| ident.cmp(ident2)); - - for (name, description, ..) in &lints_rustdoc { - push_lint_completion(buf, &name.replace('-', "_"), description) + for (name, lint) in &lints_rustdoc { + push_lint_completion(buf, name, lint); + } + for (name, (group, _)) in &lint_groups_rustdoc { + push_lint_completion(buf, name, group); } buf.push_str("];\n\n"); buf.push_str(r#"pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &["#); - for (name, description, children) in &lints_rustdoc { - if !children.is_empty() { - push_lint_group(buf, &name.replace('-', "_"), description, children); - } + for (name, (lint, children)) in &lint_groups_rustdoc { + push_lint_group(buf, name, lint, children); } buf.push('\n'); buf.push_str("];\n"); @@ -228,13 +416,19 @@ fn generate_feature_descriptor(buf: &mut String, src_dir: &Path) { buf.push_str(r#"pub const FEATURES: &[Lint] = &["#); for (feature_ident, doc) in features.into_iter() { - push_lint_completion(buf, &feature_ident, &doc) + let lint = Lint { + description: doc, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_completion(buf, &feature_ident, &lint); } buf.push('\n'); buf.push_str("];\n"); } -#[derive(Default)] +#[derive(Debug, Default)] struct ClippyLint { help: String, id: String, @@ -295,8 +489,14 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) { buf.push('\n'); for clippy_lint in clippy_lints.into_iter() { let lint_ident = format!("clippy::{}", clippy_lint.id); - let doc = clippy_lint.help; - push_lint_completion(buf, &lint_ident, &doc); + let lint = Lint { + description: clippy_lint.help, + // Allow clippy lints by default, not all users want them. + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_completion(buf, &lint_ident, &lint); } buf.push_str("];\n"); @@ -306,33 +506,59 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) { if !children.is_empty() { let lint_ident = format!("clippy::{id}"); let description = format!("lint group for: {}", children.join(", ")); - push_lint_group(buf, &lint_ident, &description, &children); + let lint = Lint { + description, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }; + push_lint_group(buf, &lint_ident, &lint, &children); } } buf.push('\n'); buf.push_str("];\n"); } -fn push_lint_completion(buf: &mut String, label: &str, description: &str) { +fn push_lint_completion(buf: &mut String, name: &str, lint: &Lint) { format_to!( buf, r###" Lint {{ label: "{}", description: r##"{}"##, - }},"###, - label, - description, + default_severity: {}, + warn_since: "###, + name, + lint.description, + lint.default_severity, + ); + match lint.warn_since { + Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"), + None => buf.push_str("None"), + } + format_to!( + buf, + r###", + deny_since: "### + ); + match lint.deny_since { + Some(edition) => format_to!(buf, "Some(Edition::Edition{edition})"), + None => buf.push_str("None"), + } + format_to!( + buf, + r###", + }},"### ); } -fn push_lint_group(buf: &mut String, label: &str, description: &str, children: &[String]) { +fn push_lint_group(buf: &mut String, name: &str, lint: &Lint, children: &[String]) { buf.push_str( r###" LintGroup { lint: "###, ); - push_lint_completion(buf, label, description); + push_lint_completion(buf, name, lint); let children = format!( "&[{}]", -- cgit 1.4.1-3-g733a5 From a63defa6ed1bc6baef3a9b03f4d0fc601bf2eba6 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:04:54 -0500 Subject: feat: Add an assist to extract an expression into a static --- .../ide-assists/src/handlers/extract_variable.rs | 596 +++++++++++++++++---- .../rust-analyzer/crates/ide-assists/src/tests.rs | 192 ++++++- .../crates/ide-assists/src/tests/generated.rs | 18 + 3 files changed, 686 insertions(+), 120 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 6670eac6a7a..a8d71ed7f4d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -1,14 +1,12 @@ use hir::{HirDisplay, TypeInfo}; -use ide_db::syntax_helpers::suggest_name; +use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name}; use syntax::{ ast::{ self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory, AstNode, }, syntax_editor::Position, - NodeOrToken, - SyntaxKind::{self}, - SyntaxNode, T, + NodeOrToken, SyntaxKind, SyntaxNode, T, }; use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists}; @@ -46,6 +44,23 @@ use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists}; // VAR_NAME * 4; // } // ``` + +// Assist: extract_static +// +// Extracts subexpression into a static. +// +// ``` +// fn main() { +// $0(1 + 2)$0 * 4; +// } +// ``` +// -> +// ``` +// fn main() { +// static $0VAR_NAME: i32 = 1 + 2; +// VAR_NAME * 4; +// } +// ``` pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let node = if ctx.has_empty_selection() { if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) { @@ -114,15 +129,20 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let Some(anchor) = Anchor::from(&to_extract, kind) else { continue; }; + let ty_string = match kind { - ExtractionKind::Constant => { + ExtractionKind::Constant | ExtractionKind::Static => { let Some(ty) = ty.clone() else { continue; }; // We can't mutably reference a const, nor can we define // one using a non-const expression or one of unknown type - if needs_mut || !is_body_const(&ctx.sema, &to_extract_no_ref) || ty.is_unknown() { + if needs_mut + || !is_body_const(&ctx.sema, &to_extract_no_ref) + || ty.is_unknown() + || ty.is_mutable_reference() + { continue; } @@ -135,92 +155,111 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op _ => "".to_owned(), }; - acc.add(kind.assist_id(), kind.label(), target, |edit| { - let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract); - - let make = SyntaxFactory::new(); - let mut editor = edit.make_editor(&expr_replace); + acc.add_group( + &GroupLabel("Extract into...".to_owned()), + kind.assist_id(), + kind.label(), + target, + |edit| { + let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract); - let pat_name = make.name(&var_name); - let name_expr = make.expr_path(make::ext::ident_path(&var_name)); + let make = SyntaxFactory::new(); + let mut editor = edit.make_editor(&expr_replace); - if let Some(cap) = ctx.config.snippet_cap { - let tabstop = edit.make_tabstop_before(cap); - editor.add_annotation(pat_name.syntax().clone(), tabstop); - } + let pat_name = make.name(&var_name); + let name_expr = make.expr_path(make::ext::ident_path(&var_name)); - let initializer = match ty.as_ref().filter(|_| needs_ref) { - Some(receiver_type) if receiver_type.is_mutable_reference() => { - make.expr_ref(to_extract_no_ref.clone(), true) + if let Some(cap) = ctx.config.snippet_cap { + let tabstop = edit.make_tabstop_before(cap); + editor.add_annotation(pat_name.syntax().clone(), tabstop); } - Some(receiver_type) if receiver_type.is_reference() => { - make.expr_ref(to_extract_no_ref.clone(), false) - } - _ => to_extract_no_ref.clone(), - }; - let new_stmt: ast::Stmt = match kind { - ExtractionKind::Variable => { - let ident_pat = make.ident_pat(false, needs_mut, pat_name); - make.let_stmt(ident_pat.into(), None, Some(initializer)).into() - } - ExtractionKind::Constant => { - let ast_ty = make.ty(&ty_string); - ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer)).into() - } - }; - - match &anchor { - Anchor::Before(place) => { - let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token()); - let indent_to = IndentLevel::from_node(place); - - // Adjust ws to insert depending on if this is all inline or on separate lines - let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) { - format!("\n{indent_to}") - } else { - " ".to_owned() - }; - - editor.insert_all( - Position::before(place), - vec![ - new_stmt.syntax().clone().into(), - make::tokens::whitespace(&trailing_ws).into(), - ], - ); - - editor.replace(expr_replace, name_expr.syntax()); - } - Anchor::Replace(stmt) => { - cov_mark::hit!(test_extract_var_expr_stmt); + let initializer = match ty.as_ref().filter(|_| needs_ref) { + Some(receiver_type) if receiver_type.is_mutable_reference() => { + make.expr_ref(to_extract_no_ref.clone(), true) + } + Some(receiver_type) if receiver_type.is_reference() => { + make.expr_ref(to_extract_no_ref.clone(), false) + } + _ => to_extract_no_ref.clone(), + }; + + let new_stmt: ast::Stmt = match kind { + ExtractionKind::Variable => { + let ident_pat = make.ident_pat(false, needs_mut, pat_name); + make.let_stmt(ident_pat.into(), None, Some(initializer)).into() + } + ExtractionKind::Constant => { + let ast_ty = make.ty(&ty_string); + ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer)) + .into() + } + ExtractionKind::Static => { + let ast_ty = make.ty(&ty_string); + ast::Item::Static(make.item_static( + None, + false, + false, + pat_name, + ast_ty, + Some(initializer), + )) + .into() + } + }; + + match &anchor { + Anchor::Before(place) => { + let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token()); + let indent_to = IndentLevel::from_node(place); + + // Adjust ws to insert depending on if this is all inline or on separate lines + let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) { + format!("\n{indent_to}") + } else { + " ".to_owned() + }; + + editor.insert_all( + Position::before(place), + vec![ + new_stmt.syntax().clone().into(), + make::tokens::whitespace(&trailing_ws).into(), + ], + ); - editor.replace(stmt.syntax(), new_stmt.syntax()); - } - Anchor::WrapInBlock(to_wrap) => { - let indent_to = to_wrap.indent_level(); - - let block = if to_wrap.syntax() == &expr_replace { - // Since `expr_replace` is the same that needs to be wrapped in a block, - // we can just directly replace it with a block - make.block_expr([new_stmt], Some(name_expr)) - } else { - // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`. editor.replace(expr_replace, name_expr.syntax()); - make.block_expr([new_stmt], Some(to_wrap.clone())) - }; + } + Anchor::Replace(stmt) => { + cov_mark::hit!(test_extract_var_expr_stmt); - editor.replace(to_wrap.syntax(), block.syntax()); + editor.replace(stmt.syntax(), new_stmt.syntax()); + } + Anchor::WrapInBlock(to_wrap) => { + let indent_to = to_wrap.indent_level(); + + let block = if to_wrap.syntax() == &expr_replace { + // Since `expr_replace` is the same that needs to be wrapped in a block, + // we can just directly replace it with a block + make.block_expr([new_stmt], Some(name_expr)) + } else { + // `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`. + editor.replace(expr_replace, name_expr.syntax()); + make.block_expr([new_stmt], Some(to_wrap.clone())) + }; - // fixup indentation of block - block.indent(indent_to); + editor.replace(to_wrap.syntax(), block.syntax()); + + // fixup indentation of block + block.indent(indent_to); + } } - } - editor.add_mappings(make.finish_with_mappings()); - edit.add_file_edits(ctx.file_id(), editor); - edit.rename(); - }); + editor.add_mappings(make.finish_with_mappings()); + edit.add_file_edits(ctx.file_id(), editor); + edit.rename(); + }, + ); } Some(()) @@ -251,15 +290,18 @@ fn valid_target_expr(node: SyntaxNode) -> Option { enum ExtractionKind { Variable, Constant, + Static, } impl ExtractionKind { - const ALL: &'static [ExtractionKind] = &[ExtractionKind::Variable, ExtractionKind::Constant]; + const ALL: &'static [ExtractionKind] = + &[ExtractionKind::Variable, ExtractionKind::Constant, ExtractionKind::Static]; fn assist_id(&self) -> AssistId { let s = match self { ExtractionKind::Variable => "extract_variable", ExtractionKind::Constant => "extract_constant", + ExtractionKind::Static => "extract_static", }; AssistId(s, AssistKind::RefactorExtract) @@ -269,6 +311,7 @@ impl ExtractionKind { match self { ExtractionKind::Variable => "Extract into variable", ExtractionKind::Constant => "Extract into constant", + ExtractionKind::Static => "Extract into static", } } @@ -291,7 +334,7 @@ impl ExtractionKind { let var_name = match self { ExtractionKind::Variable => var_name, - ExtractionKind::Constant => var_name.to_uppercase(), + ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(), }; (var_name, expr_replace) @@ -351,7 +394,7 @@ impl Anchor { }); match kind { - ExtractionKind::Constant if result.is_none() => { + ExtractionKind::Constant | ExtractionKind::Static if result.is_none() => { to_extract.syntax().ancestors().find_map(|node| { let item = ast::Item::cast(node.clone())?; let parent = item.syntax().parent()?; @@ -381,21 +424,6 @@ mod tests { use super::*; - #[test] - fn now_bad() { - // unknown type - check_assist_not_applicable_by_label( - extract_variable, - r#" -fn main() { - let a = Some(2); - a.is_some();$0 -} -"#, - "Extract into constant", - ); - } - #[test] fn extract_var_simple_without_select() { check_assist_by_label( @@ -604,7 +632,102 @@ fn main() { } #[test] - fn extract_var_unit_expr_without_select_not_applicable() { + fn extract_static_simple_without_select() { + check_assist_by_label( + extract_variable, + r#" +fn main() -> i32 { + if true { + 1 + } else { + 2 + }$0 +} +"#, + r#" +fn main() -> i32 { + static $0VAR_NAME: i32 = if true { + 1 + } else { + 2 + }; + VAR_NAME +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo() -> i32 { 1 } +fn main() { + foo();$0 +} +"#, + r#" +const fn foo() -> i32 { 1 } +fn main() { + static $0FOO: i32 = foo(); +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + "hello"$0; +} +"#, + r#" +fn main() { + static $0VAR_NAME: &str = "hello"; +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + 1 + 2$0; +} +"#, + r#" +fn main() { + static $0VAR_NAME: i32 = 1 + 2; +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +fn main() { + match () { + () if true => 1, + _ => 2, + };$0 +} +"#, + r#" +fn main() { + static $0VAR_NAME: i32 = match () { + () if true => 1, + _ => 2, + }; +} +"#, + "Extract into static", + ); + } + + #[test] + fn dont_extract_unit_expr_without_select() { check_assist_not_applicable( extract_variable, r#" @@ -664,7 +787,24 @@ fn foo() { } #[test] - fn extract_var_in_comment_is_not_applicable() { + fn extract_static_simple() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + foo($01 + 1$0); +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; + foo(VAR_NAME); +}"#, + "Extract into static", + ); + } + + #[test] + fn dont_extract_in_comment() { cov_mark::check!(extract_var_in_comment_is_not_applicable); check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#); } @@ -732,6 +872,38 @@ fn foo() { ); } + #[test] + fn extract_static_expr_stmt() { + cov_mark::check!(test_extract_var_expr_stmt); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0 1 + 1$0; +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; +}"#, + "Extract into static", + ); + // This is hilarious but as far as I know, it's valid + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $0{ let x = 0; x }$0; + something_else(); +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = { let x = 0; x }; + something_else(); +}"#, + "Extract into static", + ); + } + #[test] fn extract_var_part_of_expr_stmt() { check_assist_by_label( @@ -766,6 +938,23 @@ fn foo() { ); } + #[test] + fn extract_static_part_of_expr_stmt() { + check_assist_by_label( + extract_variable, + r#" +fn foo() { + $01$0 + 1; +}"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1; + VAR_NAME + 1; +}"#, + "Extract into static", + ); + } + #[test] fn extract_var_last_expr() { cov_mark::check!(test_extract_var_last_expr); @@ -852,6 +1041,49 @@ const fn bar(i: i32) -> i32 { ) } + #[test] + fn extract_static_last_expr() { + cov_mark::check!(test_extract_var_last_expr); + check_assist_by_label( + extract_variable, + r#" +fn foo() { + bar($01 + 1$0) +} +"#, + r#" +fn foo() { + static $0VAR_NAME: i32 = 1 + 1; + bar(VAR_NAME) +} +"#, + "Extract into static", + ); + check_assist_by_label( + extract_variable, + r#" +fn foo() -> i32 { + $0bar(1 + 1)$0 +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + r#" +fn foo() -> i32 { + static $0BAR: i32 = bar(1 + 1); + BAR +} + +const fn bar(i: i32) -> i32 { + i +} +"#, + "Extract into static", + ) + } + #[test] fn extract_var_in_match_arm_no_block() { cov_mark::check!(test_extract_var_in_match_arm_no_block); @@ -1427,6 +1659,30 @@ fn main() { "#, "Extract into constant", ); + + check_assist_by_label( + extract_variable, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + let _ = $0vec![]$0; +} +"#, + r#" +struct Vec; +macro_rules! vec { + () => {Vec} +} +fn main() { + static $0VEC: Vec = vec![]; + let _ = VEC; +} +"#, + "Extract into static", + ); } #[test] @@ -1589,6 +1845,109 @@ fn bar() { ); } + #[test] + fn extract_static_no_block_body() { + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +const FOO: i32 = foo($0100$0); +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +static $0X: i32 = 100; +const FOO: i32 = foo(X); +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +mod foo { + enum Foo { + Bar, + Baz = $042$0, + } +} +"#, + r#" +mod foo { + static $0VAR_NAME: isize = 42; + enum Foo { + Bar, + Baz = VAR_NAME, + } +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + const World = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +trait Hello { + const World: i32; +} + +struct Bar; +impl Hello for Bar { + static $0X: i32 = 42; + const World = foo(X); +} +"#, + "Extract into static", + ); + + check_assist_by_label( + extract_variable, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + const BAZ: i32 = foo($042$0); +} +"#, + r#" +const fn foo(x: i32) -> i32 { + x +} + +fn bar() { + static $0X: i32 = 42; + const BAZ: i32 = foo(X); +} +"#, + "Extract into static", + ); + } + #[test] fn extract_var_mutable_reference_parameter() { check_assist_by_label( @@ -1641,7 +2000,28 @@ impl Vec { fn foo(s: &mut S) { $0s.vec$0.push(0); }"#, - "Extract into const", + "Extract into constant", + ); + } + + #[test] + fn dont_extract_static_mutable_reference_parameter() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +struct S { + vec: Vec +} + +struct Vec; +impl Vec { + fn push(&mut self, _:usize) {} +} + +fn foo(s: &mut S) { + $0s.vec$0.push(0); +}"#, + "Extract into static", ); } @@ -2030,6 +2410,18 @@ fn foo() { ); } + #[test] + fn dont_extract_static_for_mutable_borrow() { + check_assist_not_applicable_by_label( + extract_variable, + r#" +fn foo() { + let v = &mut $00$0; +}"#, + "Extract into static", + ); + } + #[test] fn generates_no_ref_on_calls() { check_assist_by_label( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 4f7f03764f5..e517dd46824 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -362,8 +362,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base - Extract into variable - Extract into constant + Extract into... Extract into function Replace if let with match "#]] @@ -392,8 +391,7 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base - Extract into variable - Extract into constant + Extract into... Extract into function Replace if let with match "#]] @@ -407,8 +405,7 @@ pub fn test_some_range(a: int) -> bool { let expected = labels(&assists); expect![[r#" - Extract into variable - Extract into constant + Extract into... Extract into function "#]] .assert_eq(&expected); @@ -443,7 +440,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); - assert_eq!(3, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -454,7 +451,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -470,7 +471,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into constant", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -478,6 +483,26 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_constant_assist); + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -505,7 +530,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(3, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -516,7 +541,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -532,7 +561,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into constant", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -540,6 +573,26 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_constant_assist); + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -567,7 +620,7 @@ pub fn test_some_range(a: int) -> bool { }), frange.into(), ); - assert_eq!(3, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -578,7 +631,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { @@ -637,7 +694,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into constant", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -645,6 +706,26 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_constant_assist); + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: None, + command: None, + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { @@ -664,7 +745,7 @@ pub fn test_some_range(a: int) -> bool { { let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into()); - assert_eq!(3, assists.len()); + assert_eq!(4, assists.len()); let mut assists = assists.into_iter(); let extract_into_variable_assist = assists.next().unwrap(); @@ -675,7 +756,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into variable", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { @@ -734,7 +819,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into constant", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { @@ -789,6 +878,73 @@ pub fn test_some_range(a: int) -> bool { "#]] .assert_debug_eq(&extract_into_constant_assist); + let extract_into_static_assist = assists.next().unwrap(); + expect![[r#" + Assist { + id: AssistId( + "extract_static", + RefactorExtract, + ), + label: "Extract into static", + group: Some( + GroupLabel( + "Extract into...", + ), + ), + target: 59..60, + source_change: Some( + SourceChange { + source_file_edits: { + FileId( + 0, + ): ( + TextEdit { + indels: [ + Indel { + insert: "static", + delete: 45..47, + }, + Indel { + insert: "VAR_NAME:", + delete: 48..60, + }, + Indel { + insert: "i32", + delete: 61..81, + }, + Indel { + insert: "=", + delete: 82..86, + }, + Indel { + insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", + delete: 87..108, + }, + ], + }, + Some( + SnippetEdit( + [ + ( + 0, + 52..52, + ), + ], + ), + ), + ), + }, + file_system_edits: [], + is_snippet: true, + }, + ), + command: Some( + Rename, + ), + } + "#]] + .assert_debug_eq(&extract_into_static_assist); + let extract_into_function_assist = assists.next().unwrap(); expect![[r#" Assist { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index c1799b48ed4..87c3d166ee6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -1024,6 +1024,24 @@ fn bar(name: i32) -> i32 { ) } +#[test] +fn doctest_extract_static() { + check_doc_test( + "extract_static", + r#####" +fn main() { + $0(1 + 2)$0 * 4; +} +"#####, + r#####" +fn main() { + static $0VAR_NAME: i32 = 1 + 2; + VAR_NAME * 4; +} +"#####, + ) +} + #[test] fn doctest_extract_struct_from_enum_variant() { check_doc_test( -- cgit 1.4.1-3-g733a5 From d16909ca9120df2272083840c6b664c448cfdab4 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:11:20 -0500 Subject: minor: Group `extract_function` with other extraction assists --- .../ide-assists/src/handlers/extract_function.rs | 4 +++- .../rust-analyzer/crates/ide-assists/src/tests.rs | 27 ++++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 6937d33ebc1..2e363b0b62c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -7,6 +7,7 @@ use hir::{ TypeInfo, TypeParam, }; use ide_db::{ + assists::GroupLabel, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::mod_path_to_ast, @@ -104,7 +105,8 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let scope = ImportScope::find_insert_use_container(&node, &ctx.sema)?; - acc.add( + acc.add_group( + &GroupLabel("Extract into...".to_owned()), AssistId("extract_function", crate::AssistKind::RefactorExtract), "Extract into function", target_range, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index e517dd46824..0b1ff87c5c2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -363,7 +363,6 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base Extract into... - Extract into function Replace if let with match "#]] .assert_eq(&expected); @@ -392,7 +391,6 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Convert integer base Extract into... - Extract into function Replace if let with match "#]] .assert_eq(&expected); @@ -406,7 +404,6 @@ pub fn test_some_range(a: int) -> bool { expect![[r#" Extract into... - Extract into function "#]] .assert_eq(&expected); } @@ -511,7 +508,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -601,7 +602,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -734,7 +739,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: None, command: None, @@ -953,7 +962,11 @@ pub fn test_some_range(a: int) -> bool { RefactorExtract, ), label: "Extract into function", - group: None, + group: Some( + GroupLabel( + "Extract into...", + ), + ), target: 59..60, source_change: Some( SourceChange { -- cgit 1.4.1-3-g733a5 From ef879f7a740eeb7817322234e2618aeffc6284eb Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Wed, 11 Dec 2024 14:35:36 -0500 Subject: Fix publish workflow link in manual --- src/tools/rust-analyzer/docs/user/manual.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc index 246ebdab2c9..da2aa4eae4e 100644 --- a/src/tools/rust-analyzer/docs/user/manual.adoc +++ b/src/tools/rust-analyzer/docs/user/manual.adoc @@ -580,7 +580,7 @@ Unfortunately, it downloads an old version of `rust-analyzer`, but you can set t There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically. -For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml[the publish workflow]. +For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/autopublish.yaml[the publish workflow]. === Zed -- cgit 1.4.1-3-g733a5 From 41bd955f8eec2c879992feb87da2d17083bce4d2 Mon Sep 17 00:00:00 2001 From: 1hakusai1 <1hakusai1@gmail.com> Date: Thu, 12 Dec 2024 18:55:14 +0900 Subject: Generate implementation with items even if snippet text edit is disabled --- .../handlers/replace_derive_with_manual_impl.rs | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 248f18789ce..2dec876215c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -139,7 +139,7 @@ fn add_assist( let trait_path = make::ty_path(replace_trait_path.clone()); match (ctx.config.snippet_cap, impl_def_with_items) { - (None, _) => { + (None, None) => { let impl_def = generate_trait_impl(adt, trait_path); ted::insert_all( @@ -147,6 +147,12 @@ fn add_assist( vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], ); } + (None, Some((impl_def, _))) => { + ted::insert_all( + insert_after, + vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], + ); + } (Some(cap), None) => { let impl_def = generate_trait_impl(adt, trait_path); @@ -272,7 +278,7 @@ fn update_attribute( #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_not_applicable}; + use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable}; use super::*; @@ -297,6 +303,30 @@ impl core::fmt::Debug for Foo { f.debug_struct("Foo").field("bar", &self.bar).finish() } } +"#, + ) + } + #[test] + fn add_custom_impl_without_snippet() { + check_assist_no_snippet_cap( + replace_derive_with_manual_impl, + r#" +//- minicore: fmt, derive +#[derive(Debu$0g)] +struct Foo { + bar: String, +} +"#, + r#" +struct Foo { + bar: String, +} + +impl core::fmt::Debug for Foo { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Foo").field("bar", &self.bar).finish() + } +} "#, ) } -- cgit 1.4.1-3-g733a5 From 0815dfb236107ead88ee69ffbc5e4f210c7c45b7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 12:58:18 +0100 Subject: fix: Fix sourceroot construction for virtual manifests --- .../rust-analyzer/crates/load-cargo/src/lib.rs | 46 +++------------------- .../crates/project-model/src/cargo_workspace.rs | 34 +++++++++++----- .../crates/project-model/src/manifest_path.rs | 6 +++ .../crates/project-model/src/workspace.rs | 45 ++++++++++++--------- .../crates/rust-analyzer/src/bin/main.rs | 4 +- .../crates/rust-analyzer/src/config.rs | 4 +- .../crates/rust-analyzer/src/global_state.rs | 11 ++++-- 7 files changed, 75 insertions(+), 75 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index cf26845b119..aa64f570ed5 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -15,9 +15,7 @@ use ide_db::{ }; use itertools::Itertools; use proc_macro_api::{MacroDylib, ProcMacroServer}; -use project_model::{ - CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace, ProjectWorkspaceKind, -}; +use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ file_set::FileSetConfig, @@ -244,6 +242,9 @@ impl ProjectFolders { } } + if dirs.include.is_empty() { + continue; + } vfs::loader::Entry::Directories(dirs) }; @@ -258,43 +259,6 @@ impl ProjectFolders { fsc.add_file_set(file_set_roots) } - // register the workspace manifest as well, note that this currently causes duplicates for - // non-virtual cargo workspaces! We ought to fix that - for ws in workspaces.iter() { - let mut file_set_roots: Vec = vec![]; - let mut entries = vec![]; - - if let Some(manifest) = ws.manifest().map(|it| it.to_path_buf()) { - file_set_roots.push(VfsPath::from(manifest.to_owned())); - entries.push(manifest.to_owned()); - } - - for buildfile in ws.buildfiles() { - file_set_roots.push(VfsPath::from(buildfile.to_owned())); - entries.push(buildfile.to_owned()); - } - - // In case of detached files we do **not** look for a rust-analyzer.toml. - if !matches!(ws.kind, ProjectWorkspaceKind::DetachedFile { .. }) { - let ws_root = ws.workspace_root(); - let ratoml_path = { - let mut p = ws_root.to_path_buf(); - p.push("rust-analyzer.toml"); - p - }; - file_set_roots.push(VfsPath::from(ratoml_path.to_owned())); - entries.push(ratoml_path.to_owned()); - } - - if !file_set_roots.is_empty() { - let entry = vfs::loader::Entry::Files(entries); - res.watch.push(res.load.len()); - res.load.push(entry); - local_filesets.push(fsc.len() as u64); - fsc.add_file_set(file_set_roots) - } - } - if let Some(user_config_path) = user_config_dir_path { let ratoml_path = { let mut p = user_config_path.to_path_buf(); @@ -303,7 +267,7 @@ impl ProjectFolders { }; let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())]; - let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]); + let entry = vfs::loader::Entry::Files(vec![ratoml_path]); res.watch.push(res.load.len()); res.load.push(entry); diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index cb5738a3b40..4ae3426ed97 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -33,6 +33,7 @@ pub struct CargoWorkspace { workspace_root: AbsPathBuf, target_directory: AbsPathBuf, manifest_path: ManifestPath, + is_virtual_workspace: bool, } impl ops::Index for CargoWorkspace { @@ -384,13 +385,20 @@ impl CargoWorkspace { .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command())) } - pub fn new(mut meta: cargo_metadata::Metadata, manifest_path: ManifestPath) -> CargoWorkspace { + pub fn new( + mut meta: cargo_metadata::Metadata, + ws_manifest_path: ManifestPath, + ) -> CargoWorkspace { let mut pkg_by_id = FxHashMap::default(); let mut packages = Arena::default(); let mut targets = Arena::default(); let ws_members = &meta.workspace_members; + let workspace_root = AbsPathBuf::assert(meta.workspace_root); + let target_directory = AbsPathBuf::assert(meta.target_directory); + let mut is_virtual_workspace = true; + meta.packages.sort_by(|a, b| a.id.cmp(&b.id)); for meta_pkg in meta.packages { let cargo_metadata::Package { @@ -429,12 +437,13 @@ impl CargoWorkspace { let is_local = source.is_none(); let is_member = ws_members.contains(&id); - let manifest = AbsPathBuf::assert(manifest_path); + let manifest = ManifestPath::try_from(AbsPathBuf::assert(manifest_path)).unwrap(); + is_virtual_workspace &= manifest != ws_manifest_path; let pkg = packages.alloc(PackageData { id: id.repr.clone(), name, version, - manifest: manifest.clone().try_into().unwrap(), + manifest: manifest.clone(), targets: Vec::new(), is_local, is_member, @@ -468,7 +477,7 @@ impl CargoWorkspace { // modified manifest file into a special target dir which is then used as // the source path. We don't want that, we want the original here so map it // back - manifest.clone() + manifest.clone().into() } else { AbsPathBuf::assert(src_path) }, @@ -493,11 +502,14 @@ impl CargoWorkspace { packages[source].active_features.extend(node.features); } - let workspace_root = AbsPathBuf::assert(meta.workspace_root); - - let target_directory = AbsPathBuf::assert(meta.target_directory); - - CargoWorkspace { packages, targets, workspace_root, target_directory, manifest_path } + CargoWorkspace { + packages, + targets, + workspace_root, + target_directory, + manifest_path: ws_manifest_path, + is_virtual_workspace, + } } pub fn packages(&self) -> impl ExactSizeIterator + '_ { @@ -579,6 +591,10 @@ impl CargoWorkspace { fn is_unique(&self, name: &str) -> bool { self.packages.iter().filter(|(_, v)| v.name == name).count() == 1 } + + pub fn is_virtual_workspace(&self) -> bool { + self.is_virtual_workspace + } } fn find_list_of_build_targets( diff --git a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs index a8be5dff7b6..a72dab60752 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/manifest_path.rs @@ -29,6 +29,12 @@ impl TryFrom for ManifestPath { } } +impl From for AbsPathBuf { + fn from(it: ManifestPath) -> Self { + it.file + } +} + impl ManifestPath { // Shadow `parent` from `Deref`. pub fn parent(&self) -> &AbsPath { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 988eff9be44..71ddee30910 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -11,8 +11,9 @@ use base_db::{ }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; use intern::{sym, Symbol}; +use itertools::Itertools; use paths::{AbsPath, AbsPathBuf}; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashMap; use semver::Version; use span::{Edition, FileId}; use toolchain::Tool; @@ -41,7 +42,9 @@ pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option, + /// Directories to exclude pub exclude: Vec, } @@ -553,17 +556,6 @@ impl ProjectWorkspace { } } - pub fn buildfiles(&self) -> Vec { - match &self.kind { - ProjectWorkspaceKind::Json(project) => project - .crates() - .filter_map(|(_, krate)| krate.build.as_ref().map(|build| build.build_file.clone())) - .map(|build_file| self.workspace_root().join(build_file)) - .collect(), - _ => vec![], - } - } - pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result { self.sysroot.discover_proc_macro_srv() } @@ -608,15 +600,25 @@ impl ProjectWorkspace { match &self.kind { ProjectWorkspaceKind::Json(project) => project .crates() - .map(|(_, krate)| PackageRoot { - is_local: krate.is_workspace_member, - include: krate.include.clone(), - exclude: krate.exclude.clone(), + .map(|(_, krate)| { + let build_files = project + .crates() + .filter_map(|(_, krate)| { + krate.build.as_ref().map(|build| build.build_file.clone()) + }) + // FIXME: PackageRoots dont allow specifying files, only directories + .filter_map(|build_file| { + self.workspace_root().join(build_file).parent().map(ToOwned::to_owned) + }); + PackageRoot { + is_local: krate.is_workspace_member, + include: krate.include.iter().cloned().chain(build_files).collect(), + exclude: krate.exclude.clone(), + } }) - .collect::>() - .into_iter() .chain(mk_sysroot()) - .collect::>(), + .unique() + .collect(), ProjectWorkspaceKind::Cargo { cargo, rustc, @@ -671,6 +673,11 @@ impl ProjectWorkspace { exclude: Vec::new(), }) })) + .chain(cargo.is_virtual_workspace().then(|| PackageRoot { + is_local: true, + include: vec![cargo.workspace_root().to_path_buf()], + exclude: Vec::new(), + })) .collect() } ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index eac33be5664..a753621eca8 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -51,7 +51,9 @@ fn actual_main() -> anyhow::Result { } } - setup_logging(flags.log_file.clone())?; + if let Err(e) = setup_logging(flags.log_file.clone()) { + eprintln!("Failed to setup logging: {e:#}"); + } let verbosity = flags.verbosity(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index bf7aca42faf..40fd294e72a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -827,6 +827,7 @@ impl Config { let mut should_update = false; if let Some(change) = change.user_config_change { + tracing::info!("updating config from user config toml: {:#}", change); if let Ok(table) = toml::from_str(&change) { let mut toml_errors = vec![]; validate_toml_table( @@ -919,7 +920,7 @@ impl Config { RatomlFileKind::Crate => { if let Some(text) = text { let mut toml_errors = vec![]; - tracing::info!("updating ra-toml config: {:#}", text); + tracing::info!("updating ra-toml crate config: {:#}", text); match toml::from_str(&text) { Ok(table) => { validate_toml_table( @@ -961,6 +962,7 @@ impl Config { } RatomlFileKind::Workspace => { if let Some(text) = text { + tracing::info!("updating ra-toml workspace config: {:#}", text); let mut toml_errors = vec![]; match toml::from_str(&text) { Ok(table) => { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 5f835702840..29be53cee1d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -417,8 +417,10 @@ impl GlobalState { }) .collect_vec(); - for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files { + for (file_id, (change_kind, vfs_path)) in modified_ratoml_files { + tracing::info!(%vfs_path, ?change_kind, "Processing rust-analyzer.toml changes"); if vfs_path.as_path() == user_config_abs_path { + tracing::info!(%vfs_path, ?change_kind, "Use config rust-analyzer.toml changes"); change.change_user_config(Some(db.file_text(file_id))); continue; } @@ -430,12 +432,14 @@ impl GlobalState { if !sr.is_library { let entry = if workspace_ratoml_paths.contains(&vfs_path) { + tracing::info!(%vfs_path, ?sr_id, "workspace rust-analyzer.toml changes"); change.change_workspace_ratoml( sr_id, vfs_path.clone(), Some(db.file_text(file_id)), ) } else { + tracing::info!(%vfs_path, ?sr_id, "crate rust-analyzer.toml changes"); change.change_ratoml( sr_id, vfs_path.clone(), @@ -446,7 +450,7 @@ impl GlobalState { if let Some((kind, old_path, old_text)) = entry { // SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins. if old_path < vfs_path { - span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect."); + tracing::error!("Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect."); // Put the old one back in. match kind { RatomlFileKind::Crate => { @@ -459,8 +463,7 @@ impl GlobalState { } } } else { - // Mapping to a SourceRoot should always end up in `Ok` - span!(Level::ERROR, "Mapping to SourceRootId failed."); + tracing::info!(%vfs_path, "Ignoring library rust-analyzer.toml"); } } change.change_source_root_parent_map(self.local_roots_parent_map.clone()); -- cgit 1.4.1-3-g733a5 From 1428cf6032cb70bb8c93d6aafdd05245c48c9be6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 13:20:08 +0100 Subject: Only parse the object file once --- .../crates/proc-macro-srv/src/dylib.rs | 16 +++++++-------- .../crates/proc-macro-srv/src/dylib/version.rs | 24 ++++++++++------------ 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 828d49e6a21..977ca8bafd8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -6,7 +6,6 @@ use proc_macro::bridge; use std::{fmt, fs, io, time::SystemTime}; use libloading::Library; -use memmap2::Mmap; use object::Object; use paths::{Utf8Path, Utf8PathBuf}; use proc_macro_api::ProcMacroKind; @@ -23,8 +22,8 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool { symbol.contains(NEW_REGISTRAR_SYMBOL) } -fn find_registrar_symbol(buffer: &[u8]) -> object::Result> { - Ok(object::File::parse(buffer)? +fn find_registrar_symbol(obj: &object::File<'_>) -> object::Result> { + Ok(obj .exports()? .into_iter() .map(|export| export.name()) @@ -109,15 +108,16 @@ struct ProcMacroLibraryLibloading { impl ProcMacroLibraryLibloading { fn open(path: &Utf8Path) -> Result { - let buffer = unsafe { Mmap::map(&fs::File::open(path)?)? }; + let file = fs::File::open(path)?; + let file = unsafe { memmap2::Mmap::map(&file) }?; + let obj = object::File::parse(&*file) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + let version_info = version::read_dylib_info(&obj)?; let symbol_name = - find_registrar_symbol(&buffer).map_err(invalid_data_err)?.ok_or_else(|| { + find_registrar_symbol(&obj).map_err(invalid_data_err)?.ok_or_else(|| { invalid_data_err(format!("Cannot find registrar symbol in file {path}")) })?; - let version_info = version::read_dylib_info(&buffer)?; - drop(buffer); - let lib = load_library(path).map_err(invalid_data_err)?; let proc_macros = crate::proc_macros::ProcMacros::from_lib( &lib, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs index c1804e4fef7..4e28aaced9b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs @@ -2,7 +2,7 @@ use std::io::{self, Read}; -use object::read::{File as BinaryFile, Object, ObjectSection}; +use object::read::{Object, ObjectSection}; #[derive(Debug)] #[allow(dead_code)] @@ -16,14 +16,14 @@ pub struct RustCInfo { } /// Read rustc dylib information -pub fn read_dylib_info(buffer: &[u8]) -> io::Result { +pub fn read_dylib_info(obj: &object::File<'_>) -> io::Result { macro_rules! err { ($e:literal) => { io::Error::new(io::ErrorKind::InvalidData, $e) }; } - let ver_str = read_version(buffer)?; + let ver_str = read_version(obj)?; let mut items = ver_str.split_whitespace(); let tag = items.next().ok_or_else(|| err!("version format error"))?; if tag != "rustc" { @@ -70,10 +70,8 @@ pub fn read_dylib_info(buffer: &[u8]) -> io::Result { /// This is used inside read_version() to locate the ".rustc" section /// from a proc macro crate's binary file. -fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'a [u8]> { - BinaryFile::parse(dylib_binary) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))? - .section_by_name(section_name) +fn read_section<'a>(obj: &object::File<'a>, section_name: &str) -> io::Result<&'a [u8]> { + obj.section_by_name(section_name) .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "section read error"))? .data() .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) @@ -101,8 +99,8 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&' /// /// Check this issue for more about the bytes layout: /// -pub fn read_version(buffer: &[u8]) -> io::Result { - let dot_rustc = read_section(buffer, ".rustc")?; +pub fn read_version(obj: &object::File<'_>) -> io::Result { + let dot_rustc = read_section(obj, ".rustc")?; // check if magic is valid if &dot_rustc[0..4] != b"rust" { @@ -151,10 +149,10 @@ pub fn read_version(buffer: &[u8]) -> io::Result { #[test] fn test_version_check() { - let info = read_dylib_info(&unsafe { - memmap2::Mmap::map(&std::fs::File::open(crate::proc_macro_test_dylib_path()).unwrap()) - .unwrap() - }) + let info = read_dylib_info( + &object::File::parse(&*std::fs::read(crate::proc_macro_test_dylib_path()).unwrap()) + .unwrap(), + ) .unwrap(); assert_eq!( -- cgit 1.4.1-3-g733a5 From b6b7c573052809609d93ce72d35f84d01fbf23fe Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 13:30:42 +0100 Subject: Fix clippy lints in proc-macro-srv --- src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs | 2 +- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 10 +++++----- .../rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs | 2 +- .../proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 2 +- .../crates/proc-macro-srv/src/server_impl/token_stream.rs | 5 +++-- .../rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 174f9c52462..7095dac348d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -69,7 +69,7 @@ fn run() -> io::Result<()> { let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock()); - let env = EnvSnapshot::new(); + let env = EnvSnapshot::default(); let mut srv = proc_macro_srv::ProcMacroSrv::new(&env); let mut buf = String::new(); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 8e78e6f2e07..85833dab1b0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -13,7 +13,7 @@ #![cfg(any(feature = "sysroot-abi", rust_analyzer))] #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span)] -#![allow(unreachable_pub, internal_features)] +#![allow(unreachable_pub, internal_features, clippy::disallowed_types, clippy::print_stderr)] extern crate proc_macro; #[cfg(feature = "in-rust-tree")] @@ -65,7 +65,7 @@ impl<'env> ProcMacroSrv<'env> { const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; -impl<'env> ProcMacroSrv<'env> { +impl ProcMacroSrv<'_> { pub fn set_span_mode(&mut self, span_mode: SpanMode) { self.span_mode = span_mode; } @@ -248,8 +248,8 @@ pub struct EnvSnapshot { vars: HashMap, } -impl EnvSnapshot { - pub fn new() -> EnvSnapshot { +impl Default for EnvSnapshot { + fn default() -> EnvSnapshot { EnvSnapshot { vars: env::vars_os().collect() } } } @@ -305,7 +305,7 @@ impl Drop for EnvChange<'_> { } if let Some(dir) = &self.prev_working_dir { - if let Err(err) = std::env::set_current_dir(&dir) { + if let Err(err) = std::env::set_current_dir(dir) { eprintln!( "Failed to set the current working dir to {}. Error: {:?}", dir.display(), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs index d48c5b30dee..097b39a3f91 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/proc_macros.rs @@ -13,7 +13,7 @@ pub(crate) struct ProcMacros { impl From for crate::PanicMessage { fn from(p: bridge::PanicMessage) -> Self { - Self { message: p.as_str().map(|s| s.to_string()) } + Self { message: p.as_str().map(|s| s.to_owned()) } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index d508c19dd71..1b535d2a1cc 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -498,7 +498,7 @@ mod tests { })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym: Symbol::intern("T"), - span: span, + span, is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Subtree(tt::Subtree { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs index dbcb5a3143a..5649e60e0bb 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs @@ -99,7 +99,7 @@ pub(super) struct TokenStreamBuilder { } /// pub(super)lic implementation details for the `TokenStream` type, such as iterators. -pub(super) mod token_stream { +pub(super) mod token_stream_impls { use core::fmt; @@ -137,6 +137,7 @@ pub(super) mod token_stream { } } + #[allow(clippy::to_string_trait_impl)] impl ToString for TokenStream { fn to_string(&self) -> String { ::tt::pretty(&self.token_trees) @@ -150,7 +151,7 @@ impl TokenStreamBuilder { } pub(super) fn push(&mut self, stream: TokenStream) { - self.acc.extend(stream.into_iter()) + self.acc.extend(stream) } pub(super) fn build(self) -> TokenStream { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 4f1a18c03fc..cc5d4a89131 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -97,7 +97,7 @@ fn assert_expand_impl( pub(crate) fn list() -> Vec { let dylib_path = proc_macro_test_dylib_path(); - let env = EnvSnapshot::new(); + let env = EnvSnapshot::default(); let mut srv = ProcMacroSrv::new(&env); let res = srv.list_macros(&dylib_path).unwrap(); res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect() -- cgit 1.4.1-3-g733a5 From 1ae8416798b27be7289f12532a90397f49404dd3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 14:48:11 +0100 Subject: internal: Drop proc-macro server support for ~1.66.0 and older toolchains --- .../crates/proc-macro-api/src/msg/flat.rs | 49 ++++------------------ .../crates/proc-macro-api/src/process.rs | 29 ++++++++++--- 2 files changed, 30 insertions(+), 48 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs index 5443a9bd67b..af3412e90e4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs @@ -42,7 +42,7 @@ use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange}; -use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; +use crate::msg::EXTENDED_LEAF_DATA; pub type SpanDataIndexMap = indexmap::IndexSet>; @@ -145,11 +145,7 @@ impl FlatTree { w.write(subtree); FlatTree { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - write_vec(w.subtree, SubtreeRepr::write_with_close_span) - } else { - write_vec(w.subtree, SubtreeRepr::write) - }, + subtree: write_vec(w.subtree, SubtreeRepr::write), literal: if version >= EXTENDED_LEAF_DATA { write_vec(w.literal, LiteralRepr::write_with_kind) } else { @@ -183,11 +179,7 @@ impl FlatTree { w.write(subtree); FlatTree { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - write_vec(w.subtree, SubtreeRepr::write_with_close_span) - } else { - write_vec(w.subtree, SubtreeRepr::write) - }, + subtree: write_vec(w.subtree, SubtreeRepr::write), literal: if version >= EXTENDED_LEAF_DATA { write_vec(w.literal, LiteralRepr::write_with_kind) } else { @@ -210,11 +202,7 @@ impl FlatTree { span_data_table: &SpanDataIndexMap, ) -> tt::Subtree { Reader { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - read_vec(self.subtree, SubtreeRepr::read_with_close_span) - } else { - read_vec(self.subtree, SubtreeRepr::read) - }, + subtree: read_vec(self.subtree, SubtreeRepr::read), literal: if version >= EXTENDED_LEAF_DATA { read_vec(self.literal, LiteralRepr::read_with_kind) } else { @@ -236,11 +224,7 @@ impl FlatTree { pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree { Reader { - subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { - read_vec(self.subtree, SubtreeRepr::read_with_close_span) - } else { - read_vec(self.subtree, SubtreeRepr::read) - }, + subtree: read_vec(self.subtree, SubtreeRepr::read), literal: if version >= EXTENDED_LEAF_DATA { read_vec(self.literal, LiteralRepr::read_with_kind) } else { @@ -273,26 +257,7 @@ fn write_vec [u32; N], const N: usize>(xs: Vec, f: F) -> Vec [u32; 4] { - let kind = match self.kind { - tt::DelimiterKind::Invisible => 0, - tt::DelimiterKind::Parenthesis => 1, - tt::DelimiterKind::Brace => 2, - tt::DelimiterKind::Bracket => 3, - }; - [self.open.0, kind, self.tt[0], self.tt[1]] - } - fn read([open, kind, lo, len]: [u32; 4]) -> SubtreeRepr { - let kind = match kind { - 0 => tt::DelimiterKind::Invisible, - 1 => tt::DelimiterKind::Parenthesis, - 2 => tt::DelimiterKind::Brace, - 3 => tt::DelimiterKind::Bracket, - other => panic!("bad kind {other}"), - }; - SubtreeRepr { open: TokenId(open), close: TokenId(!0), kind, tt: [lo, len] } - } - fn write_with_close_span(self) -> [u32; 5] { + fn write(self) -> [u32; 5] { let kind = match self.kind { tt::DelimiterKind::Invisible => 0, tt::DelimiterKind::Parenthesis => 1, @@ -301,7 +266,7 @@ impl SubtreeRepr { }; [self.open.0, self.close.0, kind, self.tt[0], self.tt[1]] } - fn read_with_close_span([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { + fn read([open, close, kind, lo, len]: [u32; 5]) -> SubtreeRepr { let kind = match kind { 0 => tt::DelimiterKind::Invisible, 1 => tt::DelimiterKind::Parenthesis, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 4045e25fdf1..b1e35b7a08b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -56,8 +56,25 @@ impl ProcMacroProcessSrv { match srv.version_check() { Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new( io::ErrorKind::Other, - format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). - This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain." + format!( + "The version of the proc-macro server ({v}) in your Rust toolchain \ + is newer than the version supported by your rust-analyzer ({CURRENT_API_VERSION}). +\ + This will prevent proc-macro expansion from working. \ + Please consider updating your rust-analyzer to ensure compatibility with your \ + current toolchain." + ), + )), + Ok(v) if v < RUST_ANALYZER_SPAN_SUPPORT => Err(io::Error::new( + io::ErrorKind::Other, + format!( + "The version of the proc-macro server ({v}) in your Rust toolchain \ + is too old and no longer supported by your rust-analyzer which requires\ + version {RUST_ANALYZER_SPAN_SUPPORT} or higher. +\ + This will prevent proc-macro expansion from working. \ + Please consider updating your toolchain or downgrading your rust-analyzer \ + to ensure compatibility with your current toolchain." ), )), Ok(v) => { @@ -72,10 +89,10 @@ impl ProcMacroProcessSrv { tracing::info!("Proc-macro server span mode: {:?}", srv.mode); Ok(srv) } - Err(e) => { - tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0"); - create_srv(false) - } + Err(e) => Err(io::Error::new( + io::ErrorKind::Other, + format!("Failed to fetch proc-macro server version: {e}"), + )), } } -- cgit 1.4.1-3-g733a5 From ec6e0983b8db5c96169a4aee4a06a87f5074de84 Mon Sep 17 00:00:00 2001 From: Philipp Hofer Date: Thu, 12 Dec 2024 15:42:21 +0100 Subject: Fix typo in error message for invalid casting Corrected the spelling of "defererence" to "dereference" in the error message that informs users about invalid casting requirements. --- .../rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index 4bd29b8c79b..c7cdcf49820 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -59,7 +59,7 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) - DiagnosticCode::RustcHardError("E0606"), format_ty!( ctx, - "casting `{}` as `{}` is invalid: needs defererence or removal of unneeded borrow", + "casting `{}` as `{}` is invalid: needs dereference or removal of unneeded borrow", d.expr_ty, d.cast_ty ), -- cgit 1.4.1-3-g733a5 From 8f004a2047e5ec8fa3aef22d92671b2425aeeced Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 13 Dec 2024 01:04:13 +0900 Subject: fix: Panic when displaying generic params with defaults, again --- .../rust-analyzer/crates/hir-ty/src/display.rs | 17 +++++++++-- .../rust-analyzer/crates/ide/src/hover/tests.rs | 35 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 3dfa0e97cec..de8ce56df64 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1053,8 +1053,21 @@ impl HirDisplay for Ty { generic_args_sans_defaults(f, Some(generic_def_id), parameters); assert!(params_len >= parameters.len()); let defaults = params_len - parameters.len(); - let without_impl = - self_param as usize + type_ + const_ + lifetime - defaults; + + // Normally, functions cannot have default parameters, but they can, + // for function-like things such as struct names or enum variants. + // The former cannot have defaults but parents, and the later cannot have + // parents but defaults. + // So, if `parent_len` > 0, it have a parent and thus it doesn't have any + // default. Therefore, we shouldn't subtract defaults because those defaults + // are from their parents. + // And if `parent_len` == 0, either parents don't exists or they don't have + // any defaults. Thus, we can - and should - subtract defaults. + let without_impl = if parent_len > 0 { + params_len - parent_len - impl_ + } else { + params_len - parent_len - impl_ - defaults + }; // parent's params (those from enclosing impl or trait, if any). let (fn_params, parent_params) = parameters.split_at(without_impl + impl_); diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index ea18b89c5c9..3786a3427fd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -9465,4 +9465,39 @@ fn main() { size = 0, align = 1 "#]], ); + + check( + r#" +//- minicore: eq +pub struct RandomState; +pub struct HashMap(K, V, S); + +impl HashMap { + pub fn new() -> HashMap { + loop {} + } +} + +impl PartialEq for HashMap { + fn eq(&self, other: &HashMap) -> bool { + false + } +} + +fn main() { + let s$0 = HashMap::<_, u64>::ne; +} +"#, + expect![[r#" + *s* + + ```rust + let s: fn ne>(&HashMap<{unknown}, u64>, &HashMap<{unknown}, u64>) -> bool + ``` + + --- + + size = 0, align = 1 + "#]], + ); } -- cgit 1.4.1-3-g733a5 From 88457c06843e57bc1bb73594ed9ca5fbf8c4747d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 17:40:51 +0100 Subject: internal: Implement `naked_asm!` builtin --- src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs | 3 ++- src/tools/rust-analyzer/crates/hir/src/semantics.rs | 1 + src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 4894c7a9311..b76db2e0052 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -74,7 +74,7 @@ impl BuiltinFnLikeExpander { } pub fn is_asm(&self) -> bool { - matches!(self, Self::Asm | Self::GlobalAsm) + matches!(self, Self::Asm | Self::GlobalAsm | Self::NakedAsm) } } @@ -122,6 +122,7 @@ register_builtin! { (stringify, Stringify) => stringify_expand, (asm, Asm) => asm_expand, (global_asm, GlobalAsm) => asm_expand, + (naked_asm, NakedAsm) => asm_expand, (cfg, Cfg) => cfg_expand, (core_panic, CorePanic) => panic_expand, (std_panic, StdPanic) => panic_expand, diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f9d3f9d07e6..602b085f00c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -434,6 +434,7 @@ impl<'db> SemanticsImpl<'db> { | BuiltinFnLikeExpander::ModulePath | BuiltinFnLikeExpander::Asm | BuiltinFnLikeExpander::GlobalAsm + | BuiltinFnLikeExpander::NakedAsm | BuiltinFnLikeExpander::LogSyntax | BuiltinFnLikeExpander::TraceMacros | BuiltinFnLikeExpander::FormatArgs diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 1120d3c7d60..c15751e7c68 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -307,6 +307,7 @@ define_symbols! { module_path, mul_assign, mul, + naked_asm, ne, neg, Neg, -- cgit 1.4.1-3-g733a5 From 54f467b68d95af1d501a068105ee3c552440c2a6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 15:09:18 +0100 Subject: Do not require a special env var to be set for the proc-macro-srv --- .../crates/proc-macro-srv-cli/src/main.rs | 56 ++++++---------------- 1 file changed, 15 insertions(+), 41 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 7095dac348d..137efd5e7a0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -6,21 +6,16 @@ #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; -use proc_macro_api::json::{read_json, write_json}; - use std::io; fn main() -> std::io::Result<()> { let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE"); - match v.as_deref() { - Ok("this is unstable") => { - // very well, if you must - } - _ => { - eprintln!("If you're rust-analyzer, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE='this is unstable'."); - eprintln!("If not, you probably shouldn't use this tool. But do what you want: I'm an error message, not a cop."); - std::process::exit(122); - } + if v.is_err() { + eprintln!("This is an IDE implementation detail, you can use this tool by exporting RUST_ANALYZER_INTERNALS_DO_NOT_USE."); + eprintln!( + "Note that this tool's API is highly unstable and may break without prior notice" + ); + std::process::exit(122); } run() @@ -28,40 +23,19 @@ fn main() -> std::io::Result<()> { #[cfg(not(any(feature = "sysroot-abi", rust_analyzer)))] fn run() -> io::Result<()> { - let err = "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function"; - eprintln!("{err}"); - use proc_macro_api::msg::{self, Message}; - - let read_request = - |buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf); - - let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock()); - - let mut buf = String::new(); - - while let Some(req) = read_request(&mut buf)? { - let res = match req { - msg::Request::ListMacros { .. } => msg::Response::ListMacros(Err(err.to_owned())), - msg::Request::ExpandMacro(_) => { - msg::Response::ExpandMacro(Err(msg::PanicMessage(err.to_owned()))) - } - msg::Request::ApiVersionCheck {} => { - msg::Response::ApiVersionCheck(proc_macro_api::msg::CURRENT_API_VERSION) - } - msg::Request::SetConfig(_) => { - msg::Response::SetConfig(proc_macro_api::msg::ServerConfig { - span_mode: msg::SpanMode::Id, - }) - } - }; - write_response(res)? - } - Ok(()) + Err(io::Error::new( + io::ErrorKind::Unsupported, + "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function" + .to_owned(), + )) } #[cfg(any(feature = "sysroot-abi", rust_analyzer))] fn run() -> io::Result<()> { - use proc_macro_api::msg::{self, Message}; + use proc_macro_api::{ + json::{read_json, write_json}, + msg::{self, Message}, + }; use proc_macro_srv::EnvSnapshot; let read_request = -- cgit 1.4.1-3-g733a5 From 3a8393895608158495dcbad14629936095c29ed3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 12 Dec 2024 17:08:17 +0100 Subject: Show expansion errors in expand_macro feature --- .../rust-analyzer/crates/hir-expand/src/lib.rs | 17 +++++--- .../rust-analyzer/crates/hir/src/semantics.rs | 34 ++++++++++------ .../crates/ide-completion/src/context/analysis.rs | 11 ++++-- src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs | 2 +- .../rust-analyzer/crates/ide-ssr/src/search.rs | 2 +- .../rust-analyzer/crates/ide/src/expand_macro.rs | 45 ++++++++++++++++------ .../crates/ide/src/highlight_related.rs | 2 +- 7 files changed, 76 insertions(+), 37 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 2ee598dfbfd..5aafe6db527 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -28,6 +28,7 @@ use rustc_hash::FxHashMap; use stdx::TupleExt; use triomphe::Arc; +use core::fmt; use std::hash::Hash; use base_db::{ra_salsa::InternValueTrivial, CrateId}; @@ -147,6 +148,10 @@ impl ExpandError { pub fn span(&self) -> Span { self.inner.1 } + + pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError { + self.inner.0.render_to_string(db) + } } #[derive(Debug, PartialEq, Eq, Clone, Hash)] @@ -164,18 +169,18 @@ pub enum ExpandErrorKind { ProcMacroPanic(Box), } -impl ExpandError { - pub fn render_to_string(&self, db: &dyn ExpandDatabase) -> RenderedExpandError { - self.inner.0.render_to_string(db) - } -} - pub struct RenderedExpandError { pub message: String, pub error: bool, pub kind: &'static str, } +impl fmt::Display for RenderedExpandError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} + impl RenderedExpandError { const GENERAL_KIND: &str = "macro-error"; } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f9d3f9d07e6..8d3f24dd117 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -28,7 +28,7 @@ use hir_expand::{ hygiene::SyntaxContextExt as _, inert_attr_macro::find_builtin_attr_idx, name::AsName, - FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, + ExpandResult, FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, }; use intern::Symbol; use itertools::Itertools; @@ -381,7 +381,13 @@ impl<'db> SemanticsImpl<'db> { node } - pub fn expand(&self, macro_call: &ast::MacroCall) -> Option { + pub fn expand(&self, file_id: MacroFileId) -> ExpandResult { + let res = self.db.parse_macro_expansion(file_id).map(|it| it.0.syntax_node()); + self.cache(res.value.clone(), file_id.into()); + res + } + + pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option { let sa = self.analyze_no_infer(macro_call.syntax())?; let macro_call = InFile::new(sa.file_id, macro_call); @@ -412,7 +418,10 @@ impl<'db> SemanticsImpl<'db> { /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy /// expansions. - pub fn expand_allowed_builtins(&self, macro_call: &ast::MacroCall) -> Option { + pub fn expand_allowed_builtins( + &self, + macro_call: &ast::MacroCall, + ) -> Option> { let sa = self.analyze_no_infer(macro_call.syntax())?; let macro_call = InFile::new(sa.file_id, macro_call); @@ -447,15 +456,15 @@ impl<'db> SemanticsImpl<'db> { return None; } - let node = self.parse_or_expand(file_id.into()); + let node = self.expand(file_id); Some(node) } /// If `item` has an attribute macro attached to it, expands it. - pub fn expand_attr_macro(&self, item: &ast::Item) -> Option { + pub fn expand_attr_macro(&self, item: &ast::Item) -> Option> { let src = self.wrap_node_infile(item.clone()); let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src.as_ref()))?; - Some(self.parse_or_expand(macro_call_id.as_file())) + Some(self.expand(macro_call_id.as_macro_file())) } pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option { @@ -479,15 +488,16 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option> { + pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option>> { let res: Vec<_> = self .derive_macro_calls(attr)? .into_iter() .flat_map(|call| { - let file_id = call?.as_file(); - let node = self.db.parse_or_expand(file_id); - self.cache(node.clone(), file_id); - Some(node) + let file_id = call?.as_macro_file(); + let ExpandResult { value, err } = self.db.parse_macro_expansion(file_id); + let root_node = value.0.syntax_node(); + self.cache(root_node.clone(), file_id.into()); + Some(ExpandResult { value: root_node, err }) }) .collect(); Some(res) @@ -555,7 +565,7 @@ impl<'db> SemanticsImpl<'db> { /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the /// expansion. `token_to_map` should be a token from the `speculative args` node. - pub fn speculative_expand( + pub fn speculative_expand_macro_call( &self, actual_macro_call: &ast::MacroCall, speculative_args: &ast::TokenTree, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index 4a678963b93..3b7898b9e86 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{Semantics, Type, TypeInfo, Variant}; +use hir::{ExpandResult, Semantics, Type, TypeInfo, Variant}; use ide_db::{active_parameter::ActiveParameter, RootDatabase}; use itertools::Either; use syntax::{ @@ -104,7 +104,10 @@ fn expand( // maybe parent items have attributes, so continue walking the ancestors (None, None) => continue 'ancestors, // successful expansions - (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => { + ( + Some(ExpandResult { value: actual_expansion, err: _ }), + Some((fake_expansion, fake_mapped_token)), + ) => { let new_offset = fake_mapped_token.text_range().start(); if new_offset + relative_offset > actual_expansion.text_range().end() { // offset outside of bounds from the original expansion, @@ -239,8 +242,8 @@ fn expand( }; match ( - sema.expand(&actual_macro_call), - sema.speculative_expand( + sema.expand_macro_call(&actual_macro_call), + sema.speculative_expand_macro_call( &actual_macro_call, &speculative_args, fake_ident_token.clone(), diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index eaca95d98c2..6b654f89345 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -286,7 +286,7 @@ impl<'db> MatchFinder<'db> { }); } } else if let Some(macro_call) = ast::MacroCall::cast(node.clone()) { - if let Some(expanded) = self.sema.expand(¯o_call) { + if let Some(expanded) = self.sema.expand_macro_call(¯o_call) { if let Some(tt) = macro_call.token_tree() { self.output_debug_for_nodes_at_range( &expanded, diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs index 241de10b44d..b1cade39266 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs @@ -189,7 +189,7 @@ impl MatchFinder<'_> { // If we've got a macro call, we already tried matching it pre-expansion, which is the only // way to match the whole macro, now try expanding it and matching the expansion. if let Some(macro_call) = ast::MacroCall::cast(code.clone()) { - if let Some(expanded) = self.sema.expand(¯o_call) { + if let Some(expanded) = self.sema.expand_macro_call(¯o_call) { if let Some(tt) = macro_call.token_tree() { // When matching within a macro expansion, we only want to allow matches of // nodes that originated entirely from within the token tree of the macro call. diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 79fdf75b7f7..10a73edd51c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -1,10 +1,11 @@ use hir::db::ExpandDatabase; -use hir::{InFile, MacroFileIdExt, Semantics}; +use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics}; use ide_db::base_db::CrateId; use ide_db::{ helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase, }; use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize}; +use stdx::format_to; use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; use crate::FilePosition; @@ -63,10 +64,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .take_while(|it| it != &token) .filter(|it| it.kind() == T![,]) .count(); - let expansion = expansions.get(idx)?.clone(); + let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone(); let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?; let expansion_span_map = db.expansion_span_map(expansion_file_id); - let expansion = format( + let mut expansion = format( db, SyntaxKind::MACRO_ITEMS, position.file_id, @@ -74,6 +75,12 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< &expansion_span_map, krate, ); + if let Some(err) = err { + expansion.insert_str( + 0, + &format!("Expansion had errors: {}\n\n", err.render_to_string(sema.db)), + ); + } Some(ExpandedMacro { name, expansion }) }); @@ -83,6 +90,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let mut anc = tok.parent_ancestors(); let mut span_map = SpanMap::empty(); + let mut error = String::new(); let (name, expanded, kind) = loop { let node = anc.next()?; @@ -97,7 +105,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .unwrap_or(Edition::CURRENT), ) .to_string(), - expand_macro_recur(&sema, &item, &mut span_map, TextSize::new(0))?, + expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?, SyntaxKind::MACRO_ITEMS, ); } @@ -112,6 +120,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< expand_macro_recur( &sema, &ast::Item::MacroCall(mac), + &mut error, &mut span_map, TextSize::new(0), )?, @@ -123,24 +132,31 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< // FIXME: // macro expansion may lose all white space information // But we hope someday we can use ra_fmt for that - let expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + if !error.is_empty() { + expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n")); + } Some(ExpandedMacro { name, expansion }) } fn expand_macro_recur( sema: &Semantics<'_, RootDatabase>, macro_call: &ast::Item, + error: &mut String, result_span_map: &mut SpanMap, offset_in_original_node: TextSize, ) -> Option { - let expanded = match macro_call { - item @ ast::Item::MacroCall(macro_call) => sema - .expand_attr_macro(item) - .or_else(|| sema.expand_allowed_builtins(macro_call))? - .clone_for_update(), - item => sema.expand_attr_macro(item)?.clone_for_update(), + let ExpandResult { value: expanded, err } = match macro_call { + item @ ast::Item::MacroCall(macro_call) => { + sema.expand_attr_macro(item).or_else(|| sema.expand_allowed_builtins(macro_call))? + } + item => sema.expand_attr_macro(item)?, }; + let expanded = expanded.clone_for_update(); + if let Some(err) = err { + format_to!(error, "\n{}", err.render_to_string(sema.db)); + } let file_id = sema.hir_file_for(&expanded).macro_file().expect("expansion must produce a macro file"); let expansion_span_map = sema.db.expansion_span_map(file_id); @@ -149,12 +165,13 @@ fn expand_macro_recur( expanded.text_range().len(), &expansion_span_map, ); - Some(expand(sema, expanded, result_span_map, u32::from(offset_in_original_node) as i32)) + Some(expand(sema, expanded, error, result_span_map, u32::from(offset_in_original_node) as i32)) } fn expand( sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode, + error: &mut String, result_span_map: &mut SpanMap, mut offset_in_original_node: i32, ) -> SyntaxNode { @@ -165,6 +182,7 @@ fn expand( if let Some(new_node) = expand_macro_recur( sema, &child, + error, result_span_map, TextSize::new( (offset_in_original_node + (u32::from(child.syntax().text_range().start()) as i32)) @@ -495,6 +513,9 @@ fn main() { "#, expect![[r#" foo! + Expansion had errors: + expected ident: `BAD` + "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index fc29ba06dad..4690416e059 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -608,7 +608,7 @@ impl<'a> WalkExpandedExprCtx<'a> { if let ast::Expr::MacroExpr(expr) = expr { if let Some(expanded) = - expr.macro_call().and_then(|call| self.sema.expand(&call)) + expr.macro_call().and_then(|call| self.sema.expand_macro_call(&call)) { match_ast! { match expanded { -- cgit 1.4.1-3-g733a5 From c8abe14dd74a3d5a3f68477bdc5babff4159fe1d Mon Sep 17 00:00:00 2001 From: Vincent Esche Date: Fri, 13 Dec 2024 09:53:10 +0100 Subject: Fix a few typos --- src/tools/rust-analyzer/crates/hir-ty/src/interner.rs | 2 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 4 ++-- src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs | 2 +- src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs | 2 +- src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs index 3dbefc5cec8..804c3aea3a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs @@ -55,7 +55,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedConst = Interned>; type InternedConcreteConst = ConstScalar; type InternedGenericArg = GenericArgData; - // We could do the following, but that saves "only" 20mb on self while increasing inferecene + // We could do the following, but that saves "only" 20mb on self while increasing inference // time by ~2.5% // type InternedGoal = Interned>; type InternedGoal = Arc; diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index d8dc9ca32a9..c13fc843568 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -299,7 +299,7 @@ impl Analysis { /// Gets the syntax tree of the file. pub fn parse(&self, file_id: FileId) -> Cancellable { - // FIXME editiojn + // FIXME edition self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree()) } @@ -540,7 +540,7 @@ impl Analysis { /// Returns URL(s) for the documentation of the symbol under the cursor. /// # Arguments /// * `position` - Position in the file. - /// * `target_dir` - Directory where the build output is storeda. + /// * `target_dir` - Directory where the build output is stored. pub fn external_docs( &self, position: FilePosition, diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs index 7b8e6840fc9..9116f1606fa 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs @@ -11,7 +11,7 @@ /// case), and we know that the query only used inputs of medium /// durability or higher, then we can skip that enumeration. /// -/// Typically, one assigns low durabilites to inputs that the user is +/// Typically, one assigns low durabilities to inputs that the user is /// frequently editing. Medium or high durabilities are used for /// configuration, the source from library crates, or other things /// that are unlikely to be edited. diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs index bd1ab6971cb..8530521d915 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs @@ -291,7 +291,7 @@ pub trait ParallelDatabase: Database + Send { /// # Panics /// /// It is not permitted to create a snapshot from inside of a - /// query. Attepting to do so will panic. + /// query. Attempting to do so will panic. /// /// # Deadlock warning /// diff --git a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs index 81136626551..3c3931e6585 100644 --- a/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs @@ -255,7 +255,7 @@ fn cycle_revalidate_unchanged_twice() { db.set_b_invokes(CycleQuery::A); assert!(db.cycle_a().is_err()); - db.set_c_invokes(CycleQuery::A); // force new revisi5on + db.set_c_invokes(CycleQuery::A); // force new revision // on this run expect![[r#" -- cgit 1.4.1-3-g733a5 From 9847e01377316ef702b425a771230c97f7bcfd9d Mon Sep 17 00:00:00 2001 From: LaurenÈ›iu Nicola Date: Fri, 13 Dec 2024 11:45:44 +0200 Subject: Bump typos --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 2 +- src/tools/rust-analyzer/.typos.toml | 7 ++++++- src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs | 4 ++-- .../crates/ide-assists/src/handlers/extract_function.rs | 2 +- .../crates/ide-assists/src/handlers/generate_function.rs | 2 +- .../rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs | 4 ++-- .../crates/ide-assists/src/handlers/replace_if_let_with_match.rs | 2 +- .../crates/ide-assists/src/handlers/toggle_async_sugar.rs | 2 +- src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs | 2 +- 9 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index d82e46016dc..46bae20054c 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -220,7 +220,7 @@ jobs: timeout-minutes: 10 env: FORCE_COLOR: 1 - TYPOS_VERSION: v1.18.0 + TYPOS_VERSION: v1.28.3 steps: - name: download typos run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml index febfb233bd9..0f2f9b1b275 100644 --- a/src/tools/rust-analyzer/.typos.toml +++ b/src/tools/rust-analyzer/.typos.toml @@ -16,7 +16,8 @@ extend-ignore-re = [ "raison d'être", "inout", "INOUT", - "optin" + "optin", + "=Pn", ] [default.extend-words] @@ -26,8 +27,12 @@ fo = "fo" ket = "ket" makro = "makro" trivias = "trivias" +thir = "thir" +jod = "jod" [default.extend-identifiers] +anc = "anc" datas = "datas" impl_froms = "impl_froms" selfs = "selfs" +taits = "taits" diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index e15d44bd6de..dda7bfb2baf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4380,7 +4380,7 @@ fn test() { fn associated_type_in_struct_expr_path() { // FIXME: All annotation should be resolvable. // For lines marked as unstable, see rust-lang/rust#86935. - // FIXME: Remove the comments once stablized. + // FIXME: Remove the comments once stabilized. check_types( r#" trait Trait { @@ -4416,7 +4416,7 @@ impl Trait for () { fn associated_type_in_struct_expr_path_enum() { // FIXME: All annotation should be resolvable. // For lines marked as unstable, see rust-lang/rust#86935. - // FIXME: Remove the comments once stablized. + // FIXME: Remove the comments once stabilized. check_types( r#" trait Trait { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 2e363b0b62c..438769a0a87 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -5011,7 +5011,7 @@ fn $0fun_name(bar: &str) { } #[test] - fn unresolveable_types_default_to_placeholder() { + fn unresolvable_types_default_to_placeholder() { check_assist( extract_function, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 76a647807cb..7b95c124e62 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -2055,7 +2055,7 @@ fn bar(closure: impl Fn(i64) -> i64) { } #[test] - fn unresolveable_types_default_to_placeholder() { + fn unresolvable_types_default_to_placeholder() { check_assist( generate_function, r" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index ec3281619cc..f0c96fe3cb8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -36,7 +36,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) let match_arm = ctx.find_node_at_offset::()?; let guard = match_arm.guard()?; if ctx.offset() > guard.syntax().text_range().end() { - cov_mark::hit!(move_guard_unapplicable_in_arm_body); + cov_mark::hit!(move_guard_inapplicable_in_arm_body); return None; } let space_before_guard = guard.syntax().prev_sibling_or_token(); @@ -219,7 +219,7 @@ mod tests { #[test] fn move_guard_to_arm_body_range() { - cov_mark::check!(move_guard_unapplicable_in_arm_body); + cov_mark::check!(move_guard_inapplicable_in_arm_body); check_assist_not_applicable( move_guard_to_arm_body, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index f13b0b0713d..56dd6cf29ae 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -360,7 +360,7 @@ mod tests { use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; #[test] - fn test_if_let_with_match_unapplicable_for_simple_ifs() { + fn test_if_let_with_match_inapplicable_for_simple_ifs() { check_assist_not_applicable( replace_if_let_with_match, r#" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs index 9ab36bf7757..8f937a04122 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs @@ -127,7 +127,7 @@ pub(crate) fn desugar_async_into_impl_future( let rparen = function.param_list()?.r_paren_token()?; let return_type = match function.ret_type() { - // unable to get a `ty` makes the action unapplicable + // unable to get a `ty` makes the action inapplicable Some(ret_type) => Some(ret_type.ty()?), // No type means `-> ()` None => None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index a508f2fedd6..156f21b784e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -184,7 +184,7 @@ impl<'a> PathTransform<'a> { if let Some(expr) = v.expr() { // FIXME: expressions in curly brackets can cause ambiguity after insertion // (e.g. `N * 2` -> `{1 + 1} * 2`; it's unclear whether `{1 + 1}` - // is a standalone statement or a part of another expresson) + // is a standalone statement or a part of another expression) // and sometimes require slight modifications; see // https://doc.rust-lang.org/reference/statements.html#expression-statements // (default values in curly brackets can cause the same problem) -- cgit 1.4.1-3-g733a5 From f69b6fc50654749b313509df268dfd58506d5cac Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:59:50 -0500 Subject: fix: Revert changes to client capabilities in `bac0ed5` --- src/tools/rust-analyzer/editors/code/src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts index 4ce19f5c665..eac7b849fdb 100644 --- a/src/tools/rust-analyzer/editors/code/src/client.ts +++ b/src/tools/rust-analyzer/editors/code/src/client.ts @@ -324,7 +324,7 @@ class ExperimentalFeatures implements lc.StaticFeature { } fillClientCapabilities(capabilities: lc.ClientCapabilities): void { capabilities.experimental = { - snippetTextEdit: false, + snippetTextEdit: true, codeActionGroup: true, hoverActions: true, serverStatusNotification: true, -- cgit 1.4.1-3-g733a5 From 3f3f27bb84b46be8294e27c6a2d64f0c918f3679 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 14 Dec 2024 14:53:11 +0000 Subject: Stop handling specialization in clippy's to_string_trait_impl lint ToString can no longer be specialized, so no need to account for it in to_string_trait_impl either. --- .../clippy_lints/src/to_string_trait_impl.rs | 3 -- src/tools/clippy/tests/ui/to_string_trait_impl.rs | 43 ---------------------- .../clippy/tests/ui/to_string_trait_impl.stderr | 14 +------ 3 files changed, 1 insertion(+), 59 deletions(-) (limited to 'src/tools') diff --git a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs index 0361836cdec..9596b85664b 100644 --- a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs @@ -1,5 +1,4 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::ty::implements_trait; use rustc_hir::{Impl, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -54,8 +53,6 @@ impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl { }) = it.kind && let Some(trait_did) = trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::ToString, trait_did) - && let Some(display_did) = cx.tcx.get_diagnostic_item(sym::Display) - && !implements_trait(cx, cx.tcx.type_of(it.owner_id).instantiate_identity(), display_did, &[]) { span_lint_and_help( cx, diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.rs b/src/tools/clippy/tests/ui/to_string_trait_impl.rs index 4c1202d4203..7be9f7994f0 100644 --- a/src/tools/clippy/tests/ui/to_string_trait_impl.rs +++ b/src/tools/clippy/tests/ui/to_string_trait_impl.rs @@ -30,46 +30,3 @@ impl Bar { String::from("Bar") } } - -mod issue12263 { - pub struct MyStringWrapper<'a>(&'a str); - - impl std::fmt::Display for MyStringWrapper<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } - } - - impl ToString for MyStringWrapper<'_> { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - pub struct S(T); - impl std::fmt::Display for S { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!() - } - } - // no specialization if the generics differ, so lint - impl ToString for S { - fn to_string(&self) -> String { - todo!() - } - } - - pub struct S2(T); - impl std::fmt::Display for S2 { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!() - } - } - - // also specialization if the generics don't differ - impl ToString for S2 { - fn to_string(&self) -> String { - todo!() - } - } -} diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr index 304c9a5e1fb..fe8afc215f0 100644 --- a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr +++ b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr @@ -12,17 +12,5 @@ LL | | } = note: `-D clippy::to-string-trait-impl` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]` -error: direct implementation of `ToString` - --> tests/ui/to_string_trait_impl.rs:56:5 - | -LL | / impl ToString for S { -LL | | fn to_string(&self) -> String { -LL | | todo!() -LL | | } -LL | | } - | |_____^ - | - = help: prefer implementing `Display` instead - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -- cgit 1.4.1-3-g733a5 From 8a4e5d7444c4d43097c2ca0d1b8e64be9dbeddfa Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 13 Dec 2024 12:19:46 +0000 Subject: Add some convenience helper methods on `hir::Safety` --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 ++-- compiler/rustc_const_eval/src/const_eval/fn_queries.rs | 5 ++--- compiler/rustc_hir/src/hir.rs | 15 ++++++++++++++- compiler/rustc_hir_analysis/src/check/check.rs | 4 ++-- compiler/rustc_hir_typeck/src/coercion.rs | 5 +++-- compiler/rustc_hir_typeck/src/fallback.rs | 6 +++--- compiler/rustc_middle/src/ty/context.rs | 6 +++--- compiler/rustc_middle/src/ty/mod.rs | 4 ++-- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_mir_build/src/check_unsafety.rs | 16 ++++++---------- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- compiler/rustc_trait_selection/src/traits/misc.rs | 2 +- src/librustdoc/html/format.rs | 5 +---- src/librustdoc/html/render/print_item.rs | 6 ++---- src/librustdoc/json/conversions.rs | 8 ++++---- src/tools/clippy/clippy_lints/src/derive.rs | 4 ++-- src/tools/clippy/clippy_lints/src/eta_reduction.rs | 2 +- .../clippy_lints/src/functions/misnamed_getters.rs | 4 ++-- .../src/functions/not_unsafe_ptr_arg_deref.rs | 4 ++-- src/tools/clippy/clippy_lints/src/inherent_to_string.rs | 4 ++-- .../clippy_lints/src/multiple_unsafe_ops_per_block.rs | 6 +++--- src/tools/clippy/clippy_lints/src/new_without_default.rs | 2 +- src/tools/clippy/clippy_lints/src/ptr.rs | 4 ++-- .../clippy_lints/src/undocumented_unsafe_blocks.rs | 4 ++-- src/tools/clippy/clippy_utils/src/check_proc_macro.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 4 ++-- src/tools/clippy/clippy_utils/src/visitors.rs | 10 +++++----- 27 files changed, 72 insertions(+), 68 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 11744eabab0..658a7f00b19 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -6,7 +6,7 @@ use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; -use rustc_hir::{self as hir, HirId, LangItem, lang_items}; +use rustc_hir::{HirId, LangItem, lang_items}; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, }; @@ -251,7 +251,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::target_feature => { if !tcx.is_closure_like(did.to_def_id()) && let Some(fn_sig) = fn_sig() - && fn_sig.skip_binder().safety() == hir::Safety::Safe + && fn_sig.skip_binder().safety().is_safe() { if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { // The `#[target_feature]` attribute is allowed on diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index beff0cd99fc..3de4c21c356 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -53,9 +53,8 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { Some(stab) => { if cfg!(debug_assertions) && stab.promotable { let sig = tcx.fn_sig(def_id); - assert_eq!( - sig.skip_binder().safety(), - hir::Safety::Safe, + assert!( + sig.skip_binder().safety().is_safe(), "don't mark const unsafe fns as promotable", // https://github.com/rust-lang/rust/pull/53851#issuecomment-418760682 ); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 365e4cbb556..b6cdf224fb2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3401,6 +3401,19 @@ impl Safety { Self::Safe => "", } } + + #[inline] + pub fn is_unsafe(self) -> bool { + !self.is_safe() + } + + #[inline] + pub fn is_safe(self) -> bool { + match self { + Self::Unsafe => false, + Self::Safe => true, + } + } } impl fmt::Display for Safety { @@ -3445,7 +3458,7 @@ impl FnHeader { } pub fn is_unsafe(&self) -> bool { - matches!(&self.safety, Safety::Unsafe) + self.safety.is_unsafe() } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 022a6d457ec..8ff94fa566d 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::MultiSpan; use rustc_errors::codes::*; use rustc_hir::def::{CtorKind, DefKind}; -use rustc_hir::{Node, Safety, intravisit}; +use rustc_hir::{Node, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, ObligationCauseCode}; use rustc_lint_defs::builtin::{ @@ -161,7 +161,7 @@ fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) { }; let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); for field in def.all_fields() { - if field.safety != Safety::Unsafe { + if !field.safety.is_unsafe() { continue; } let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args)) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bf41dcbe4a3..7d7c9331edf 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -863,7 +863,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let outer_universe = self.infcx.universe(); let result = if let ty::FnPtr(_, hdr_b) = b.kind() - && let (hir::Safety::Safe, hir::Safety::Unsafe) = (fn_ty_a.safety(), hdr_b.safety) + && fn_ty_a.safety().is_safe() + && hdr_b.safety.is_unsafe() { let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); self.unify_and(unsafe_a, b, to_unsafe) @@ -925,7 +926,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396). - if b_hdr.safety == hir::Safety::Safe + if b_hdr.safety.is_safe() && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty() { return Err(TypeError::TargetFeatureCast(def_id)); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ddd146fe785..64acff8c8bf 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -765,7 +765,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() && let sig = method_ty.fn_sig(self.fcx.tcx) - && let hir::Safety::Unsafe = sig.safety() + && sig.safety().is_unsafe() { let mut collector = InferVarCollector { value: (ex.hir_id, ex.span, UnsafeUseReason::Method), @@ -785,7 +785,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( if func_ty.is_fn() && let sig = func_ty.fn_sig(self.fcx.tcx) - && let hir::Safety::Unsafe = sig.safety() + && sig.safety().is_unsafe() { let mut collector = InferVarCollector { value: (ex.hir_id, ex.span, UnsafeUseReason::Call), @@ -816,7 +816,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( // `is_fn` excludes closures, but those can't be unsafe. if ty.is_fn() && let sig = ty.fn_sig(self.fcx.tcx) - && let hir::Safety::Unsafe = sig.safety() + && sig.safety().is_unsafe() { let mut collector = InferVarCollector { value: (ex.hir_id, ex.span, UnsafeUseReason::Path), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2841470d248..e382e63e2bd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -586,7 +586,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool { - self.trait_def(trait_def_id).safety == hir::Safety::Unsafe + self.trait_def(trait_def_id).safety.is_unsafe() } fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { @@ -722,7 +722,7 @@ impl<'tcx> rustc_type_ir::inherent::Safety> for hir::Safety { } fn is_safe(self) -> bool { - matches!(self, hir::Safety::Safe) + self.is_safe() } fn prefix_str(self) -> &'static str { @@ -2521,7 +2521,7 @@ impl<'tcx> TyCtxt<'tcx> { /// that is, a `fn` type that is equivalent in every way for being /// unsafe. pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { - assert_eq!(sig.safety(), hir::Safety::Safe); + assert!(sig.safety().is_safe()); Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 70e0568b202..70d43abe8ed 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -33,9 +33,9 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; +use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; -use rustc_hir::{LangItem, Safety}; use rustc_index::IndexVec; use rustc_macros::{ Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, @@ -1279,7 +1279,7 @@ impl VariantDef { /// Returns whether this variant has unsafe fields. pub fn has_unsafe_fields(&self) -> bool { - self.fields.iter().any(|x| x.safety == Safety::Unsafe) + self.fields.iter().any(|x| x.safety.is_unsafe()) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b9a45ea3c2c..270bb560c48 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1291,7 +1291,7 @@ impl<'tcx> Ty<'tcx> { /// Checks whether this type is an ADT that has unsafe fields. pub fn has_unsafe_fields(self) -> bool { if let ty::Adt(adt_def, ..) = self.kind() { - adt_def.all_fields().any(|x| x.safety == hir::Safety::Unsafe) + adt_def.all_fields().any(|x| x.safety.is_unsafe()) } else { false } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index f37b3f977fa..90be690e034 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -4,7 +4,7 @@ use std::ops::Bound; use rustc_errors::DiagArgValue; use rustc_hir::def::DefKind; -use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Safety}; +use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability}; use rustc_middle::middle::codegen_fn_attrs::TargetFeature; use rustc_middle::mir::BorrowKind; use rustc_middle::span_bug; @@ -342,7 +342,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Leaf { subpatterns, .. } => { if let ty::Adt(adt_def, ..) = pat.ty.kind() { for pat in subpatterns { - if adt_def.non_enum_variant().fields[pat.field].safety == Safety::Unsafe { + if adt_def.non_enum_variant().fields[pat.field].safety.is_unsafe() { self.requires_unsafe(pat.pattern.span, UseOfUnsafeField); } } @@ -367,7 +367,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Variant { adt_def, args: _, variant_index, subpatterns } => { for pat in subpatterns { let field = &pat.field; - if adt_def.variant(*variant_index).fields[*field].safety == Safety::Unsafe { + if adt_def.variant(*variant_index).fields[*field].safety.is_unsafe() { self.requires_unsafe(pat.pattern.span, UseOfUnsafeField); } } @@ -479,7 +479,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { return; // don't visit the whole expression } ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => { - if self.thir[fun].ty.fn_sig(self.tcx).safety() == hir::Safety::Unsafe { + if self.thir[fun].ty.fn_sig(self.tcx).safety().is_unsafe() { let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() { Some(*func_id) } else { @@ -623,7 +623,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { ExprKind::Field { lhs, variant_index, name } => { let lhs = &self.thir[lhs]; if let ty::Adt(adt_def, _) = lhs.ty.kind() { - if adt_def.variant(variant_index).fields[name].safety == Safety::Unsafe { + if adt_def.variant(variant_index).fields[name].safety.is_unsafe() { self.requires_unsafe(expr.span, UseOfUnsafeField); } else if adt_def.is_union() { if let Some(assigned_ty) = self.assignment_info { @@ -1112,11 +1112,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { let hir_id = tcx.local_def_id_to_hir_id(def); let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { - if fn_sig.header.safety == hir::Safety::Unsafe { - SafetyContext::UnsafeFn - } else { - SafetyContext::Safe - } + if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe } }); let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features; let mut warnings = Vec::new(); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1a10ab8829c..2e1d85d15da 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -439,7 +439,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { let sig = sig_tys.with(hdr); self.push("F"); self.in_binder(&sig, |cx, sig| { - if sig.safety == hir::Safety::Unsafe { + if sig.safety.is_unsafe() { cx.push("U"); } match sig.abi { diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index d216ae72913..7a67b943e94 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -84,7 +84,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( return Err(CopyImplementationError::HasDestructor); } - if impl_safety == hir::Safety::Safe && self_type.has_unsafe_fields() { + if impl_safety.is_safe() && self_type.has_unsafe_fields() { return Err(CopyImplementationError::HasUnsafeFields); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0a563b1df26..7d40f662ed0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1626,10 +1626,7 @@ pub(crate) trait PrintWithSpace { impl PrintWithSpace for hir::Safety { fn print_with_space(&self) -> &str { - match self { - hir::Safety::Unsafe => "unsafe ", - hir::Safety::Safe => "", - } + self.prefix_str() } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4c8d704e65b..ced9ff2d685 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -469,7 +469,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let unsafety_flag = match myitem.kind { clean::FunctionItem(_) | clean::ForeignFunctionItem(..) - if myitem.fn_header(tcx).unwrap().safety == hir::Safety::Unsafe => + if myitem.fn_header(tcx).unwrap().safety.is_unsafe() => { "âš " } @@ -1926,9 +1926,7 @@ fn item_static( buffer, "{vis}{safe}static {mutability}{name}: {typ}", vis = visibility_print_with_space(it, cx), - safe = safety - .map(|safe| if safe == hir::Safety::Unsafe { "unsafe " } else { "" }) - .unwrap_or(""), + safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bb967b7f163..be39984c3da 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -639,7 +639,7 @@ impl FromClean for FunctionPointer { let clean::BareFunctionDecl { safety, generic_params, decl, abi } = bare_decl; FunctionPointer { header: FunctionHeader { - is_unsafe: matches!(safety, rustc_hir::Safety::Unsafe), + is_unsafe: safety.is_unsafe(), is_const: false, is_async: false, abi: convert_abi(abi), @@ -669,7 +669,7 @@ impl FromClean for Trait { fn from_clean(trait_: clean::Trait, renderer: &JsonRenderer<'_>) -> Self { let tcx = renderer.tcx; let is_auto = trait_.is_auto(tcx); - let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe; + let is_unsafe = trait_.safety(tcx).is_unsafe(); let is_dyn_compatible = trait_.is_dyn_compatible(tcx); let clean::Trait { items, generics, bounds, .. } = trait_; Trait { @@ -711,7 +711,7 @@ impl FromClean for Impl { ty::ImplPolarity::Negative => true, }; Impl { - is_unsafe: safety == rustc_hir::Safety::Unsafe, + is_unsafe: safety.is_unsafe(), generics: generics.into_json(renderer), provided_trait_methods: provided_trait_methods .into_iter() @@ -840,7 +840,7 @@ fn convert_static( Static { type_: (*stat.type_).into_json(renderer), is_mutable: stat.mutability == ast::Mutability::Mut, - is_unsafe: safety == rustc_hir::Safety::Unsafe, + is_unsafe: safety.is_unsafe(), expr: stat .expr .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 8125dab8adf..f65edd36253 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item}; use rustc_hir::{ - self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource, + self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; @@ -421,7 +421,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { id: LocalDefId, ) -> Self::Result { if let Some(header) = kind.header() - && header.safety == Safety::Unsafe + && header.safety.is_unsafe() { ControlFlow::Break(()) } else { diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 8c22e43349f..2cd48ef98e5 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -281,7 +281,7 @@ fn check_inputs( } fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool { - call_sig.safety == Safety::Safe && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) + call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) } /// This walks through both signatures and checks for any time a late-bound region is expected by an diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs index 2cbc4b07234..017571c38db 100644 --- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs +++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Safety}; +use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Span; @@ -34,7 +34,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: ImplicitSelfKind::None => return, }; - let name = if sig.header.safety == Safety::Unsafe { + let name = if sig.header.safety.is_unsafe() { name.strip_suffix("_unchecked").unwrap_or(name) } else { name diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 4986a311eba..3ded8dc3012 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>( body: &'tcx hir::Body<'tcx>, def_id: LocalDefId, ) { - if safety == hir::Safety::Safe && cx.effective_visibilities.is_exported(def_id) { + if safety.is_safe() && cx.effective_visibilities.is_exported(def_id) { let raw_ptrs = iter_input_pats(decl, body) .filter_map(|arg| raw_ptr_arg(cx, arg)) .collect::(); @@ -58,7 +58,7 @@ fn check_raw_ptr<'tcx>( }, hir::ExprKind::MethodCall(_, recv, args, _) => { let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap(); - if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety == hir::Safety::Unsafe { + if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() { check_arg(cx, &raw_ptrs, recv); for arg in args { check_arg(cx, &raw_ptrs, arg); diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs index ec6174bc030..e096dd25175 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::{implements_trait, is_type_lang_item}; use clippy_utils::{return_ty, trait_ref_of_method}; -use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem, Safety}; +use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString { if let ImplItemKind::Fn(ref signature, _) = impl_item.kind // #11201 && let header = signature.header - && header.safety == Safety::Safe + && header.safety.is_safe() && header.abi == Abi::Rust && impl_item.ident.name == sym::to_string && let decl = signature.decl diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 12bcc608174..79252bba74d 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::visitors::{Descend, Visitable, for_each_expr}; use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; -use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp}; +use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -133,7 +133,7 @@ fn collect_unsafe_exprs<'tcx>( ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr), _ => return Continue(Descend::Yes), }; - if sig.safety() == Safety::Unsafe { + if sig.safety().is_unsafe() { unsafe_ops.push(("unsafe function call occurs here", expr.span)); } }, @@ -144,7 +144,7 @@ fn collect_unsafe_exprs<'tcx>( .type_dependent_def_id(expr.hir_id) .map(|def_id| cx.tcx.fn_sig(def_id)) { - if sig.skip_binder().safety() == Safety::Unsafe { + if sig.skip_binder().safety().is_unsafe() { unsafe_ops.push(("unsafe method call occurs here", expr.span)); } } diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index b60fea3f03e..abdce69e764 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind { let name = impl_item.ident.name; let id = impl_item.owner_id; - if sig.header.safety == hir::Safety::Unsafe { + if sig.header.safety.is_unsafe() { // can't be implemented for unsafe new return; } diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index dec4c18a309..44a8789462b 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -8,7 +8,7 @@ use rustc_hir::hir_id::{HirId, HirIdMap}; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{ self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind, - ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, Safety, TraitFn, TraitItem, TraitItemKind, TyKind, + ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind, }; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{Obligation, ObligationCause}; @@ -541,7 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio .collect(); if let Some(args) = args && !args.is_empty() - && body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value)) + && body.is_none_or(|body| sig.header.safety.is_unsafe() || contains_unsafe_block(cx, body.value)) { span_lint_and_then( cx, diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index b79e59f857b..45d730985bb 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -203,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { let item_has_safety_comment = item_has_safety_comment(cx, item); match (&item.kind, item_has_safety_comment) { // lint unsafe impl without safety comment - (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety == hir::Safety::Unsafe => { + (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety.is_unsafe() => { if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id()) && !is_unsafe_from_proc_macro(cx, item.span) { @@ -227,7 +227,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } }, // lint safe impl with unnecessary safety comment - (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety == hir::Safety::Safe => { + (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety.is_safe() => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { let (span, help_span) = mk_spans(pos); diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 3269bf758ac..b71b53ea3bb 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -373,7 +373,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1), TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), TyKind::BareFn(bare_fn) => ( - if bare_fn.safety == Safety::Unsafe { + if bare_fn.safety.is_unsafe() { Pat::Str("unsafe") } else if bare_fn.abi != Abi::Rust { Pat::Str("extern") diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 260d1b801e3..bc3c3ca5c21 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind}; +use rustc_hir::{Expr, FnDecl, LangItem, TyKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; @@ -531,7 +531,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) { /// Returns `true` if the given type is an `unsafe` function. pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind() { - ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe, + ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 351e619d7b1..b3d998fbc52 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr}; use rustc_hir::{ AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath, - Safety, Stmt, UnOp, UnsafeSource, StructTailExpr, + Stmt, UnOp, UnsafeSource, StructTailExpr, }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; @@ -426,15 +426,15 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { .cx .typeck_results() .type_dependent_def_id(e.hir_id) - .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) => + .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) => { ControlFlow::Break(()) }, ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() { - ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => { + ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => { ControlFlow::Break(()) }, - ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()), + ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()), _ => walk_expr(self, e), }, ExprKind::Path(ref p) @@ -458,7 +458,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { } fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind - && i.safety == Safety::Unsafe + && i.safety.is_unsafe() { ControlFlow::Break(()) } else { -- cgit 1.4.1-3-g733a5 From da535b9155fdab852dfd18006a5585612e50a70c Mon Sep 17 00:00:00 2001 From: jyn Date: Tue, 10 Dec 2024 03:03:28 -0500 Subject: Fix `--nocapture` for run-make tests This was confusing because there are three layers of output hiding. 1. libtest shoves all output into a buffer and does not print it unless the test fails or `--nocapture` is passed. 2. compiletest chooses whether to print the output from any given process. 3. run-make-support chooses what output to print. This modifies 2 and 3. - compiletest: Don't require both `--verbose` and `--nocapture` to show the output of run-make tests. - compiletest: Distinguish rustc and rmake stderr by printing the command name (e.g. "--stderr--" to "--rustc stderr--"). - run-make-support: Unconditionally print the needle/haystack being searched. Previously this was only printed on failure. Before: ``` $ x t tests/run-make/linker-warning --force-rerun -- --nocapture running 1 tests . test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 377 filtered out; finished in 281.64ms $ x t tests/run-make/linker-warning --force-rerun -v -- --nocapture 2>&1 | wc -l 1004 $ x t tests/run-make/linker-warning --force-rerun -v -- --nocapture | tail -n40 running 1 tests ------stdout------------------------------ ------stderr------------------------------ warning: unused import: `std::path::Path` --> /home/jyn/src/rust2/tests/run-make/linker-warning/rmake.rs:1:5 | 1 | use std::path::Path; | ^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `run_make_support::rfs::remove_file` --> /home/jyn/src/rust2/tests/run-make/linker-warning/rmake.rs:3:5 | 3 | use run_make_support::rfs::remove_file; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted ------------------------------------------ test [run-make] tests/run-make/linker-warning ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 377 filtered out; finished in 285.89ms ``` After: ``` Testing stage1 compiletest suite=run-make mode=run-make (x86_64-unknown-linux-gnu) running 1 tests ------rmake stdout------------------------------ ------rmake stderr------------------------------ assert_contains_regex: === HAYSTACK === error: linking with `./fake-linker` failed: exit status: 1 | = note: LC_ALL="C" PATH="/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin:...:/bin" VSLANG="1033" "./fake-linker" "-m64" "/tmp/rustcYqdAZT/symbols.o" "main.main.d17f5fbe6225cf88-cgu.0.rcgu.o" "main.2uoctswmurc6ir5rvoay0p9ke.rcgu.o" "-Wl,--as-needed" "-Wl,-Bstatic" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-B/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "-fuse-ld=lld" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/test/run-make/linker-warning/rmake_out" "-L" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" = note: error: baz error: aborting due to 1 previous error === NEEDLE === fake-linker.*run_make_error assert_not_contains_regex: === HAYSTACK === === NEEDLE === fake-linker.*run_make_error ------------------------------------------ . test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 377 filtered out; finished in 314.81ms ``` --- src/tools/compiletest/src/runtest.rs | 38 ++++++++------ src/tools/compiletest/src/runtest/run_make.rs | 13 +++-- .../run-make-support/src/assertion_helpers.rs | 58 +++++++++------------- 3 files changed, 54 insertions(+), 55 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7b11bf3b121..4a4494a1e23 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -410,7 +410,12 @@ impl<'test> TestCx<'test> { truncated: Truncated::No, cmdline: format!("{cmd:?}"), }; - self.dump_output(&proc_res.stdout, &proc_res.stderr); + self.dump_output( + self.config.verbose, + &cmd.get_program().to_string_lossy(), + &proc_res.stdout, + &proc_res.stderr, + ); proc_res } @@ -1401,7 +1406,12 @@ impl<'test> TestCx<'test> { cmdline, }; - self.dump_output(&result.stdout, &result.stderr); + self.dump_output( + self.config.verbose, + &command.get_program().to_string_lossy(), + &result.stdout, + &result.stderr, + ); result } @@ -1816,12 +1826,22 @@ impl<'test> TestCx<'test> { } } - fn dump_output(&self, out: &str, err: &str) { + fn dump_output(&self, print_output: bool, proc_name: &str, out: &str, err: &str) { let revision = if let Some(r) = self.revision { format!("{}.", r) } else { String::new() }; self.dump_output_file(out, &format!("{}out", revision)); self.dump_output_file(err, &format!("{}err", revision)); - self.maybe_dump_to_stdout(out, err); + + if !print_output { + return; + } + + let proc_name = Path::new(proc_name).file_name().unwrap().to_string_lossy(); + println!("------{proc_name} stdout------------------------------"); + println!("{}", out); + println!("------{proc_name} stderr------------------------------"); + println!("{}", err); + println!("------------------------------------------"); } fn dump_output_file(&self, out: &str, extension: &str) { @@ -1874,16 +1894,6 @@ impl<'test> TestCx<'test> { output_base_name(self.config, self.testpaths, self.safe_revision()) } - fn maybe_dump_to_stdout(&self, out: &str, err: &str) { - if self.config.verbose { - println!("------stdout------------------------------"); - println!("{}", out); - println!("------stderr------------------------------"); - println!("{}", err); - println!("------------------------------------------"); - } - } - fn error(&self, err: &str) { match self.revision { Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 04bc2d7787d..85ade5b727a 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -517,14 +517,13 @@ impl TestCx<'_> { let proc = disable_error_reporting(|| cmd.spawn().expect("failed to spawn `rmake`")); let (Output { stdout, stderr, status }, truncated) = self.read2_abbreviated(proc); + let stdout = String::from_utf8_lossy(&stdout).into_owned(); + let stderr = String::from_utf8_lossy(&stderr).into_owned(); + // This conditions on `status.success()` so we don't print output twice on error. + // NOTE: this code is called from a libtest thread, so it's hidden by default unless --nocapture is passed. + self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr); if !status.success() { - let res = ProcRes { - status, - stdout: String::from_utf8_lossy(&stdout).into_owned(), - stderr: String::from_utf8_lossy(&stderr).into_owned(), - truncated, - cmdline: format!("{:?}", cmd), - }; + let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) }; self.fatal_proc_rec("rmake recipe failed to complete", &res); } } diff --git a/src/tools/run-make-support/src/assertion_helpers.rs b/src/tools/run-make-support/src/assertion_helpers.rs index b4da65aff4a..e84a3cf633f 100644 --- a/src/tools/run-make-support/src/assertion_helpers.rs +++ b/src/tools/run-make-support/src/assertion_helpers.rs @@ -5,16 +5,31 @@ use std::path::Path; use crate::{fs, regex}; +fn print<'a, 'e, A: AsRef, E: AsRef>( + assertion_kind: &str, + haystack: &'a A, + needle: &'e E, +) -> (&'a str, &'e str) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); + eprintln!("{assertion_kind}:"); + eprintln!("=== HAYSTACK ==="); + eprintln!("{}", haystack); + eprintln!("=== NEEDLE ==="); + eprintln!("{}", needle); + (haystack, needle) +} + /// Assert that `actual` is equal to `expected`. #[track_caller] pub fn assert_equals, E: AsRef>(actual: A, expected: E) { let actual = actual.as_ref(); let expected = expected.as_ref(); + eprintln!("=== ACTUAL TEXT ==="); + eprintln!("{}", actual); + eprintln!("=== EXPECTED ==="); + eprintln!("{}", expected); if actual != expected { - eprintln!("=== ACTUAL TEXT ==="); - eprintln!("{}", actual); - eprintln!("=== EXPECTED ==="); - eprintln!("{}", expected); panic!("expected text was not found in actual text"); } } @@ -22,13 +37,8 @@ pub fn assert_equals, E: AsRef>(actual: A, expected: E) { /// Assert that `haystack` contains `needle`. #[track_caller] pub fn assert_contains, N: AsRef>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_contains", &haystack, &needle); if !haystack.contains(needle) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was not found in haystack"); } } @@ -36,13 +46,8 @@ pub fn assert_contains, N: AsRef>(haystack: H, needle: N) { /// Assert that `haystack` does not contain `needle`. #[track_caller] pub fn assert_not_contains, N: AsRef>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_not_contains", &haystack, &needle); if haystack.contains(needle) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was unexpectedly found in haystack"); } } @@ -50,14 +55,9 @@ pub fn assert_not_contains, N: AsRef>(haystack: H, needle: N) /// Assert that `haystack` contains the regex pattern `needle`. #[track_caller] pub fn assert_contains_regex, N: AsRef>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_contains_regex", &haystack, &needle); let re = regex::Regex::new(needle).unwrap(); if !re.is_match(haystack) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was not found in haystack"); } } @@ -65,14 +65,9 @@ pub fn assert_contains_regex, N: AsRef>(haystack: H, needle: /// Assert that `haystack` does not contain the regex pattern `needle`. #[track_caller] pub fn assert_not_contains_regex, N: AsRef>(haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_not_contains_regex", &haystack, &needle); let re = regex::Regex::new(needle).unwrap(); if re.is_match(haystack) { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle was unexpectedly found in haystack"); } } @@ -80,13 +75,8 @@ pub fn assert_not_contains_regex, N: AsRef>(haystack: H, need /// Assert that `haystack` contains `needle` a `count` number of times. #[track_caller] pub fn assert_count_is, N: AsRef>(count: usize, haystack: H, needle: N) { - let haystack = haystack.as_ref(); - let needle = needle.as_ref(); + let (haystack, needle) = print("assert_count_is", &haystack, &needle); if count != haystack.matches(needle).count() { - eprintln!("=== HAYSTACK ==="); - eprintln!("{}", haystack); - eprintln!("=== NEEDLE ==="); - eprintln!("{}", needle); panic!("needle did not appear {count} times in haystack"); } } -- cgit 1.4.1-3-g733a5 From 056eb758e7e68df9c1cdcc3a91a07372df4de49c Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 12 Dec 2024 08:07:59 -0500 Subject: show which test the `rmake` process belongs to --- src/tools/compiletest/src/runtest.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 4a4494a1e23..8af4325e7b1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fs::{self, File, create_dir_all}; use std::hash::{DefaultHasher, Hash, Hasher}; use std::io::prelude::*; @@ -1836,7 +1836,20 @@ impl<'test> TestCx<'test> { return; } - let proc_name = Path::new(proc_name).file_name().unwrap().to_string_lossy(); + let path = Path::new(proc_name); + let proc_name = if path.file_stem().is_some_and(|p| p == "rmake") { + OsString::from_iter( + path.parent() + .unwrap() + .file_name() + .into_iter() + .chain(Some(OsStr::new("/"))) + .chain(path.file_name()), + ) + } else { + path.file_name().unwrap().into() + }; + let proc_name = proc_name.to_string_lossy(); println!("------{proc_name} stdout------------------------------"); println!("{}", out); println!("------{proc_name} stderr------------------------------"); -- cgit 1.4.1-3-g733a5 From 9e22cbf48bc1fca1ec3d551464b2c94d520afd97 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 15 Dec 2024 16:35:17 +0100 Subject: internal: Show mir eval errors on hover with debug env var set --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 100 ++++++--------------- .../src/handlers/inline_const_as_literal.rs | 6 +- .../rust-analyzer/crates/ide/src/hover/render.rs | 65 +++++++++++--- .../rust-analyzer/crates/ide/src/interpret.rs | 35 ++++++-- .../crates/rust-analyzer/src/cli/analysis_stats.rs | 4 +- 5 files changed, 113 insertions(+), 97 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 83d72dfcf14..3bc2eee1e7c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2649,24 +2649,31 @@ impl Const { Type::from_value_def(db, self.id) } - /// Evaluate the constant and return the result as a string. - /// - /// This function is intended for IDE assistance, different from [`Const::render_eval`]. - pub fn eval(self, db: &dyn HirDatabase) -> Result { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - Ok(format!("{}", c.display(db, self.krate(db).edition(db)))) + /// Evaluate the constant. + pub fn eval(self, db: &dyn HirDatabase) -> Result { + db.const_eval(self.id.into(), Substitution::empty(Interner), None) + .map(|it| EvaluatedConst { const_: it, def: self.id.into() }) } +} - /// Evaluate the constant and return the result as a string, with more detailed information. - /// - /// This function is intended for user-facing display. - pub fn render_eval( - self, - db: &dyn HirDatabase, - edition: Edition, - ) -> Result { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - let data = &c.data(Interner); +impl HasVisibility for Const { + fn visibility(&self, db: &dyn HirDatabase) -> Visibility { + db.const_visibility(self.id) + } +} + +pub struct EvaluatedConst { + def: DefWithBodyId, + const_: hir_ty::Const, +} + +impl EvaluatedConst { + pub fn render(&self, db: &dyn HirDatabase, edition: Edition) -> String { + format!("{}", self.const_.display(db, edition)) + } + + pub fn render_debug(&self, db: &dyn HirDatabase) -> Result { + let data = self.const_.data(Interner); if let TyKind::Scalar(s) = data.ty.kind(Interner) { if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) { if let hir_ty::ConstValue::Concrete(c) = &data.value { @@ -2689,17 +2696,7 @@ impl Const { } } } - if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) { - Ok(s) - } else { - Ok(format!("{}", c.display(db, edition))) - } - } -} - -impl HasVisibility for Const { - fn visibility(&self, db: &dyn HirDatabase) -> Visibility { - db.const_visibility(self.id) + mir::render_const_using_debug_impl(db, self.def, &self.const_) } } @@ -2729,51 +2726,10 @@ impl Static { Type::from_value_def(db, self.id) } - /// Evaluate the static and return the result as a string. - /// - /// This function is intended for IDE assistance, different from [`Static::render_eval`]. - pub fn eval(self, db: &dyn HirDatabase) -> Result { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - Ok(format!("{}", c.display(db, self.krate(db).edition(db)))) - } - - /// Evaluate the static and return the result as a string, with more detailed information. - /// - /// This function is intended for user-facing display. - pub fn render_eval( - self, - db: &dyn HirDatabase, - edition: Edition, - ) -> Result { - let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?; - let data = &c.data(Interner); - if let TyKind::Scalar(s) = data.ty.kind(Interner) { - if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) { - if let hir_ty::ConstValue::Concrete(c) = &data.value { - if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned { - let value = u128::from_le_bytes(mir::pad16(b, false)); - let value_signed = - i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_)))); - let mut result = if let Scalar::Int(_) = s { - value_signed.to_string() - } else { - value.to_string() - }; - if value >= 10 { - format_to!(result, " ({value:#X})"); - return Ok(result); - } else { - return Ok(result); - } - } - } - } - } - if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) { - Ok(s) - } else { - Ok(format!("{}", c.display(db, edition))) - } + /// Evaluate the static initializer. + pub fn eval(self, db: &dyn HirDatabase) -> Result { + db.const_eval(self.id.into(), Substitution::empty(Interner), None) + .map(|it| EvaluatedConst { const_: it, def: self.id.into() }) } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs index 2bd4c4da1e2..c92c22378f8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -1,3 +1,4 @@ +use hir::HasCrate; use syntax::{ast, AstNode}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -51,7 +52,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::MatchExpr(_) | ast::Expr::MacroExpr(_) | ast::Expr::BinExpr(_) - | ast::Expr::CallExpr(_) => konst.eval(ctx.sema.db).ok()?, + | ast::Expr::CallExpr(_) => konst + .eval(ctx.sema.db) + .ok()? + .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)), _ => return None, }; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index 5a00d635698..e617d462ecd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -1,5 +1,5 @@ //! Logic for rendering the different hover messages -use std::{mem, ops::Not}; +use std::{env, mem, ops::Not}; use either::Either; use hir::{ @@ -28,6 +28,7 @@ use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T} use crate::{ doc_links::{remove_links, rewrite_links}, hover::{notable_traits, walk_and_push_ty}, + interpret::render_const_eval_error, HoverAction, HoverConfig, HoverResult, Markup, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, }; @@ -464,41 +465,77 @@ pub(super) fn definition( Ok(it) => { Some(if it >= 10 { format!("{it} ({it:#X})") } else { format!("{it}") }) } - Err(_) => it.value(db).map(|it| format!("{it:?}")), + Err(err) => { + let res = it.value(db).map(|it| format!("{it:?}")); + if env::var_os("RA_DEV").is_some() { + let res = res.as_deref().unwrap_or(""); + Some(format!("{res} ({})", render_const_eval_error(db, err, edition))) + } else { + res + } + } } } else { None } } Definition::Const(it) => { - let body = it.render_eval(db, edition); - match body { - Ok(it) => Some(it), - Err(_) => { + let body = it.eval(db); + Some(match body { + Ok(it) => match it.render_debug(db) { + Ok(it) => it, + Err(err) => { + let it = it.render(db, edition); + if env::var_os("RA_DEV").is_some() { + format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + } else { + it + } + } + }, + Err(err) => { let source = it.source(db)?; let mut body = source.value.body()?.syntax().clone(); if let Some(macro_file) = source.file_id.macro_file() { let span_map = db.expansion_span_map(macro_file); body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } - Some(body.to_string()) + if env::var_os("RA_DEV").is_some() { + format!("{body}\n{}", render_const_eval_error(db, err, edition)) + } else { + body.to_string() + } } - } + }) } Definition::Static(it) => { - let body = it.render_eval(db, edition); - match body { - Ok(it) => Some(it), - Err(_) => { + let body = it.eval(db); + Some(match body { + Ok(it) => match it.render_debug(db) { + Ok(it) => it, + Err(err) => { + let it = it.render(db, edition); + if env::var_os("RA_DEV").is_some() { + format!("{it}\n{}", render_const_eval_error(db, err.into(), edition)) + } else { + it + } + } + }, + Err(err) => { let source = it.source(db)?; let mut body = source.value.body()?.syntax().clone(); if let Some(macro_file) = source.file_id.macro_file() { let span_map = db.expansion_span_map(macro_file); body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into()); } - Some(body.to_string()) + if env::var_os("RA_DEV").is_some() { + format!("{body}\n{}", render_const_eval_error(db, err, edition)) + } else { + body.to_string() + } } - } + }) } _ => None, }; diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 5fa6f4e4842..e0fdc3dd6f9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -1,5 +1,6 @@ -use hir::{DefWithBody, Semantics}; +use hir::{ConstEvalError, DefWithBody, Semantics}; use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; +use span::Edition; use std::time::{Duration, Instant}; use stdx::format_to; use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; @@ -47,18 +48,36 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura None => format!("file://{path} range {text_range:?}"), } }; + let edition = def.module(db).krate().edition(db); let start_time = Instant::now(); let res = match def { DefWithBody::Function(it) => it.eval(db, span_formatter), - DefWithBody::Static(it) => it.eval(db), - DefWithBody::Const(it) => it.eval(db), + DefWithBody::Static(it) => it.eval(db).map(|it| it.render(db, edition)), + DefWithBody::Const(it) => it.eval(db).map(|it| it.render(db, edition)), _ => unreachable!(), }; - let res = res.unwrap_or_else(|e| { - let mut r = String::new(); - _ = e.pretty_print(&mut r, db, span_formatter, def.module(db).krate().edition(db)); - r - }); + let res = res.unwrap_or_else(|e| render_const_eval_error(db, e, edition)); let duration = Instant::now() - start_time; Some((duration, res)) } + +pub(crate) fn render_const_eval_error( + db: &RootDatabase, + e: ConstEvalError, + edition: Edition, +) -> String { + let span_formatter = |file_id, text_range: TextRange| { + let path = &db + .source_root(db.file_source_root(file_id)) + .path_for_file(&file_id) + .map(|x| x.to_string()); + let path = path.as_deref().unwrap_or(""); + match db.line_index(file_id).try_line_col(text_range.start()) { + Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col), + None => format!("file://{path} range {text_range:?}"), + } + }; + let mut r = String::new(); + _ = e.pretty_print(&mut r, db, span_formatter, edition); + r +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index e3ea441f3ab..66cd2e424e3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -331,8 +331,8 @@ impl flags::AnalysisStats { let mut fail = 0; for &b in bodies { let res = match b { - DefWithBody::Const(c) => c.render_eval(db, Edition::LATEST), - DefWithBody::Static(s) => s.render_eval(db, Edition::LATEST), + DefWithBody::Const(c) => c.eval(db), + DefWithBody::Static(s) => s.eval(db), _ => continue, }; all += 1; -- cgit 1.4.1-3-g733a5 From 31a462f6e07032d81dbb8521062e6d1608f5da76 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 15 Dec 2024 16:37:43 +0100 Subject: fix: Fix proc-macro dylib names on windows --- src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 977ca8bafd8..26f6af84aae 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -199,18 +199,15 @@ fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result to.push("rust-analyzer-proc-macros"); _ = fs::create_dir(&to); - let file_name = path.file_name().ok_or_else(|| { + let file_name = path.file_stem().ok_or_else(|| { io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}")) })?; to.push({ // Generate a unique number by abusing `HashMap`'s hasher. // Maybe this will also "inspire" a libs team member to finally put `rand` in libstd. - let t = RandomState::new().build_hasher().finish(); - let mut unique_name = t.to_string(); - unique_name.push_str(file_name); - unique_name.push('-'); - unique_name + let unique_name = RandomState::new().build_hasher().finish(); + format!("{file_name}-{unique_name}.dll") }); fs::copy(path, &to)?; Ok(to) -- cgit 1.4.1-3-g733a5 From 53b2c7cc95a034467a05a147db1eb4f5666815f8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 2 Dec 2024 11:27:57 +0000 Subject: Rename `value` field to `expr` to simplify later commits' diffs --- compiler/rustc_ast/src/ast.rs | 10 +++++----- compiler/rustc_ast/src/attr/mod.rs | 8 ++++---- compiler/rustc_ast/src/mut_visit.rs | 4 ++-- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 6 +++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 ++-- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 6 ++---- compiler/rustc_resolve/src/rustdoc.rs | 4 ++-- .../src/error_reporting/traits/on_unimplemented.rs | 2 +- .../clippy_lints/src/attrs/should_panic_without_expect.rs | 2 +- .../clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs | 2 +- src/tools/clippy/clippy_lints/src/large_include_file.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 4 ++-- 14 files changed, 28 insertions(+), 30 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f0099fa8adc..76d769a8dbd 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1759,7 +1759,7 @@ pub enum AttrArgs { /// Span of the `=` token. eq_span: Span, - value: AttrArgsEq, + expr: AttrArgsEq, }, } @@ -1804,7 +1804,7 @@ impl AttrArgs { match self { AttrArgs::Empty => None, AttrArgs::Delimited(args) => Some(args.dspan.entire()), - AttrArgs::Eq { eq_span, value } => Some(eq_span.to(value.span())), + AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span())), } } @@ -1814,7 +1814,7 @@ impl AttrArgs { match self { AttrArgs::Empty => TokenStream::default(), AttrArgs::Delimited(args) => args.tokens.clone(), - AttrArgs::Eq { value, .. } => TokenStream::from_ast(value.unwrap_ast()), + AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr.unwrap_ast()), } } } @@ -1828,10 +1828,10 @@ where match self { AttrArgs::Empty => {} AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), - AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { unreachable!("hash_stable {:?}", expr); } - AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } => { + AttrArgs::Eq { eq_span, expr: AttrArgsEq::Hir(lit) } => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0d79cadef34..a13eb4f4cab 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -268,7 +268,7 @@ impl AttrItem { /// ``` fn value_str(&self) -> Option { match &self.args { - AttrArgs::Eq { value, .. } => value.value_str(), + AttrArgs::Eq { expr, .. } => expr.value_str(), AttrArgs::Delimited(_) | AttrArgs::Empty => None, } } @@ -492,7 +492,7 @@ impl MetaItemKind { MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List) } AttrArgs::Delimited(..) => None, - AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => match expr.kind { + AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => match expr.kind { ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) @@ -501,7 +501,7 @@ impl MetaItemKind { } _ => None, }, - AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => { Some(MetaItemKind::NameValue(lit.clone())) } } @@ -704,7 +704,7 @@ pub fn mk_attr_name_value_str( tokens: None, }); let path = Path::from_ident(Ident::new(name, span)); - let args = AttrArgs::Eq { eq_span: span, value: AttrArgsEq::Ast(expr) }; + let args = AttrArgs::Eq { eq_span: span, expr: AttrArgsEq::Ast(expr) }; mk_attr(g, style, unsafety, path, args, span) } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b44e2d9cace..ecf637a79ab 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -451,8 +451,8 @@ fn visit_attr_args(vis: &mut T, args: &mut AttrArgs) { match args { AttrArgs::Empty => {} AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq { eq_span, value } => { - vis.visit_expr(value.unwrap_ast_mut()); + AttrArgs::Eq { eq_span, expr } => { + vis.visit_expr(expr.unwrap_ast_mut()); vis.visit_span(eq_span); } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 22db4438e31..5bfdc19e156 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1287,7 +1287,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) - match args { AttrArgs::Empty => {} AttrArgs::Delimited(_args) => {} - AttrArgs::Eq { value, .. } => try_visit!(visitor.visit_expr(value.unwrap_ast())), + AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr.unwrap_ast())), } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e4600b0f636..a343913b94a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -896,8 +896,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - &AttrArgs::Eq { eq_span, ref value } => { - let expr = value.unwrap_ast(); + &AttrArgs::Eq { eq_span, ref expr } => { + let expr = expr.unwrap_ast(); // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind @@ -913,7 +913,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } + AttrArgs::Eq { eq_span, expr: AttrArgsEq::Hir(lit) } } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 04ffa2cffe3..5025d581ab0 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -648,14 +648,14 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 37556c064d8..ffbd0c5269b 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> { AttrArgs::Delimited(args) } else if self.eat(&token::Eq) { let eq_span = self.prev_token.span; - AttrArgs::Eq { eq_span, value: AttrArgsEq::Ast(self.parse_expr_force_collect()?) } + AttrArgs::Eq { eq_span, expr: AttrArgsEq::Ast(self.parse_expr_force_collect()?) } } else { AttrArgs::Empty }) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index aab3f10bc66..f6ce26bd24a 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -70,7 +70,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { if let ast::ExprKind::Lit(token_lit) = expr.kind { let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span); let res = match res { @@ -116,9 +116,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met return Err(err); } } - AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { - MetaItemKind::NameValue(lit.clone()) - } + AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => MetaItemKind::NameValue(lit.clone()), }, }) } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 65128ceb866..1fbfe56d95d 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -220,9 +220,9 @@ pub fn attrs_to_doc_fragments<'a>( fn span_for_value(attr: &ast::Attribute) -> Span { if let ast::AttrKind::Normal(normal) = &attr.kind - && let ast::AttrArgs::Eq { value, .. } = &normal.item.args + && let ast::AttrArgs::Eq { expr, .. } = &normal.item.args { - value.span().with_ctxt(attr.span.ctxt()) + expr.span().with_ctxt(attr.span.ctxt()) } else { attr.span } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index f10314c1c9e..6368cd473f1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -639,7 +639,7 @@ impl<'tcx> OnUnimplementedDirective { let report_span = match &item.args { AttrArgs::Empty => item.path.span, AttrArgs::Delimited(args) => args.dspan.entire(), - AttrArgs::Eq { eq_span, value } => eq_span.to(value.span()), + AttrArgs::Eq { eq_span, expr } => eq_span.to(expr.span()), }; if let Some(item_def_id) = item_def_id.as_local() { diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs index 97cffeb098e..1d6b3388e59 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -9,7 +9,7 @@ use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq { value: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args { + if let AttrArgs::Eq { expr: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs index 2182689f985..f2886164a46 100644 --- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -12,7 +12,7 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { if !attr.span.from_expansion() && let AttrKind::Normal(ref normal) = attr.kind && normal.item.path == sym::doc - && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrArgs::Eq { expr: AttrArgsEq::Hir(ref meta), .. } = normal.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index b38e362410e..a0657a233c1 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -96,7 +96,7 @@ impl LateLintPass<'_> for LargeIncludeFile { && let AttrKind::Normal(ref normal) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrArgs::Eq { expr: AttrArgsEq::Hir(ref meta), .. } = normal.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 12074dd16e6..6df0748c117 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -872,8 +872,8 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { match (l, r) { (Empty, Empty) => true, (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra), - (Eq { value: AttrArgsEq::Ast(le), .. }, Eq{ value: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re), - (Eq { value: AttrArgsEq::Hir(ll), .. }, Eq{ value: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind, + (Eq { expr: AttrArgsEq::Ast(le), .. }, Eq{ expr: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re), + (Eq { expr: AttrArgsEq::Hir(ll), .. }, Eq{ expr: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind, _ => false, } } -- cgit 1.4.1-3-g733a5 From d50c0a5480257cbac33b312cb633777f3d2b2483 Mon Sep 17 00:00:00 2001 From: Jonathan Dönszelmann Date: Thu, 17 Oct 2024 01:14:01 +0200 Subject: Add hir::Attribute --- Cargo.lock | 4 +- compiler/rustc_ast/src/ast.rs | 12 +- compiler/rustc_ast/src/attr/mod.rs | 263 +++++++++++++++----- compiler/rustc_ast/src/entry.rs | 4 +- compiler/rustc_ast/src/lib.rs | 12 +- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 6 +- compiler/rustc_ast_lowering/src/lib.rs | 44 ++-- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 17 +- compiler/rustc_attr/src/builtin.rs | 266 ++++++++++----------- compiler/rustc_codegen_ssa/Cargo.toml | 1 + .../rustc_codegen_ssa/src/assert_module_sources.rs | 8 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 85 ++++--- compiler/rustc_codegen_ssa/src/target_features.rs | 4 +- compiler/rustc_expand/src/base.rs | 18 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 4 +- compiler/rustc_hir/Cargo.toml | 1 + compiler/rustc_hir/src/arena.rs | 2 +- compiler/rustc_hir/src/hir.rs | 252 ++++++++++++++++++- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir/src/lang_items.rs | 8 +- compiler/rustc_hir/src/stable_hash_impls.rs | 10 +- compiler/rustc_hir_pretty/src/lib.rs | 114 ++++++++- compiler/rustc_incremental/src/assert_dep_graph.rs | 4 +- .../rustc_incremental/src/persist/dirty_clean.rs | 6 +- compiler/rustc_lint/src/builtin.rs | 6 +- compiler/rustc_lint/src/levels.rs | 15 +- compiler/rustc_lint/src/nonstandard_style.rs | 63 ++--- compiler/rustc_lint/src/passes.rs | 6 +- compiler/rustc_lint_defs/src/lib.rs | 7 +- compiler/rustc_metadata/src/creader.rs | 9 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- .../src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 6 +- compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/middle/limits.rs | 32 ++- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/query/on_disk_cache.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 13 +- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 22 +- compiler/rustc_middle/src/ty/parameterized.rs | 3 +- compiler/rustc_mir_build/src/build/custom/mod.rs | 3 +- compiler/rustc_parse/src/parser/attr.rs | 5 +- compiler/rustc_parse/src/parser/mod.rs | 8 +- compiler/rustc_parse/src/validate_attr.rs | 6 +- compiler/rustc_passes/src/abi_test.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 23 +- compiler/rustc_passes/src/diagnostic_items.rs | 5 +- compiler/rustc_passes/src/input_stats.rs | 2 +- compiler/rustc_passes/src/layout_test.rs | 2 +- compiler/rustc_passes/src/lib_features.rs | 2 +- .../rustc_query_system/src/ich/impls_syntax.rs | 28 +-- compiler/rustc_resolve/src/macros.rs | 4 +- compiler/rustc_resolve/src/rustdoc.rs | 39 ++- compiler/rustc_smir/Cargo.toml | 2 +- compiler/rustc_smir/src/rustc_smir/context.rs | 11 +- .../src/error_reporting/traits/on_unimplemented.rs | 7 +- src/librustdoc/clean/inline.rs | 22 +- src/librustdoc/clean/mod.rs | 28 +-- src/librustdoc/clean/types.rs | 48 ++-- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/doctest.rs | 4 +- src/librustdoc/doctest/rust.rs | 2 +- .../clippy/clippy_lints/src/attrs/inline_always.rs | 2 +- .../src/attrs/should_panic_without_expect.rs | 4 +- .../clippy_lints/src/cognitive_complexity.rs | 3 +- .../clippy_lints/src/doc/empty_line_after.rs | 4 +- .../src/doc/include_in_doc_without_cfg.rs | 10 +- src/tools/clippy/clippy_lints/src/doc/mod.rs | 3 +- .../src/doc/suspicious_doc_comments.rs | 5 +- .../src/doc/too_long_first_doc_paragraph.rs | 3 +- .../clippy/clippy_lints/src/functions/must_use.rs | 3 +- .../clippy/clippy_lints/src/large_include_file.rs | 8 +- src/tools/clippy/clippy_lints/src/macro_use.rs | 3 +- .../clippy_lints/src/matches/match_like_matches.rs | 4 +- src/tools/clippy/clippy_lints/src/missing_doc.rs | 16 +- .../clippy/clippy_lints/src/missing_inline.rs | 4 +- .../clippy_lints/src/needless_pass_by_value.rs | 5 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 3 +- src/tools/clippy/clippy_utils/src/attrs.rs | 58 +++-- src/tools/clippy/clippy_utils/src/lib.rs | 31 +-- src/tools/clippy/clippy_utils/src/msrvs.rs | 16 +- .../macros/genercs-in-path-with-prettry-hir.stdout | 4 +- 89 files changed, 1143 insertions(+), 658 deletions(-) (limited to 'src/tools') diff --git a/Cargo.lock b/Cargo.lock index 923d4017c0c..5eeb855aacb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3521,6 +3521,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", + "rustc_hir_pretty", "rustc_incremental", "rustc_index", "rustc_macros", @@ -3786,6 +3787,7 @@ dependencies = [ "rustc_span", "rustc_target", "smallvec", + "thin-vec", "tracing", ] @@ -4454,9 +4456,9 @@ version = "0.0.0" dependencies = [ "rustc_abi", "rustc_ast", - "rustc_ast_pretty", "rustc_data_structures", "rustc_hir", + "rustc_hir_pretty", "rustc_middle", "rustc_session", "rustc_span", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 76d769a8dbd..b42c0834786 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1759,7 +1759,7 @@ pub enum AttrArgs { /// Span of the `=` token. eq_span: Span, - expr: AttrArgsEq, + expr: P, }, } @@ -1804,7 +1804,7 @@ impl AttrArgs { match self { AttrArgs::Empty => None, AttrArgs::Delimited(args) => Some(args.dspan.entire()), - AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span())), + AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)), } } @@ -1814,7 +1814,7 @@ impl AttrArgs { match self { AttrArgs::Empty => TokenStream::default(), AttrArgs::Delimited(args) => args.tokens.clone(), - AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr.unwrap_ast()), + AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr), } } } @@ -1828,13 +1828,9 @@ where match self { AttrArgs::Empty => {} AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), - AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr, .. } => { unreachable!("hash_stable {:?}", expr); } - AttrArgs::Eq { eq_span, expr: AttrArgsEq::Hir(lit) } => { - eq_span.hash_stable(ctx, hasher); - lit.hash_stable(ctx, hasher); - } } } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index a13eb4f4cab..8ee3d4d590c 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,5 +1,6 @@ //! Functions dealing with attributes and meta items. +use std::fmt::Debug; use std::iter; use std::sync::atomic::{AtomicU32, Ordering}; @@ -10,9 +11,9 @@ use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; use crate::ast::{ - AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, - DelimArgs, Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, - NormalAttr, Path, PathSegment, Safety, + AttrArgs, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, DelimArgs, + Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path, + PathSegment, Safety, }; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; @@ -66,11 +67,27 @@ impl Attribute { AttrKind::DocComment(..) => panic!("unexpected doc comment"), } } +} + +impl AttributeExt for Attribute { + fn id(&self) -> AttrId { + self.id + } + + fn value_span(&self) -> Option { + match &self.kind { + AttrKind::Normal(normal) => match &normal.item.args { + AttrArgs::Eq { expr, .. } => Some(expr.span), + _ => None, + }, + AttrKind::DocComment(..) => None, + } + } /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not /// a doc comment) will return `false`. - pub fn is_doc_comment(&self) -> bool { + fn is_doc_comment(&self) -> bool { match self.kind { AttrKind::Normal(..) => false, AttrKind::DocComment(..) => true, @@ -78,7 +95,7 @@ impl Attribute { } /// For a single-segment attribute, returns its name; otherwise, returns `None`. - pub fn ident(&self) -> Option { + fn ident(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => { if let [ident] = &*normal.item.path.segments { @@ -91,28 +108,14 @@ impl Attribute { } } - pub fn name_or_empty(&self) -> Symbol { - self.ident().unwrap_or_else(Ident::empty).name - } - - pub fn path(&self) -> SmallVec<[Symbol; 1]> { - match &self.kind { - AttrKind::Normal(normal) => { - normal.item.path.segments.iter().map(|s| s.ident.name).collect() - } - AttrKind::DocComment(..) => smallvec![sym::doc], - } - } - - #[inline] - pub fn has_name(&self, name: Symbol) -> bool { + fn ident_path(&self) -> Option> { match &self.kind { - AttrKind::Normal(normal) => normal.item.path == name, - AttrKind::DocComment(..) => false, + AttrKind::Normal(p) => Some(p.item.path.segments.iter().map(|i| i.ident).collect()), + AttrKind::DocComment(_, _) => None, } } - pub fn path_matches(&self, name: &[Symbol]) -> bool { + fn path_matches(&self, name: &[Symbol]) -> bool { match &self.kind { AttrKind::Normal(normal) => { normal.item.path.segments.len() == name.len() @@ -128,7 +131,11 @@ impl Attribute { } } - pub fn is_word(&self) -> bool { + fn span(&self) -> Span { + self.span + } + + fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { matches!(normal.item.args, AttrArgs::Empty) } else { @@ -143,7 +150,7 @@ impl Attribute { /// #[attr = ""] // Returns `None`. /// #[attr] // Returns `None`. /// ``` - pub fn meta_item_list(&self) -> Option> { + fn meta_item_list(&self) -> Option> { match &self.kind { AttrKind::Normal(normal) => normal.item.meta_item_list(), AttrKind::DocComment(..) => None, @@ -165,7 +172,7 @@ impl Attribute { /// ```text /// #[attr("value")] /// ``` - pub fn value_str(&self) -> Option { + fn value_str(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => normal.item.value_str(), AttrKind::DocComment(..) => None, @@ -177,7 +184,7 @@ impl Attribute { /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. /// * `#[doc(...)]` returns `None`. - pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { match &self.kind { AttrKind::DocComment(kind, data) => Some((*data, *kind)), AttrKind::Normal(normal) if normal.item.path == sym::doc => { @@ -191,7 +198,7 @@ impl Attribute { /// * `///doc` returns `Some("doc")`. /// * `#[doc = "doc"]` returns `Some("doc")`. /// * `#[doc(...)]` returns `None`. - pub fn doc_str(&self) -> Option { + fn doc_str(&self) -> Option { match &self.kind { AttrKind::DocComment(.., data) => Some(*data), AttrKind::Normal(normal) if normal.item.path == sym::doc => normal.item.value_str(), @@ -199,14 +206,14 @@ impl Attribute { } } - pub fn may_have_doc_links(&self) -> bool { - self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str())) + fn style(&self) -> AttrStyle { + self.style } +} - pub fn is_proc_macro_attr(&self) -> bool { - [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] - .iter() - .any(|kind| self.has_name(*kind)) +impl Attribute { + pub fn may_have_doc_links(&self) -> bool { + self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str())) } /// Extracts the MetaItem from inside this Attribute. @@ -268,7 +275,12 @@ impl AttrItem { /// ``` fn value_str(&self) -> Option { match &self.args { - AttrArgs::Eq { expr, .. } => expr.value_str(), + AttrArgs::Eq { expr, .. } => match expr.kind { + ExprKind::Lit(token_lit) => { + LitKind::from_token_lit(token_lit).ok().and_then(|lit| lit.str()) + } + _ => None, + }, AttrArgs::Delimited(_) | AttrArgs::Empty => None, } } @@ -287,20 +299,6 @@ impl AttrItem { } } -impl AttrArgsEq { - fn value_str(&self) -> Option { - match self { - AttrArgsEq::Ast(expr) => match expr.kind { - ExprKind::Lit(token_lit) => { - LitKind::from_token_lit(token_lit).ok().and_then(|lit| lit.str()) - } - _ => None, - }, - AttrArgsEq::Hir(lit) => lit.kind.str(), - } - } -} - impl MetaItem { /// For a single-segment meta item, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option { @@ -439,7 +437,8 @@ impl MetaItem { } impl MetaItemKind { - fn list_from_tokens(tokens: TokenStream) -> Option> { + // public because it can be called in the hir + pub fn list_from_tokens(tokens: TokenStream) -> Option> { let mut tokens = tokens.trees().peekable(); let mut result = ThinVec::new(); while tokens.peek().is_some() { @@ -492,7 +491,7 @@ impl MetaItemKind { MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List) } AttrArgs::Delimited(..) => None, - AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => match expr.kind { + AttrArgs::Eq { expr, .. } => match expr.kind { ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) @@ -501,9 +500,6 @@ impl MetaItemKind { } _ => None, }, - AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => { - Some(MetaItemKind::NameValue(lit.clone())) - } } } } @@ -704,26 +700,175 @@ pub fn mk_attr_name_value_str( tokens: None, }); let path = Path::from_ident(Ident::new(name, span)); - let args = AttrArgs::Eq { eq_span: span, expr: AttrArgsEq::Ast(expr) }; + let args = AttrArgs::Eq { eq_span: span, expr }; mk_attr(g, style, unsafety, path, args, span) } -pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { +pub fn filter_by_name(attrs: &[A], name: Symbol) -> impl Iterator { attrs.iter().filter(move |attr| attr.has_name(name)) } -pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { +pub fn find_by_name(attrs: &[A], name: Symbol) -> Option<&A> { filter_by_name(attrs, name).next() } -pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option { +pub fn first_attr_value_str_by_name(attrs: &[impl AttributeExt], name: Symbol) -> Option { find_by_name(attrs, name).and_then(|attr| attr.value_str()) } -pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { +pub fn contains_name(attrs: &[impl AttributeExt], name: Symbol) -> bool { find_by_name(attrs, name).is_some() } pub fn list_contains_name(items: &[MetaItemInner], name: Symbol) -> bool { items.iter().any(|item| item.has_name(name)) } + +impl MetaItemLit { + pub fn value_str(&self) -> Option { + LitKind::from_token_lit(self.as_token_lit()).ok().and_then(|lit| lit.str()) + } +} + +pub trait AttributeExt: Debug { + fn id(&self) -> AttrId; + + fn name_or_empty(&self) -> Symbol { + self.ident().unwrap_or_else(Ident::empty).name + } + + /// Get the meta item list, `#[attr(meta item list)]` + fn meta_item_list(&self) -> Option>; + + /// Gets the value literal, as string, when using `#[attr = value]` + fn value_str(&self) -> Option; + + /// Gets the span of the value literal, as string, when using `#[attr = value]` + fn value_span(&self) -> Option; + + /// For a single-segment attribute, returns its name; otherwise, returns `None`. + fn ident(&self) -> Option; + + /// Checks whether the path of this attribute matches the name. + /// + /// Matches one segment of the path to each element in `name` + fn path_matches(&self, name: &[Symbol]) -> bool; + + /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). + /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not + /// a doc comment) will return `false`. + fn is_doc_comment(&self) -> bool; + + #[inline] + fn has_name(&self, name: Symbol) -> bool { + self.ident().map(|x| x.name == name).unwrap_or(false) + } + + /// get the span of the entire attribute + fn span(&self) -> Span; + + fn is_word(&self) -> bool; + + fn path(&self) -> SmallVec<[Symbol; 1]> { + self.ident_path() + .map(|i| i.into_iter().map(|i| i.name).collect()) + .unwrap_or(smallvec![sym::doc]) + } + + /// Returns None for doc comments + fn ident_path(&self) -> Option>; + + /// Returns the documentation if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some("doc")`. + /// * `#[doc = "doc"]` returns `Some("doc")`. + /// * `#[doc(...)]` returns `None`. + fn doc_str(&self) -> Option; + + fn is_proc_macro_attr(&self) -> bool { + [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] + .iter() + .any(|kind| self.has_name(*kind)) + } + + /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some(("doc", CommentKind::Line))`. + /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. + /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. + /// * `#[doc(...)]` returns `None`. + fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)>; + + fn style(&self) -> AttrStyle; +} + +// FIXME(fn_delegation): use function delegation instead of manually forwarding + +impl Attribute { + pub fn id(&self) -> AttrId { + AttributeExt::id(self) + } + + pub fn name_or_empty(&self) -> Symbol { + AttributeExt::name_or_empty(self) + } + + pub fn meta_item_list(&self) -> Option> { + AttributeExt::meta_item_list(self) + } + + pub fn value_str(&self) -> Option { + AttributeExt::value_str(self) + } + + pub fn value_span(&self) -> Option { + AttributeExt::value_span(self) + } + + pub fn ident(&self) -> Option { + AttributeExt::ident(self) + } + + pub fn path_matches(&self, name: &[Symbol]) -> bool { + AttributeExt::path_matches(self, name) + } + + pub fn is_doc_comment(&self) -> bool { + AttributeExt::is_doc_comment(self) + } + + #[inline] + pub fn has_name(&self, name: Symbol) -> bool { + AttributeExt::has_name(self, name) + } + + pub fn span(&self) -> Span { + AttributeExt::span(self) + } + + pub fn is_word(&self) -> bool { + AttributeExt::is_word(self) + } + + pub fn path(&self) -> SmallVec<[Symbol; 1]> { + AttributeExt::path(self) + } + + pub fn ident_path(&self) -> Option> { + AttributeExt::ident_path(self) + } + + pub fn doc_str(&self) -> Option { + AttributeExt::doc_str(self) + } + + pub fn is_proc_macro_attr(&self) -> bool { + AttributeExt::is_proc_macro_attr(self) + } + + pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + AttributeExt::doc_str_and_comment_kind(self) + } + + pub fn style(&self) -> AttrStyle { + AttributeExt::style(self) + } +} diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs index 45c4caca6e9..fffcb3ef988 100644 --- a/compiler/rustc_ast/src/entry.rs +++ b/compiler/rustc_ast/src/entry.rs @@ -1,7 +1,7 @@ use rustc_span::Symbol; use rustc_span::symbol::sym; -use crate::{Attribute, attr}; +use crate::attr::{self, AttributeExt}; #[derive(Debug)] pub enum EntryPointType { @@ -37,7 +37,7 @@ pub enum EntryPointType { } pub fn entry_point_type( - attrs: &[Attribute], + attrs: &[impl AttributeExt], at_root: bool, name: Option, ) -> EntryPointType { diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 7730d0b4b78..6372c66050e 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -44,20 +44,10 @@ pub mod token; pub mod tokenstream; pub mod visit; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; - pub use self::ast::*; pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: rustc_span::HashStableContext { - fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher); -} - -impl HashStable for ast::Attribute { - fn hash_stable(&self, hcx: &mut AstCtx, hasher: &mut StableHasher) { - hcx.hash_attr(self, hasher) - } -} +pub trait HashStableContext: rustc_span::HashStableContext {} diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ecf637a79ab..f07266a3e2d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -452,7 +452,7 @@ fn visit_attr_args(vis: &mut T, args: &mut AttrArgs) { AttrArgs::Empty => {} AttrArgs::Delimited(args) => visit_delim_args(vis, args), AttrArgs::Eq { eq_span, expr } => { - vis.visit_expr(expr.unwrap_ast_mut()); + vis.visit_expr(expr); vis.visit_span(eq_span); } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 5bfdc19e156..211d13659ee 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1287,7 +1287,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) - match args { AttrArgs::Empty => {} AttrArgs::Delimited(_args) => {} - AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr.unwrap_ast())), + AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr)), } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d63131eacb5..ad4410c57dd 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -176,7 +176,7 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, hir_id: hir::HirId, ident: &mut Ident, - attrs: &'hir [Attribute], + attrs: &'hir [hir::Attribute], vis_span: Span, i: &ItemKind, ) -> hir::ItemKind<'hir> { @@ -467,7 +467,7 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, vis_span: Span, ident: &mut Ident, - attrs: &'hir [Attribute], + attrs: &'hir [hir::Attribute], ) -> hir::ItemKind<'hir> { let path = &tree.prefix; let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); @@ -1392,7 +1392,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub(super) fn lower_safety(&mut self, s: Safety, default: hir::Safety) -> hir::Safety { + pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety { match s { Safety::Unsafe(_) => hir::Safety::Unsafe, Safety::Default => default, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a343913b94a..41fa4c13442 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -41,7 +41,6 @@ // tidy-alphabetical-end use rustc_ast::node_id::NodeMap; -use rustc_ast::ptr::P; use rustc_ast::{self as ast, *}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; @@ -96,7 +95,7 @@ struct LoweringContext<'a, 'hir> { /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// Attributes inside the owner being lowered. - attrs: SortedMap, + attrs: SortedMap, /// Collect items that were created by lowering the current owner. children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>, @@ -847,7 +846,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ret } - fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [Attribute] { + fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [hir::Attribute] { if attrs.is_empty() { &[] } else { @@ -859,25 +858,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_attr(&self, attr: &Attribute) -> Attribute { + fn lower_attr(&self, attr: &Attribute) -> hir::Attribute { // Note that we explicitly do not walk the path. Since we don't really // lower attributes (we use the AST version) there is nowhere to keep // the `HirId`s. We don't actually need HIR version of attributes anyway. // Tokens are also not needed after macro expansion and parsing. let kind = match attr.kind { - AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { - item: AttrItem { - unsafety: normal.item.unsafety, - path: normal.item.path.clone(), - args: self.lower_attr_args(&normal.item.args), - tokens: None, + AttrKind::Normal(ref normal) => hir::AttrKind::Normal(Box::new(hir::AttrItem { + unsafety: self.lower_safety(normal.item.unsafety, hir::Safety::Safe), + path: hir::AttrPath { + segments: normal + .item + .path + .segments + .iter() + .map(|i| i.ident) + .collect::>() + .into_boxed_slice(), + span: normal.item.path.span, }, - tokens: None, + args: self.lower_attr_args(&normal.item.args), })), - AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data), + AttrKind::DocComment(comment_kind, data) => { + hir::AttrKind::DocComment(comment_kind, data) + } }; - Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) } + hir::Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) } } fn alias_attrs(&mut self, id: HirId, target_id: HirId) { @@ -889,15 +896,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs { + fn lower_attr_args(&self, args: &AttrArgs) -> hir::AttrArgs { match args { - AttrArgs::Empty => AttrArgs::Empty, - AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)), + AttrArgs::Empty => hir::AttrArgs::Empty, + AttrArgs::Delimited(args) => hir::AttrArgs::Delimited(self.lower_delim_args(args)), // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). &AttrArgs::Eq { eq_span, ref expr } => { - let expr = expr.unwrap_ast(); // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind @@ -913,7 +919,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - AttrArgs::Eq { eq_span, expr: AttrArgsEq::Hir(lit) } + hir::AttrArgs::Eq { eq_span, expr: lit } } } } @@ -2201,7 +2207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn stmt_let_pat( &mut self, - attrs: Option<&'hir [Attribute]>, + attrs: Option<&'hir [hir::Attribute]>, span: Span, init: Option<&'hir hir::Expr<'hir>>, pat: &'hir hir::Pat<'hir>, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 290c2e52970..a42e3445c8d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -342,7 +342,7 @@ impl<'a> AstValidator<'a> { sym::forbid, sym::warn, ]; - !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(attr) + !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(*attr) }) .for_each(|attr| { if attr.is_doc_comment() { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 5025d581ab0..41fded027cb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -17,9 +17,9 @@ use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; use rustc_ast::{ - self as ast, AttrArgs, AttrArgsEq, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg, - GenericBound, InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, - InlineAsmTemplatePiece, PatKind, RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr, + self as ast, AttrArgs, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg, GenericBound, + InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, PatKind, + RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr, }; use rustc_data_structures::sync::Lrc; use rustc_span::edition::Edition; @@ -359,7 +359,7 @@ fn binop_to_string(op: BinOpToken) -> &'static str { } } -fn doc_comment_to_string( +pub fn doc_comment_to_string( comment_kind: CommentKind, attr_style: ast::AttrStyle, data: Symbol, @@ -648,20 +648,13 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr, .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => { - self.print_path(&item.path, false, 0); - self.space(); - self.word_space("="); - let token_str = self.meta_item_lit_to_string(lit); - self.word(token_str); - } } match item.unsafety { ast::Safety::Unsafe(_) => self.pclose(), diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 94f9727eb7f..d5ee03d2b68 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -3,10 +3,8 @@ use std::num::NonZero; use rustc_abi::Align; -use rustc_ast::{ - self as ast, Attribute, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId, - attr, -}; +use rustc_ast::attr::AttributeExt; +use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; use rustc_ast_pretty::pprust; use rustc_errors::ErrorGuaranteed; use rustc_feature::{Features, GatedCfg, find_gated_cfg, is_builtin_attr_name}; @@ -20,8 +18,8 @@ use rustc_span::Span; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{Symbol, kw, sym}; -use crate::fluent_generated; use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; +use crate::{filter_by_name, first_attr_value_str_by_name, fluent_generated}; /// The version placeholder that recently stabilized features contain inside the /// `since` field of the `#[stable]` attribute. @@ -29,7 +27,7 @@ use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; /// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; -pub fn is_builtin_attr(attr: &Attribute) -> bool { +pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } @@ -215,7 +213,7 @@ impl UnstableReason { /// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_stability( sess: &Session, - attrs: &[Attribute], + attrs: &[impl AttributeExt], item_sp: Span, ) -> Option<(Stability, Span)> { let mut stab: Option<(Stability, Span)> = None; @@ -226,23 +224,25 @@ pub fn find_stability( sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, sym::unstable => { if stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); break; } if let Some((feature, level)) = parse_unstability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span)); + stab = Some((Stability { level, feature }, attr.span())); } } sym::stable => { if stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); break; } if let Some((feature, level)) = parse_stability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span)); + stab = Some((Stability { level, feature }, attr.span())); } } _ => {} @@ -272,7 +272,7 @@ pub fn find_stability( /// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_const_stability( sess: &Session, - attrs: &[Attribute], + attrs: &[impl AttributeExt], item_sp: Span, ) -> Option<(ConstStability, Span)> { let mut const_stab: Option<(ConstStability, Span)> = None; @@ -285,8 +285,9 @@ pub fn find_const_stability( sym::rustc_const_stable_indirect => const_stable_indirect = true, sym::rustc_const_unstable => { if const_stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); break; } @@ -298,14 +299,15 @@ pub fn find_const_stability( const_stable_indirect: false, promotable: false, }, - attr.span, + attr.span(), )); } } sym::rustc_const_stable => { if const_stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); break; } if let Some((feature, level)) = parse_stability(sess, attr) { @@ -316,7 +318,7 @@ pub fn find_const_stability( const_stable_indirect: false, promotable: false, }, - attr.span, + attr.span(), )); } } @@ -361,7 +363,7 @@ pub fn find_const_stability( /// without the `staged_api` feature. pub fn unmarked_crate_const_stab( _sess: &Session, - attrs: &[Attribute], + attrs: &[impl AttributeExt], regular_stab: Stability, ) -> ConstStability { assert!(regular_stab.level.is_unstable()); @@ -381,7 +383,7 @@ pub fn unmarked_crate_const_stab( /// Returns `None` if no stability attributes are found. pub fn find_body_stability( sess: &Session, - attrs: &[Attribute], + attrs: &[impl AttributeExt], ) -> Option<(DefaultBodyStability, Span)> { let mut body_stab: Option<(DefaultBodyStability, Span)> = None; @@ -389,12 +391,12 @@ pub fn find_body_stability( if attr.has_name(sym::rustc_default_body_unstable) { if body_stab.is_some() { sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span }); + .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() }); break; } if let Some((feature, level)) = parse_unstability(sess, attr) { - body_stab = Some((DefaultBodyStability { level, feature }, attr.span)); + body_stab = Some((DefaultBodyStability { level, feature }, attr.span())); } } } @@ -420,9 +422,8 @@ fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) - /// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and /// its stability information. -fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { - let meta = attr.meta()?; - let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; +fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; let mut feature = None; let mut since = None; @@ -454,9 +455,9 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit let feature = match feature { Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span })) + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span })), + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), }; let since = if let Some(since) = since { @@ -465,11 +466,11 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit } else if let Some(version) = parse_version(since) { StableSince::Version(version) } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); StableSince::Err } } else { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); StableSince::Err }; @@ -484,9 +485,8 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit /// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` /// attribute, and return the feature name and its stability information. -fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { - let meta = attr.meta()?; - let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; +fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; let mut feature = None; let mut reason = None; @@ -553,13 +553,14 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil let feature = match feature { Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span })) + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span })), + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), }; - let issue = issue - .ok_or_else(|| sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span })); + let issue = issue.ok_or_else(|| { + sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() }) + }); match (feature, issue) { (Ok(feature), Ok(_)) => { @@ -575,8 +576,8 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil } } -pub fn find_crate_name(attrs: &[Attribute]) -> Option { - attr::first_attr_value_str_by_name(attrs, sym::crate_name) +pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { + first_attr_value_str_by_name(attrs, sym::crate_name) } #[derive(Clone, Debug)] @@ -884,7 +885,7 @@ impl Deprecation { pub fn find_deprecation( sess: &Session, features: &Features, - attrs: &[Attribute], + attrs: &[impl AttributeExt], ) -> Option<(Deprecation, Span)> { let mut depr: Option<(Deprecation, Span)> = None; let is_rustc = features.staged_api(); @@ -894,98 +895,97 @@ pub fn find_deprecation( continue; } - let Some(meta) = attr.meta() else { - continue; - }; let mut since = None; let mut note = None; let mut suggestion = None; - match &meta.kind { - MetaItemKind::Word => {} - MetaItemKind::NameValue(..) => note = meta.value_str(), - MetaItemKind::List(list) => { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleItem { - span: meta.span, - item: pprust::path_to_string(&meta.path), + + if attr.is_doc_comment() { + continue; + } else if attr.is_word() { + } else if let Some(value) = attr.value_str() { + note = Some(value) + } else if let Some(list) = attr.meta_item_list() { + let get = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); + return false; + } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + if let Some(lit) = meta.name_value_literal() { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), }); - return false; - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true } else { - if let Some(lit) = meta.name_value_literal() { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - } else { - sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { - span: meta.span, - }); - } - - false + sess.dcx() + .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); } - }; + false + } + }; - for meta in list { - match meta { - MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { - sym::since => { - if !get(mi, &mut since) { - continue 'outer; - } - } - sym::note => { - if !get(mi, &mut note) { - continue 'outer; - } + for meta in &list { + match meta { + MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { + sym::since => { + if !get(mi, &mut since) { + continue 'outer; } - sym::suggestion => { - if !features.deprecated_suggestion() { - sess.dcx().emit_err( - session_diagnostics::DeprecatedItemSuggestion { - span: mi.span, - is_nightly: sess.is_nightly_build(), - details: (), - }, - ); - } - - if !get(mi, &mut suggestion) { - continue 'outer; - } + } + sym::note => { + if !get(mi, &mut note) { + continue 'outer; } - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: if features.deprecated_suggestion() { - &["since", "note", "suggestion"] - } else { - &["since", "note"] + } + sym::suggestion => { + if !features.deprecated_suggestion() { + sess.dcx().emit_err( + session_diagnostics::DeprecatedItemSuggestion { + span: mi.span, + is_nightly: sess.is_nightly_build(), + details: (), }, - }); + ); + } + + if !get(mi, &mut suggestion) { continue 'outer; } - }, - MetaItemInner::Lit(lit) => { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedKvPair, - is_bytestr: false, - start_point_span: sess.source_map().start_point(lit.span), + } + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: if features.deprecated_suggestion() { + &["since", "note", "suggestion"] + } else { + &["since", "note"] + }, }); continue 'outer; } + }, + MetaItemInner::Lit(lit) => { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedKvPair, + is_bytestr: false, + start_point_span: sess.source_map().start_point(lit.span), + }); + continue 'outer; } } } + } else { + continue; } let since = if let Some(since) = since { @@ -996,22 +996,22 @@ pub fn find_deprecation( } else if let Some(version) = parse_version(since) { DeprecatedSince::RustcVersion(version) } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); DeprecatedSince::Err } } else if is_rustc { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); DeprecatedSince::Err } else { DeprecatedSince::Unspecified }; if is_rustc && note.is_none() { - sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span }); + sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() }); continue; } - depr = Some((Deprecation { since, note, suggestion }, attr.span)); + depr = Some((Deprecation { since, note, suggestion }, attr.span())); } depr @@ -1054,11 +1054,11 @@ impl IntType { /// the same discriminant size that the corresponding C enum would or C /// structure layout, `packed` to remove padding, and `transparent` to delegate representation /// concerns to the only non-ZST field. -pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec { +pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec { if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() } } -pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { +pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec { assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); use ReprAttr::*; let mut acc = Vec::new(); @@ -1238,7 +1238,7 @@ pub enum TransparencyError { } pub fn find_transparency( - attrs: &[Attribute], + attrs: &[impl AttributeExt], macro_rules: bool, ) -> (Transparency, Option) { let mut transparency = None; @@ -1246,7 +1246,7 @@ pub fn find_transparency( for attr in attrs { if attr.has_name(sym::rustc_macro_transparency) { if let Some((_, old_span)) = transparency { - error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span)); + error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span())); break; } else if let Some(value) = attr.value_str() { transparency = Some(( @@ -1255,11 +1255,12 @@ pub fn find_transparency( sym::semitransparent => Transparency::SemiTransparent, sym::opaque => Transparency::Opaque, _ => { - error = Some(TransparencyError::UnknownTransparency(value, attr.span)); + error = + Some(TransparencyError::UnknownTransparency(value, attr.span())); continue; } }, - attr.span, + attr.span(), )); } } @@ -1270,29 +1271,29 @@ pub fn find_transparency( pub fn allow_internal_unstable<'a>( sess: &'a Session, - attrs: &'a [Attribute], + attrs: &'a [impl AttributeExt], ) -> impl Iterator + 'a { allow_unstable(sess, attrs, sym::allow_internal_unstable) } pub fn rustc_allow_const_fn_unstable<'a>( sess: &'a Session, - attrs: &'a [Attribute], + attrs: &'a [impl AttributeExt], ) -> impl Iterator + 'a { allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) } fn allow_unstable<'a>( sess: &'a Session, - attrs: &'a [Attribute], + attrs: &'a [impl AttributeExt], symbol: Symbol, ) -> impl Iterator + 'a { - let attrs = attr::filter_by_name(attrs, symbol); + let attrs = filter_by_name(attrs, symbol); let list = attrs .filter_map(move |attr| { attr.meta_item_list().or_else(|| { sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList { - span: attr.span, + span: attr.span(), name: symbol.to_ident_string(), }); None @@ -1332,9 +1333,8 @@ pub fn parse_alignment(node: &ast::LitKind) -> Result { } /// Read the content of a `rustc_confusables` attribute, and return the list of candidate names. -pub fn parse_confusables(attr: &Attribute) -> Option> { - let meta = attr.meta()?; - let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; +pub fn parse_confusables(attr: &impl AttributeExt) -> Option> { + let metas = attr.meta_item_list()?; let mut candidates = Vec::new(); diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 450a95ae20c..f5c155667ba 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -23,6 +23,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 11bcd727501..d1b1ff88b4a 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -26,9 +26,9 @@ use std::borrow::Cow; use std::fmt; -use rustc_ast as ast; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{DiagArgValue, IntoDiagArg}; +use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; @@ -77,7 +77,7 @@ struct AssertModuleSource<'tcx> { } impl<'tcx> AssertModuleSource<'tcx> { - fn check_attr(&mut self, attr: &ast::Attribute) { + fn check_attr(&mut self, attr: &hir::Attribute) { let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) { (CguReuse::PreLto, ComparisonKind::AtLeast) } else if attr.has_name(sym::rustc_partition_codegened) { @@ -158,7 +158,7 @@ impl<'tcx> AssertModuleSource<'tcx> { ); } - fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol { + fn field(&self, attr: &hir::Attribute, name: Symbol) -> Symbol { for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(name) { if let Some(value) = item.value_str() { @@ -177,7 +177,7 @@ impl<'tcx> AssertModuleSource<'tcx> { /// Scan for a `cfg="foo"` attribute and check whether we have a /// cfg flag called `foo`. - fn check_config(&self, attr: &ast::Attribute) -> bool { + fn check_config(&self, attr: &hir::Attribute) -> bool { let config = &self.tcx.sess.psess.config; let value = self.field(attr, sym::cfg); debug!("check_config(config={:?}, value={:?})", config, value); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 12c5065cd71..5edd18bd3f4 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItemInner, MetaItemKind, ast, attr}; +use rustc_ast::{MetaItemInner, attr}; use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; @@ -6,7 +6,7 @@ use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; -use rustc_hir::{HirId, LangItem, lang_items}; +use rustc_hir::{self as hir, HirId, LangItem, lang_items}; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, }; @@ -525,28 +525,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if !attr.has_name(sym::inline) { return ia; } - match attr.meta_kind() { - Some(MetaItemKind::Word) => InlineAttr::Hint, - Some(MetaItemKind::List(ref items)) => { - inline_span = Some(attr.span); - if items.len() != 1 { - struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument") - .emit(); - InlineAttr::None - } else if list_contains_name(items, sym::always) { - InlineAttr::Always - } else if list_contains_name(items, sym::never) { - InlineAttr::Never - } else { - struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .with_help("valid inline arguments are `always` and `never`") - .emit(); + if attr.is_word() { + InlineAttr::Hint + } else if let Some(ref items) = attr.meta_item_list() { + inline_span = Some(attr.span); + if items.len() != 1 { + struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); + InlineAttr::None + } else if list_contains_name(items, sym::always) { + InlineAttr::Always + } else if list_contains_name(items, sym::never) { + InlineAttr::Never + } else { + struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") + .with_help("valid inline arguments are `always` and `never`") + .emit(); - InlineAttr::None - } + InlineAttr::None } - Some(MetaItemKind::NameValue(_)) => ia, - None => ia, + } else { + ia } }); @@ -562,27 +560,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { return ia; } let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); - match attr.meta_kind() { - Some(MetaItemKind::Word) => { + if attr.is_word() { + err(attr.span, "expected one argument"); + ia + } else if let Some(ref items) = attr.meta_item_list() { + inline_span = Some(attr.span); + if items.len() != 1 { err(attr.span, "expected one argument"); - ia - } - Some(MetaItemKind::List(ref items)) => { - inline_span = Some(attr.span); - if items.len() != 1 { - err(attr.span, "expected one argument"); - OptimizeAttr::None - } else if list_contains_name(items, sym::size) { - OptimizeAttr::Size - } else if list_contains_name(items, sym::speed) { - OptimizeAttr::Speed - } else { - err(items[0].span(), "invalid argument"); - OptimizeAttr::None - } + OptimizeAttr::None + } else if list_contains_name(items, sym::size) { + OptimizeAttr::Size + } else if list_contains_name(items, sym::speed) { + OptimizeAttr::Speed + } else { + err(items[0].span(), "invalid argument"); + OptimizeAttr::None } - Some(MetaItemKind::NameValue(_)) => ia, - None => ia, + } else { + OptimizeAttr::None } }); @@ -730,7 +725,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { false } -fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option { +fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option { use rustc_ast::{LitIntType, LitKind, MetaItemLit}; let meta_item_list = attr.meta_item_list(); let meta_item_list = meta_item_list.as_deref(); @@ -795,7 +790,7 @@ struct MixedExportNameAndNoMangleState<'a> { export_name: Option, hir_id: Option, no_mangle: Option, - no_mangle_attr: Option<&'a ast::Attribute>, + no_mangle_attr: Option<&'a hir::Attribute>, } impl<'a> MixedExportNameAndNoMangleState<'a> { @@ -803,7 +798,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> { self.export_name = Some(span); } - fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a ast::Attribute) { + fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) { self.no_mangle = Some(span); self.hir_id = Some(hir_id); self.no_mangle_attr = Some(attr_name); @@ -824,7 +819,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> { no_mangle, errors::MixedExportNameAndNoMangle { no_mangle, - no_mangle_attr: rustc_ast_pretty::pprust::attribute_to_string(no_mangle_attr), + no_mangle_attr: rustc_hir_pretty::attribute_to_string(&tcx, no_mangle_attr), export_name, removal_span: no_mangle, }, diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index fa600ec7166..cce1b4e9ed8 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -1,8 +1,8 @@ -use rustc_ast::ast; use rustc_attr::InstructionSetAttr; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::Applicability; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_middle::middle::codegen_fn_attrs::TargetFeature; @@ -19,7 +19,7 @@ use crate::errors; /// Enabled target features are added to `target_features`. pub(crate) fn from_target_feature_attr( tcx: TyCtxt<'_>, - attr: &ast::Attribute, + attr: &hir::Attribute, rust_target_features: &UnordMap, target_features: &mut Vec, ) { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index bed500c3032..8e42afb60d8 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -4,7 +4,7 @@ use std::path::Component::Prefix; use std::path::{Path, PathBuf}; use std::rc::Rc; -use rustc_ast::attr::MarkedAttrs; +use rustc_ast::attr::{AttributeExt, MarkedAttrs}; use rustc_ast::ptr::P; use rustc_ast::token::Nonterminal; use rustc_ast::tokenstream::TokenStream; @@ -782,10 +782,12 @@ impl SyntaxExtension { } } - fn collapse_debuginfo_by_name(attr: &Attribute) -> Result { + fn collapse_debuginfo_by_name( + attr: &impl AttributeExt, + ) -> Result { let list = attr.meta_item_list(); let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else { - return Err(attr.span); + return Err(attr.span()); }; if !item.is_word() { return Err(item.span); @@ -805,7 +807,7 @@ impl SyntaxExtension { /// | (unspecified) | no | if-ext | if-ext | yes | /// | external | no | if-ext | if-ext | yes | /// | yes | yes | yes | yes | yes | - fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], ext: bool) -> bool { + fn get_collapse_debuginfo(sess: &Session, attrs: &[impl AttributeExt], ext: bool) -> bool { let flag = sess.opts.cg.collapse_macro_debuginfo; let attr = attr::find_by_name(attrs, sym::collapse_debuginfo) .and_then(|attr| { @@ -842,11 +844,11 @@ impl SyntaxExtension { helper_attrs: Vec, edition: Edition, name: Symbol, - attrs: &[ast::Attribute], + attrs: &[impl AttributeExt], is_local: bool, ) -> SyntaxExtension { let allow_internal_unstable = - attr::allow_internal_unstable(sess, attrs).collect::>(); + rustc_attr::allow_internal_unstable(sess, attrs).collect::>(); let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe); let local_inner_macros = attr::find_by_name(attrs, sym::macro_export) @@ -1305,7 +1307,7 @@ pub fn resolve_path(sess: &Session, path: impl Into, span: Span) -> PRe pub fn parse_macro_name_and_helper_attrs( dcx: DiagCtxtHandle<'_>, - attr: &Attribute, + attr: &impl AttributeExt, macro_type: &str, ) -> Option<(Symbol, Vec)> { // Once we've located the `#[proc_macro_derive]` attribute, verify @@ -1313,7 +1315,7 @@ pub fn parse_macro_name_and_helper_attrs( // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = attr.meta_item_list()?; let ([trait_attr] | [trait_attr, _]) = list.as_slice() else { - dcx.emit_err(errors::AttrNoArguments { span: attr.span }); + dcx.emit_err(errors::AttrNoArguments { span: attr.span() }); return None; }; let Some(trait_attr) = trait_attr.meta_item() else { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index a373c753cc1..f7e3403cd28 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -9,7 +9,7 @@ use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId}; use rustc_ast_pretty::pprust; -use rustc_attr::{self as attr, TransparencyError}; +use rustc_attr::{self as attr, AttributeExt, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_feature::Features; @@ -371,7 +371,7 @@ pub fn compile_declarative_macro( features: &Features, macro_def: &ast::MacroDef, ident: Ident, - attrs: &[ast::Attribute], + attrs: &[impl AttributeExt], span: Span, node_id: NodeId, edition: Edition, diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 85c6da83379..5bfc4756ec6 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -16,5 +16,6 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index f1f624269ae..88c0d223fd3 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -6,7 +6,7 @@ macro_rules! arena_types { $macro!([ // HIR types [] asm_template: rustc_ast::InlineAsmTemplatePiece, - [] attribute: rustc_ast::Attribute, + [] attribute: rustc_hir::Attribute, [] owner_info: rustc_hir::OwnerInfo<'tcx>, [] use_path: rustc_hir::UsePath<'tcx>, [] lit: rustc_hir::Lit, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 957d1b48a27..56dba0c61e2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,10 +1,13 @@ use std::fmt; use rustc_abi::ExternAbi; +// ignore-tidy-filelength +use rustc_ast::attr::AttributeExt; +use rustc_ast::token::CommentKind; use rustc_ast::util::parser::{AssocOp, ExprPrecedence}; use rustc_ast::{ - self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, - LitKind, TraitObjectSyntax, UintTy, + self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, + IntTy, Label, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy, }; pub use rustc_ast::{ BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy, @@ -21,6 +24,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Span}; use rustc_target::asm::InlineAsmRegOrRegClass; use smallvec::SmallVec; +use thin_vec::ThinVec; use tracing::debug; use crate::LangItem; @@ -937,6 +941,250 @@ pub struct ParentedNode<'tcx> { pub node: Node<'tcx>, } +/// Arguments passed to an attribute macro. +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)] +pub enum AttrArgs { + /// No arguments: `#[attr]`. + Empty, + /// Delimited arguments: `#[attr()/[]/{}]`. + Delimited(DelimArgs), + /// Arguments of a key-value attribute: `#[attr = "value"]`. + Eq { + /// Span of the `=` token. + eq_span: Span, + /// The "value". + expr: MetaItemLit, + }, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub enum AttrKind { + /// A normal attribute. + Normal(Box), + + /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`). + /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal` + /// variant (which is much less compact and thus more expensive). + DocComment(CommentKind, Symbol), +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)] +pub struct AttrPath { + pub segments: Box<[Ident]>, + pub span: Span, +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)] +pub struct AttrItem { + pub unsafety: Safety, + // Not lowered to hir::Path because we have no NodeId to resolve to. + pub path: AttrPath, + pub args: AttrArgs, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub struct Attribute { + pub kind: AttrKind, + pub id: AttrId, + /// Denotes if the attribute decorates the following construct (outer) + /// or the construct this attribute is contained within (inner). + pub style: AttrStyle, + pub span: Span, +} + +impl Attribute { + pub fn get_normal_item(&self) -> &AttrItem { + match &self.kind { + AttrKind::Normal(normal) => &normal, + AttrKind::DocComment(..) => panic!("unexpected doc comment"), + } + } + + pub fn unwrap_normal_item(self) -> AttrItem { + match self.kind { + AttrKind::Normal(normal) => *normal, + AttrKind::DocComment(..) => panic!("unexpected doc comment"), + } + } + + pub fn value_lit(&self) -> Option<&MetaItemLit> { + match &self.kind { + AttrKind::Normal(n) => match n.as_ref() { + AttrItem { args: AttrArgs::Eq { expr, .. }, .. } => Some(expr), + _ => None, + }, + _ => None, + } + } +} + +impl AttributeExt for Attribute { + fn id(&self) -> AttrId { + self.id + } + + fn meta_item_list(&self) -> Option> { + match &self.kind { + AttrKind::Normal(n) => match n.as_ref() { + AttrItem { args: AttrArgs::Delimited(d), .. } => { + ast::MetaItemKind::list_from_tokens(d.tokens.clone()) + } + _ => None, + }, + _ => None, + } + } + + fn value_str(&self) -> Option { + self.value_lit().and_then(|x| x.value_str()) + } + + fn value_span(&self) -> Option { + self.value_lit().map(|i| i.span) + } + + /// For a single-segment attribute, returns its name; otherwise, returns `None`. + fn ident(&self) -> Option { + match &self.kind { + AttrKind::Normal(n) => { + if let [ident] = n.path.segments.as_ref() { + Some(*ident) + } else { + None + } + } + AttrKind::DocComment(..) => None, + } + } + + fn path_matches(&self, name: &[Symbol]) -> bool { + match &self.kind { + AttrKind::Normal(n) => { + n.path.segments.len() == name.len() + && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n) + } + AttrKind::DocComment(..) => false, + } + } + + fn is_doc_comment(&self) -> bool { + matches!(self.kind, AttrKind::DocComment(..)) + } + + fn span(&self) -> Span { + self.span + } + + fn is_word(&self) -> bool { + match &self.kind { + AttrKind::Normal(n) => { + matches!(n.args, AttrArgs::Empty) + } + AttrKind::DocComment(..) => false, + } + } + + fn ident_path(&self) -> Option> { + match &self.kind { + AttrKind::Normal(n) => Some(n.path.segments.iter().copied().collect()), + AttrKind::DocComment(..) => None, + } + } + + fn doc_str(&self) -> Option { + match &self.kind { + AttrKind::DocComment(.., data) => Some(*data), + AttrKind::Normal(_) if self.has_name(sym::doc) => self.value_str(), + _ => None, + } + } + fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + match &self.kind { + AttrKind::DocComment(kind, data) => Some((*data, *kind)), + AttrKind::Normal(_) if self.name_or_empty() == sym::doc => { + self.value_str().map(|s| (s, CommentKind::Line)) + } + _ => None, + } + } + + fn style(&self) -> AttrStyle { + self.style + } +} + +// FIXME(fn_delegation): use function delegation instead of manually forwarding +impl Attribute { + pub fn id(&self) -> AttrId { + AttributeExt::id(self) + } + + pub fn name_or_empty(&self) -> Symbol { + AttributeExt::name_or_empty(self) + } + + pub fn meta_item_list(&self) -> Option> { + AttributeExt::meta_item_list(self) + } + + pub fn value_str(&self) -> Option { + AttributeExt::value_str(self) + } + + pub fn value_span(&self) -> Option { + AttributeExt::value_span(self) + } + + pub fn ident(&self) -> Option { + AttributeExt::ident(self) + } + + pub fn path_matches(&self, name: &[Symbol]) -> bool { + AttributeExt::path_matches(self, name) + } + + pub fn is_doc_comment(&self) -> bool { + AttributeExt::is_doc_comment(self) + } + + #[inline] + pub fn has_name(&self, name: Symbol) -> bool { + AttributeExt::has_name(self, name) + } + + pub fn span(&self) -> Span { + AttributeExt::span(self) + } + + pub fn is_word(&self) -> bool { + AttributeExt::is_word(self) + } + + pub fn path(&self) -> SmallVec<[Symbol; 1]> { + AttributeExt::path(self) + } + + pub fn ident_path(&self) -> Option> { + AttributeExt::ident_path(self) + } + + pub fn doc_str(&self) -> Option { + AttributeExt::doc_str(self) + } + + pub fn is_proc_macro_attr(&self) -> bool { + AttributeExt::is_proc_macro_attr(self) + } + + pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + AttributeExt::doc_str_and_comment_kind(self) + } + + pub fn style(&self) -> AttrStyle { + AttributeExt::style(self) + } +} + /// Attributes owned by a HIR owner. #[derive(Debug)] pub struct AttributeMap<'tcx> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 6d481f7536a..5ed5a43d522 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -64,8 +64,8 @@ //! This order consistency is required in a few places in rustc, for //! example coroutine inference, and possibly also HIR borrowck. +use rustc_ast::Label; use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list}; -use rustc_ast::{Attribute, Label}; use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{Ident, Symbol}; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 15cb331d07a..3684695774e 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -7,7 +7,7 @@ //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`. //! * Functions called by the compiler itself. -use rustc_ast as ast; +use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; @@ -153,11 +153,11 @@ impl HashStable for LangItem { /// Extracts the first `lang = "$name"` out of a list of attributes. /// The `#[panic_handler]` attribute is also extracted out when found. -pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> { +pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> { attrs.iter().find_map(|attr| { Some(match attr { - _ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span), - _ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span), + _ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span()), + _ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span()), _ => return None, }) }) diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index fe169e989ec..db0d0fcf3b9 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -2,7 +2,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHas use rustc_span::def_id::DefPathHash; use crate::hir::{ - AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, + Attribute, AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, + TraitItemId, }; use crate::hir_id::{HirId, ItemLocalId}; @@ -12,6 +13,7 @@ use crate::hir_id::{HirId, ItemLocalId}; pub trait HashStableContext: rustc_ast::HashStableContext + rustc_target::HashStableContext { + fn hash_attr(&mut self, _: &Attribute, hasher: &mut StableHasher); } impl ToStableHashKey for HirId { @@ -113,3 +115,9 @@ impl HashStable for Crate<'_> { opt_hir_hash.unwrap().hash_stable(hcx, hasher) } } + +impl HashStable for Attribute { + fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { + hcx.hash_attr(self, hasher) + } +} diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 8dd8a5c98ef..5430c273d89 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -11,16 +11,18 @@ use std::vec; use rustc_abi::ExternAbi; use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity}; +use rustc_ast::{DUMMY_NODE_ID, DelimArgs}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; +use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir::{ BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, }; -use rustc_span::FileName; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; +use rustc_span::{FileName, Span}; use {rustc_ast as ast, rustc_hir as hir}; pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String { @@ -68,15 +70,109 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { pub struct State<'a> { pub s: pp::Printer, comments: Option>, - attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute], ann: &'a (dyn PpAnn + 'a), } impl<'a> State<'a> { - fn attrs(&self, id: HirId) -> &'a [ast::Attribute] { + fn attrs(&self, id: HirId) -> &'a [hir::Attribute] { (self.attrs)(id) } + fn print_inner_attributes(&mut self, attrs: &[hir::Attribute]) -> bool { + self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true) + } + + fn print_outer_attributes(&mut self, attrs: &[hir::Attribute]) -> bool { + self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true) + } + + fn print_either_attributes( + &mut self, + attrs: &[hir::Attribute], + kind: ast::AttrStyle, + is_inline: bool, + trailing_hardbreak: bool, + ) -> bool { + let mut printed = false; + for attr in attrs { + if attr.style == kind { + self.print_attribute_inline(attr, is_inline); + if is_inline { + self.nbsp(); + } + printed = true; + } + } + if printed && trailing_hardbreak && !is_inline { + self.hardbreak_if_not_bol(); + } + printed + } + + fn print_attribute_inline(&mut self, attr: &hir::Attribute, is_inline: bool) { + if !is_inline { + self.hardbreak_if_not_bol(); + } + self.maybe_print_comment(attr.span.lo()); + match &attr.kind { + hir::AttrKind::Normal(normal) => { + match attr.style { + ast::AttrStyle::Inner => self.word("#!["), + ast::AttrStyle::Outer => self.word("#["), + } + self.print_attr_item(&normal, attr.span); + self.word("]"); + } + hir::AttrKind::DocComment(comment_kind, data) => { + self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string( + *comment_kind, + attr.style, + *data, + )); + self.hardbreak() + } + } + } + + fn print_attr_item(&mut self, item: &hir::AttrItem, span: Span) { + self.ibox(0); + let path = ast::Path { + span, + segments: item + .path + .segments + .iter() + .map(|i| ast::PathSegment { ident: *i, args: None, id: DUMMY_NODE_ID }) + .collect(), + tokens: None, + }; + + match &item.args { + hir::AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self + .print_mac_common( + Some(MacHeader::Path(&path)), + false, + None, + *delim, + tokens, + true, + span, + ), + hir::AttrArgs::Empty => { + PrintState::print_path(self, &path, false, 0); + } + hir::AttrArgs::Eq { eq_span: _, expr } => { + PrintState::print_path(self, &path, false, 0); + self.space(); + self.word_space("="); + let token_str = self.meta_item_lit_to_string(expr); + self.word(token_str); + } + } + self.end(); + } + fn print_node(&mut self, node: Node<'_>) { match node { Node::Param(a) => self.print_param(a), @@ -164,7 +260,7 @@ pub fn print_crate<'a>( krate: &hir::Mod<'_>, filename: FileName, input: String, - attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute], ann: &'a dyn PpAnn, ) -> String { let mut s = State { @@ -191,6 +287,10 @@ where printer.s.eof() } +pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String { + to_string(ann, |s| s.print_attribute_inline(attr, false)) +} + pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String { to_string(ann, |s| s.print_type(ty)) } @@ -242,7 +342,7 @@ impl<'a> State<'a> { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span); } - fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) { + fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[hir::Attribute]) { self.print_inner_attributes(attrs); for &item_id in _mod.item_ids { self.ann.nested(self, Nested::Item(item_id)); @@ -926,14 +1026,14 @@ impl<'a> State<'a> { self.print_block_maybe_unclosed(blk, &[], false) } - fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[ast::Attribute]) { + fn print_block_with_attrs(&mut self, blk: &hir::Block<'_>, attrs: &[hir::Attribute]) { self.print_block_maybe_unclosed(blk, attrs, true) } fn print_block_maybe_unclosed( &mut self, blk: &hir::Block<'_>, - attrs: &[ast::Attribute], + attrs: &[hir::Attribute], close_box: bool, ) { match blk.rules { diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 1f46155abc8..031c50c45d4 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -50,7 +50,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_span::symbol::{Symbol, sym}; use tracing::debug; -use {rustc_ast as ast, rustc_graphviz as dot, rustc_hir as hir}; +use {rustc_graphviz as dot, rustc_hir as hir}; use crate::errors; @@ -106,7 +106,7 @@ struct IfThisChanged<'tcx> { } impl<'tcx> IfThisChanged<'tcx> { - fn argument(&self, attr: &ast::Attribute) -> Option { + fn argument(&self, attr: &hir::Attribute) -> Option { let mut value = None; for list_item in attr.meta_item_list().unwrap_or_default() { match list_item.ident() { diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 2075d4214c1..a85686e590b 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -19,11 +19,13 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. -use rustc_ast::{self as ast, Attribute, MetaItemInner}; +use rustc_ast::{self as ast, MetaItemInner}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit}; +use rustc_hir::{ + Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit, +}; use rustc_middle::dep_graph::{DepNode, DepNodeExt, label_strs}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3543784bc72..2d3ecb6943c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -387,7 +387,7 @@ pub struct MissingDoc; impl_lint_pass!(MissingDoc => [MISSING_DOCS]); -fn has_doc(attr: &ast::Attribute) -> bool { +fn has_doc(attr: &hir::Attribute) -> bool { if attr.is_doc_comment() { return true; } @@ -1012,7 +1012,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { let attrs = cx.tcx.hir().attrs(it.hir_id()); - let check_no_mangle_on_generic_fn = |no_mangle_attr: &ast::Attribute, + let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute, impl_generics: Option<&hir::Generics<'_>>, generics: &hir::Generics<'_>, span| { @@ -1176,7 +1176,7 @@ declare_lint_pass!( ); impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) { if attr.has_name(sym::feature) && let Some(items) = attr.meta_item_list() { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 4b1dafbdbee..7ea6c63dbe6 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,4 +1,5 @@ use rustc_ast_pretty::pprust; +use rustc_attr::AttributeExt; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::{Features, GateIssue}; @@ -371,7 +372,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> { /// FIXME(blyxyas): In a future revision, we should also graph #![allow]s, /// but that is handled with more care - fn visit_attribute(&mut self, attribute: &'tcx ast::Attribute) { + fn visit_attribute(&mut self, attribute: &'tcx hir::Attribute) { if matches!( Level::from_attr(attribute), Some( @@ -383,10 +384,9 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> { ) ) { let store = unerased_lint_store(self.tcx.sess); - let Some(meta) = attribute.meta() else { return }; // Lint attributes are always a metalist inside a // metalist (even with just one lint). - let Some(meta_item_list) = meta.meta_item_list() else { return }; + let Some(meta_item_list) = attribute.meta_item_list() else { return }; for meta_list in meta_item_list { // Convert Path to String @@ -686,7 +686,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { }; } - fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option) { + fn add( + &mut self, + attrs: &[impl AttributeExt], + is_crate_node: bool, + source_hir_id: Option, + ) { let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { if attr.has_name(sym::automatically_derived) { @@ -910,7 +915,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let src = LintLevelSource::Node { name, span: sp, reason }; for &id in ids { - if self.check_gated_lint(id, attr.span, false) { + if self.check_gated_lint(id, attr.span(), false) { self.insert_spec(id, (level, src)); } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 4d8ebf2909e..ff464b76c0d 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -1,7 +1,7 @@ use rustc_abi::ExternAbi; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::FnKind; -use rustc_hir::{GenericParamKind, PatKind}; +use rustc_hir::{AttrArgs, AttrItem, AttrKind, GenericParamKind, PatKind}; use rustc_middle::ty; use rustc_session::config::CrateType; use rustc_session::{declare_lint, declare_lint_pass}; @@ -342,36 +342,37 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) - .and_then(|attr| attr.meta()) - .and_then(|meta| { - meta.name_value_literal().and_then(|lit| { - if let ast::LitKind::Str(name, ..) = lit.kind { - // Discard the double quotes surrounding the literal. - let sp = cx - .sess() - .source_map() - .span_to_snippet(lit.span) - .ok() - .and_then(|snippet| { - let left = snippet.find('"')?; - let right = - snippet.rfind('"').map(|pos| snippet.len() - pos)?; - - Some( - lit.span - .with_lo(lit.span.lo() + BytePos(left as u32 + 1)) - .with_hi(lit.span.hi() - BytePos(right as u32)), - ) - }) - .unwrap_or(lit.span); - - Some(Ident::new(name, sp)) - } else { - None - } - }) - }) + attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then( + |attr| { + if let AttrKind::Normal(n) = &attr.kind + && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: ref lit }, .. } = + n.as_ref() + && let ast::LitKind::Str(name, ..) = lit.kind + { + // Discard the double quotes surrounding the literal. + let sp = cx + .sess() + .source_map() + .span_to_snippet(lit.span) + .ok() + .and_then(|snippet| { + let left = snippet.find('"')?; + let right = snippet.rfind('"').map(|pos| snippet.len() - pos)?; + + Some( + lit.span + .with_lo(lit.span.lo() + BytePos(left as u32 + 1)) + .with_hi(lit.span.hi() - BytePos(right as u32)), + ) + }) + .unwrap_or(lit.span); + + Some(Ident::new(name, sp)) + } else { + None + } + }, + ) }; if let Some(ident) = &crate_ident { diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 9d84d36e779..380cbe650f0 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -42,9 +42,9 @@ macro_rules! late_lint_methods { fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>); fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>); fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId); - fn check_attribute(a: &'tcx rustc_ast::Attribute); - fn check_attributes(a: &'tcx [rustc_ast::Attribute]); - fn check_attributes_post(a: &'tcx [rustc_ast::Attribute]); + fn check_attribute(a: &'tcx rustc_hir::Attribute); + fn check_attributes(a: &'tcx [rustc_hir::Attribute]); + fn check_attributes_post(a: &'tcx [rustc_hir::Attribute]); ]); ) } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index eb761bd6475..7edb1d2ffe8 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -3,8 +3,9 @@ // tidy-alphabetical-end use rustc_abi::ExternAbi; +use rustc_ast::AttrId; +use rustc_ast::attr::AttributeExt; use rustc_ast::node_id::NodeId; -use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{ HashStable, StableCompare, StableHasher, ToStableHashKey, @@ -221,8 +222,8 @@ impl Level { } /// Converts an `Attribute` to a level. - pub fn from_attr(attr: &Attribute) -> Option { - Self::from_symbol(attr.name_or_empty(), Some(attr.id)) + pub fn from_attr(attr: &impl AttributeExt) -> Option { + Self::from_symbol(attr.name_or_empty(), Some(attr.id())) } /// Converts a `Symbol` to a level. diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 29dba2bca61..fd1535094c9 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -17,6 +17,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard}; use rustc_errors::DiagCtxtHandle; use rustc_expand::base::SyntaxExtension; use rustc_fs_util::try_canonicalize; +use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId}; use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; @@ -97,7 +98,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub enum LoadedMacro { - MacroDef { def: MacroDef, ident: Ident, attrs: AttrVec, span: Span, edition: Edition }, + MacroDef { + def: MacroDef, + ident: Ident, + attrs: Vec, + span: Span, + edition: Edition, + }, ProcMacro(SyntaxExtension), } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b9586338655..6eae4f9a8d6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1369,7 +1369,7 @@ impl<'a> CrateMetadataRef<'a> { self, id: DefIndex, sess: &'a Session, - ) -> impl Iterator + 'a { + ) -> impl Iterator + 'a { self.root .tables .attributes diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f01ad31d0bb..3077312ccf9 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -344,7 +344,7 @@ provide! { tcx, def_id, other, cdata, } associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } - item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } + attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } is_mir_available => { cdata.is_item_mir_available(def_id.index) } is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } cross_crate_inlinable => { table_direct } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index df5b06c6d16..92c0e8c3a50 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -4,7 +4,7 @@ use std::fs::File; use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; -use rustc_ast::Attribute; +use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::sync::{Lrc, join, par_for_each_in}; @@ -814,7 +814,7 @@ struct AnalyzeAttrState<'a> { /// visibility: this is a piece of data that can be computed once per defid, and not once per /// attribute. Some attributes would only be usable downstream if they are public. #[inline] -fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState<'_>) -> bool { +fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool { let mut should_encode = false; if !rustc_feature::encode_cross_crate(attr.name_or_empty()) { // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. @@ -1354,7 +1354,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .hir() .attrs(tcx.local_def_id_to_hir_id(def_id)) .iter() - .filter(|attr| analyze_attr(attr, &mut state)); + .filter(|attr| analyze_attr(*attr, &mut state)); record_array!(self.tables.attributes[def_id.to_def_id()] <- attr_iter); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4961464833a..fa843a10adf 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -403,7 +403,7 @@ define_tables! { cross_crate_inlinable: Table, - optional: - attributes: Table>, + attributes: Table>, // For non-reexported names in a module every name is associated with a separate `DefId`, // so we can take their names, visibilities etc from other encoded tables. module_children_non_reexports: Table>, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index b664230d10b..52233d407f2 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -85,7 +85,7 @@ macro_rules! arena_types { [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>, - [decode] attribute: rustc_ast::Attribute, + [decode] attribute: rustc_hir::Attribute, [] name_set: rustc_data_structures::unord::UnordSet, [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, [] pats: rustc_middle::ty::PatternKind<'tcx>, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0c701c834f2..fc3cbfd7b3e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -9,11 +9,11 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit::Visitor; use rustc_hir::*; +use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{ErrorGuaranteed, Span}; -use {rustc_ast as ast, rustc_hir_pretty as pprust_hir}; use crate::hir::ModuleItems; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; @@ -381,7 +381,7 @@ impl<'hir> Map<'hir> { /// Gets the attributes on the crate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. - pub fn krate_attrs(self) -> &'hir [ast::Attribute] { + pub fn krate_attrs(self) -> &'hir [Attribute] { self.attrs(CRATE_HIR_ID) } @@ -792,7 +792,7 @@ impl<'hir> Map<'hir> { /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. - pub fn attrs(self, id: HirId) -> &'hir [ast::Attribute] { + pub fn attrs(self, id: HirId) -> &'hir [Attribute] { self.tcx.hir_attrs(id.owner).get(id.local_id) } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ad0d70152e1..ffefd81cd08 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> { self, node: OwnerNode<'_>, bodies: &SortedMap>, - attrs: &SortedMap, + attrs: &SortedMap, ) -> (Option, Option) { if self.needs_crate_hash() { self.with_stable_hashing_context(|mut hcx| { diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 270bcabcc86..3a3e84a87af 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -10,7 +10,7 @@ use std::num::IntErrorKind; -use rustc_ast::Attribute; +use rustc_ast::attr::AttributeExt; use rustc_session::{Limit, Limits, Session}; use rustc_span::symbol::{Symbol, sym}; @@ -35,32 +35,36 @@ pub fn provide(providers: &mut Providers) { } } -pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit { +pub fn get_recursion_limit(krate_attrs: &[impl AttributeExt], sess: &Session) -> Limit { get_limit(krate_attrs, sess, sym::recursion_limit, 128) } -fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: usize) -> Limit { +fn get_limit( + krate_attrs: &[impl AttributeExt], + sess: &Session, + name: Symbol, + default: usize, +) -> Limit { match get_limit_size(krate_attrs, sess, name) { Some(size) => Limit::new(size), None => Limit::new(default), } } -pub fn get_limit_size(krate_attrs: &[Attribute], sess: &Session, name: Symbol) -> Option { +pub fn get_limit_size( + krate_attrs: &[impl AttributeExt], + sess: &Session, + name: Symbol, +) -> Option { for attr in krate_attrs { if !attr.has_name(name) { continue; } - if let Some(s) = attr.value_str() { - match s.as_str().parse() { + if let Some(sym) = attr.value_str() { + match sym.as_str().parse() { Ok(n) => return Some(n), Err(e) => { - let value_span = attr - .meta() - .and_then(|meta| meta.name_value_literal_span()) - .unwrap_or(attr.span); - let error_str = match e.kind() { IntErrorKind::PosOverflow => "`limit` is too large", IntErrorKind::Empty => "`limit` must be a non-negative integer", @@ -71,7 +75,11 @@ pub fn get_limit_size(krate_attrs: &[Attribute], sess: &Session, name: Symbol) - IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; - sess.dcx().emit_err(LimitInvalid { span: attr.span, value_span, error_str }); + sess.dcx().emit_err(LimitInvalid { + span: attr.span(), + value_span: attr.value_span().unwrap(), + error_str, + }); } } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cc4e31294bd..906a47713f4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1267,7 +1267,7 @@ rustc_queries! { /// Returns the attributes on the item at `def_id`. /// /// Do not use this directly, use `tcx.get_attrs` instead. - query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] { + query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] { desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 119a99e1bf7..2c22f7b8f49 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -798,7 +798,7 @@ macro_rules! impl_ref_decoder { impl_ref_decoder! {<'tcx> Span, - rustc_ast::Attribute, + rustc_hir::Attribute, rustc_span::symbol::Ident, ty::Variance, rustc_span::def_id::DefId, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8337b0f9c1b..f32656decd2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -13,7 +13,7 @@ use std::ops::{Bound, Deref}; use std::{fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; -use rustc_ast::{self as ast, attr}; +use rustc_ast as ast; use rustc_data_structures::defer; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -29,13 +29,12 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, }; -use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::Definitions; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{HirId, Node, TraitCandidate}; +use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate}; use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::cache::WithDepNode; @@ -3239,12 +3238,16 @@ pub fn provide(providers: &mut Providers) { providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); providers.is_panic_runtime = - |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime); + |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::panic_runtime); providers.is_compiler_builtins = - |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins); + |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins); providers.has_panic_handler = |tcx, LocalCrate| { // We want to check if the panic handler was defined in this crate tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) }; providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP); } + +pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { + attrs.iter().any(|x| x.has_name(name)) +} diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 1dd564d9798..0ba187bf105 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -277,7 +277,7 @@ impl<'tcx> InstanceKind<'tcx> { &self, tcx: TyCtxt<'tcx>, attr: Symbol, - ) -> impl Iterator { + ) -> impl Iterator { tcx.get_attrs(self.def_id(), attr) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 262eba64027..cf8b6b5901a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1745,11 +1745,11 @@ impl<'tcx> TyCtxt<'tcx> { } // FIXME(@lcnr): Remove this function. - pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] { + pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] { if let Some(did) = did.as_local() { self.hir().attrs(self.local_def_id_to_hir_id(did)) } else { - self.item_attrs(did) + self.attrs_for_def(did) } } @@ -1758,14 +1758,14 @@ impl<'tcx> TyCtxt<'tcx> { self, did: impl Into, attr: Symbol, - ) -> impl Iterator { + ) -> impl Iterator { let did: DefId = did.into(); - let filter_fn = move |a: &&ast::Attribute| a.has_name(attr); + let filter_fn = move |a: &&hir::Attribute| a.has_name(attr); if let Some(did) = did.as_local() { self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { debug_assert!(rustc_feature::encode_cross_crate(attr)); - self.item_attrs(did).iter().filter(filter_fn) + self.attrs_for_def(did).iter().filter(filter_fn) } } @@ -1781,7 +1781,7 @@ impl<'tcx> TyCtxt<'tcx> { self, did: impl Into, attr: Symbol, - ) -> Option<&'tcx ast::Attribute> { + ) -> Option<&'tcx hir::Attribute> { let did: DefId = did.into(); if did.as_local().is_some() { // it's a crate local item, we need to check feature flags @@ -1794,7 +1794,7 @@ impl<'tcx> TyCtxt<'tcx> { // we filter out unstable diagnostic attributes before // encoding attributes debug_assert!(rustc_feature::encode_cross_crate(attr)); - self.item_attrs(did) + self.attrs_for_def(did) .iter() .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr)) } @@ -1804,19 +1804,19 @@ impl<'tcx> TyCtxt<'tcx> { self, did: DefId, attr: &'attr [Symbol], - ) -> impl Iterator + 'attr + ) -> impl Iterator + 'attr where 'tcx: 'attr, { - let filter_fn = move |a: &&ast::Attribute| a.path_matches(attr); + let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr); if let Some(did) = did.as_local() { self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { - self.item_attrs(did).iter().filter(filter_fn) + self.attrs_for_def(did).iter().filter(filter_fn) } } - pub fn get_attr(self, did: impl Into, attr: Symbol) -> Option<&'tcx ast::Attribute> { + pub fn get_attr(self, did: impl Into, attr: Symbol) -> Option<&'tcx hir::Attribute> { if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) { let did: DefId = did.into(); bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr); diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index f7322217aa3..348f25c8f90 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -111,6 +111,7 @@ trivially_parameterized_over_tcx! { rustc_span::hygiene::SyntaxContextData, rustc_span::symbol::Ident, rustc_type_ir::Variance, + rustc_hir::Attribute, } // HACK(compiler-errors): This macro rule can only take a fake path, @@ -140,5 +141,5 @@ parameterized_over_tcx! { ty::Predicate, ty::Clause, ty::ClauseKind, - ty::ImplTraitHeader + ty::ImplTraitHeader, } diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index e809c9a23f3..34cdc288f0b 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -17,10 +17,9 @@ //! terminators, and everything below can be found in the `parse::instruction` submodule. //! -use rustc_ast::Attribute; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::HirId; use rustc_hir::def_id::DefId; +use rustc_hir::{Attribute, HirId}; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::*; use rustc_middle::span_bug; diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index b6fa2099588..8cf37671185 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,6 +1,5 @@ -use rustc_ast as ast; -use rustc_ast::attr; use rustc_ast::token::{self, Delimiter}; +use rustc_ast::{self as ast, Attribute, attr}; use rustc_errors::codes::*; use rustc_errors::{Diag, PResult}; use rustc_span::symbol::kw; @@ -48,7 +47,7 @@ impl<'a> Parser<'a> { let start_pos = self.num_bump_calls; loop { let attr = if self.check(&token::Pound) { - let prev_outer_attr_sp = outer_attrs.last().map(|attr| attr.span); + let prev_outer_attr_sp = outer_attrs.last().map(|attr: &Attribute| attr.span); let inner_error_reason = if just_parsed_doc_comment { Some(InnerAttrForbiddenReason::AfterOuterDocComment { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index ffbd0c5269b..976ffe608a2 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -29,9 +29,9 @@ use rustc_ast::tokenstream::{ }; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, - DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, - Safety, StrLit, Visibility, VisibilityKind, + self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, + DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, + Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> { AttrArgs::Delimited(args) } else if self.eat(&token::Eq) { let eq_span = self.prev_token.span; - AttrArgs::Eq { eq_span, expr: AttrArgsEq::Ast(self.parse_expr_force_collect()?) } + AttrArgs::Eq { eq_span, expr: self.parse_expr_force_collect()? } } else { AttrArgs::Empty }) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f6ce26bd24a..8b6b37c0f8f 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -3,8 +3,7 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; use rustc_ast::{ - self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, - Safety, + self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety, }; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; @@ -70,7 +69,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - AttrArgs::Eq { expr: AttrArgsEq::Ast(expr), .. } => { + AttrArgs::Eq { expr, .. } => { if let ast::ExprKind::Lit(token_lit) = expr.kind { let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span); let res = match res { @@ -116,7 +115,6 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met return Err(err); } } - AttrArgs::Eq { expr: AttrArgsEq::Hir(lit), .. } => MetaItemKind::NameValue(lit.clone()), }, }) } diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 4db8584b884..ff3ae65fbea 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -1,4 +1,4 @@ -use rustc_ast::Attribute; +use rustc_hir::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a400fa6752a..ee197ce07ca 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -7,17 +7,15 @@ use std::cell::Cell; use std::collections::hash_map::Entry; -use rustc_ast::{ - AttrKind, AttrStyle, Attribute, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast, -}; +use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ - self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, - Item, ItemKind, MethodKind, Safety, Target, TraitItem, + self as hir, self, AssocItemKind, AttrKind, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, + ForeignItem, HirId, Item, ItemKind, MethodKind, Safety, Target, TraitItem, }; use rustc_macros::LintDiagnostic; use rustc_middle::hir::nested_filter; @@ -1176,10 +1174,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { specified_inline: &mut Option<(bool, Span)>, aliases: &mut FxHashMap, ) { - if let Some(mi) = attr.meta() - && let Some(list) = mi.meta_item_list() - { - for meta in list { + if let Some(list) = attr.meta_item_list() { + for meta in &list { if let Some(i_meta) = meta.meta_item() { match i_meta.name_or_empty() { sym::alias => { @@ -1279,7 +1275,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttrStyle::Inner => "!", AttrStyle::Outer => "", }, - sugg: (attr.meta().unwrap().span, applicability), + sugg: (attr.span, applicability), }, ); } else if i_meta.has_name(sym::passes) @@ -2141,10 +2137,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_confusables(&self, attr: &Attribute, target: Target) { match target { Target::Method(MethodKind::Inherent) => { - let Some(meta) = attr.meta() else { - return; - }; - let ast::MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { + let Some(metas) = attr.meta_item_list() else { return; }; @@ -2602,7 +2595,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { if let AttrKind::Normal(ref p) = attr.kind { tcx.dcx().try_steal_replace_and_emit_err( - p.item.path.span, + p.path.span, StashKey::UndeterminedMacroResolution, err, ); diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 1c3d3bf3dea..071e537233b 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -9,9 +9,8 @@ //! //! * Compiler internal types like `Ty` and `TyCtxt` -use rustc_ast as ast; -use rustc_hir::OwnerId; use rustc_hir::diagnostic_items::DiagnosticItems; +use rustc_hir::{Attribute, OwnerId}; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, LOCAL_CRATE}; @@ -55,7 +54,7 @@ fn report_duplicate_item( } /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes. -fn extract(attrs: &[ast::Attribute]) -> Option { +fn extract(attrs: &[Attribute]) -> Option { attrs.iter().find_map(|attr| { if attr.has_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None } }) diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 7ccbc7bdc57..a65e91d629f 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -500,7 +500,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_assoc_item_constraint(self, constraint) } - fn visit_attribute(&mut self, attr: &'v ast::Attribute) { + fn visit_attribute(&mut self, attr: &'v hir::Attribute) { self.record("Attribute", None, attr); } diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index bb90b5a1e31..dbdc383504c 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -1,5 +1,5 @@ use rustc_abi::{HasDataLayout, TargetDataLayout}; -use rustc_ast::Attribute; +use rustc_hir::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 8a360c017ad..ec9075bbdee 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -4,8 +4,8 @@ //! but are not declared in one single location (unlike lang features), which means we need to //! collect them instead. -use rustc_ast::Attribute; use rustc_attr::VERSION_PLACEHOLDER; +use rustc_hir::Attribute; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures}; diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 5a72e80a0a5..480fd497728 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -1,18 +1,17 @@ //! This module contains `HashStable` implementations for various data types -//! from `rustc_ast` in no particular order. +//! from various crates in no particular order. -use std::assert_matches::assert_matches; - -use rustc_ast as ast; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hir as hir; use rustc_span::SourceFile; use smallvec::SmallVec; use crate::ich::StableHashingContext; impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {} +impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {} -impl<'a> HashStable> for [ast::Attribute] { +impl<'a> HashStable> for [hir::Attribute] { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { if self.is_empty() { self.len().hash_stable(hcx, hasher); @@ -20,7 +19,7 @@ impl<'a> HashStable> for [ast::Attribute] { } // Some attributes are always ignored during hashing. - let filtered: SmallVec<[&ast::Attribute; 8]> = self + let filtered: SmallVec<[&hir::Attribute; 8]> = self .iter() .filter(|attr| { !attr.is_doc_comment() @@ -35,30 +34,23 @@ impl<'a> HashStable> for [ast::Attribute] { } } -impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> { - fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) { +impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { + fn hash_attr(&mut self, attr: &hir::Attribute, hasher: &mut StableHasher) { // Make sure that these have been filtered out. debug_assert!(!attr.ident().is_some_and(|ident| self.is_ignored_attr(ident.name))); debug_assert!(!attr.is_doc_comment()); - let ast::Attribute { kind, id: _, style, span } = attr; - if let ast::AttrKind::Normal(normal) = kind { - normal.item.hash_stable(self, hasher); + let hir::Attribute { kind, id: _, style, span } = attr; + if let hir::AttrKind::Normal(item) = kind { + item.hash_stable(self, hasher); style.hash_stable(self, hasher); span.hash_stable(self, hasher); - assert_matches!( - normal.tokens.as_ref(), - None, - "Tokens should have been removed during lowering!" - ); } else { unreachable!(); } } } -impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {} - impl<'a> HashStable> for SourceFile { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let SourceFile { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 669a9c2428f..6e2af9aae23 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -7,7 +7,7 @@ use std::mem; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr}; use rustc_ast_pretty::pprust; -use rustc_attr::StabilityLevel; +use rustc_attr::{AttributeExt, StabilityLevel}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, StashKey}; @@ -1126,7 +1126,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, macro_def: &ast::MacroDef, ident: Ident, - attrs: &[ast::Attribute], + attrs: &[impl AttributeExt], span: Span, node_id: NodeId, edition: Edition, diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 1fbfe56d95d..8b14fe31d8c 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -6,6 +6,7 @@ use pulldown_cmark::{ }; use rustc_ast as ast; use rustc_ast::util::comments::beautify_doc_string; +use rustc_attr::AttributeExt; use rustc_data_structures::fx::FxIndexMap; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; @@ -192,19 +193,24 @@ pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) { } } -pub fn attrs_to_doc_fragments<'a>( - attrs: impl Iterator)>, +pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>( + attrs: impl Iterator)>, doc_only: bool, -) -> (Vec, ast::AttrVec) { +) -> (Vec, Vec) { let mut doc_fragments = Vec::new(); - let mut other_attrs = ast::AttrVec::new(); + let mut other_attrs = Vec::::new(); for (attr, item_id) in attrs { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { let doc = beautify_doc_string(doc_str, comment_kind); let (span, kind) = if attr.is_doc_comment() { - (attr.span, DocFragmentKind::SugaredDoc) + (attr.span(), DocFragmentKind::SugaredDoc) } else { - (span_for_value(attr), DocFragmentKind::RawDoc) + ( + attr.value_span() + .map(|i| i.with_ctxt(attr.span().ctxt())) + .unwrap_or(attr.span()), + DocFragmentKind::RawDoc, + ) }; let fragment = DocFragment { span, doc, kind, item_id, indent: 0 }; doc_fragments.push(fragment); @@ -218,16 +224,6 @@ pub fn attrs_to_doc_fragments<'a>( (doc_fragments, other_attrs) } -fn span_for_value(attr: &ast::Attribute) -> Span { - if let ast::AttrKind::Normal(normal) = &attr.kind - && let ast::AttrArgs::Eq { expr, .. } = &normal.item.args - { - expr.span().with_ctxt(attr.span.ctxt()) - } else { - attr.span - } -} - /// Return the doc-comments on this item, grouped by the module they came from. /// The module can be different if this is a re-export with added documentation. /// @@ -353,12 +349,15 @@ pub fn strip_generics_from_path(path_str: &str) -> Result, MalformedGen /// //// If there are no doc-comments, return true. /// FIXME(#78591): Support both inner and outer attributes on the same item. -pub fn inner_docs(attrs: &[ast::Attribute]) -> bool { - attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner) +pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { + attrs + .iter() + .find(|a| a.doc_str().is_some()) + .map_or(true, |a| a.style() == ast::AttrStyle::Inner) } /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`. -pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool { +pub fn has_primitive_or_keyword_docs(attrs: &[impl AttributeExt]) -> bool { for attr in attrs { if attr.has_name(sym::rustc_doc_primitive) { return true; @@ -408,7 +407,7 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool { /// Simplified version of `preprocessed_markdown_links` from rustdoc. /// Must return at least the same links as it, but may add some more links on top of that. -pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec> { +pub(crate) fn attrs_to_preprocessed_links(attrs: &[A]) -> Vec> { let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true); let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap(); diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 1230667ee91..29ce24e8b78 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -7,9 +7,9 @@ edition = "2021" # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 9025b47c422..4b172517fd5 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -255,7 +255,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { attr.iter().map(|seg| rustc_span::symbol::Symbol::intern(&seg)).collect(); tcx.get_attrs_by_path(did, &attr_name) .map(|attribute| { - let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute); + let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute); let span = attribute.span; stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables)) }) @@ -266,17 +266,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let did = tables[def_id]; - let filter_fn = move |a: &&rustc_ast::ast::Attribute| { - matches!(a.kind, rustc_ast::ast::AttrKind::Normal(_)) - }; + let filter_fn = + move |a: &&rustc_hir::Attribute| matches!(a.kind, rustc_hir::AttrKind::Normal(_)); let attrs_iter = if let Some(did) = did.as_local() { tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { - tcx.item_attrs(did).iter().filter(filter_fn) + tcx.attrs_for_def(did).iter().filter(filter_fn) }; attrs_iter .map(|attribute| { - let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute); + let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute); let span = attribute.span; stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables)) }) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 6368cd473f1..dac4a03bf75 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,11 +1,12 @@ use std::iter; use std::path::PathBuf; -use rustc_ast::{AttrArgs, AttrKind, Attribute, MetaItemInner}; +use rustc_ast::MetaItemInner; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{AttrArgs, AttrKind, Attribute}; use rustc_macros::LintDiagnostic; use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; @@ -639,7 +640,7 @@ impl<'tcx> OnUnimplementedDirective { let report_span = match &item.args { AttrArgs::Empty => item.path.span, AttrArgs::Delimited(args) => args.dspan.entire(), - AttrArgs::Eq { eq_span, expr } => eq_span.to(expr.span()), + AttrArgs::Eq { eq_span, expr } => eq_span.to(expr.span), }; if let Some(item_def_id) = item_def_id.as_local() { @@ -654,7 +655,7 @@ impl<'tcx> OnUnimplementedDirective { } } else if is_diagnostic_namespace_variant { match &attr.kind { - AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => { + AttrKind::Normal(p) if !matches!(p.args, AttrArgs::Empty) => { if let Some(item_def_id) = item_def_id.as_local() { tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d81c47886d2..019a888bd2f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -4,6 +4,7 @@ use std::iter::once; use std::sync::Arc; use rustc_data_structures::fx::FxHashSet; +use rustc_hir as hir; use rustc_hir::Mutability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdSet, LocalDefId, LocalModDefId}; @@ -15,7 +16,6 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, trace}; -use {rustc_ast as ast, rustc_hir as hir}; use super::Item; use crate::clean::{ @@ -43,7 +43,7 @@ pub(crate) fn try_inline( cx: &mut DocContext<'_>, res: Res, name: Symbol, - attrs: Option<(&[ast::Attribute], Option)>, + attrs: Option<(&[hir::Attribute], Option)>, visited: &mut DefIdSet, ) -> Option> { let did = res.opt_def_id()?; @@ -206,7 +206,7 @@ pub(crate) fn try_inline_glob( } } -pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast::Attribute] { +pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir::Attribute] { cx.tcx.get_attrs_unchecked(did) } @@ -360,7 +360,7 @@ fn build_type_alias( pub(crate) fn build_impls( cx: &mut DocContext<'_>, did: DefId, - attrs: Option<(&[ast::Attribute], Option)>, + attrs: Option<(&[hir::Attribute], Option)>, ret: &mut Vec, ) { let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls"); @@ -392,8 +392,8 @@ pub(crate) fn build_impls( pub(crate) fn merge_attrs( cx: &mut DocContext<'_>, - old_attrs: &[ast::Attribute], - new_attrs: Option<(&[ast::Attribute], Option)>, + old_attrs: &[hir::Attribute], + new_attrs: Option<(&[hir::Attribute], Option)>, ) -> (clean::Attributes, Option>) { // NOTE: If we have additional attributes (from a re-export), // always insert them first. This ensure that re-export @@ -404,14 +404,14 @@ pub(crate) fn merge_attrs( both.extend_from_slice(old_attrs); ( if let Some(item_id) = item_id { - Attributes::from_ast_with_additional(old_attrs, (inner, item_id.to_def_id())) + Attributes::from_hir_with_additional(old_attrs, (inner, item_id.to_def_id())) } else { - Attributes::from_ast(&both) + Attributes::from_hir(&both) }, both.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } else { - (Attributes::from_ast(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg)) + (Attributes::from_hir(old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg)) } } @@ -419,7 +419,7 @@ pub(crate) fn merge_attrs( pub(crate) fn build_impl( cx: &mut DocContext<'_>, did: DefId, - attrs: Option<(&[ast::Attribute], Option)>, + attrs: Option<(&[hir::Attribute], Option)>, ret: &mut Vec, ) { if !cx.inlined.insert(did.into()) { @@ -629,7 +629,7 @@ fn build_module_items( visited: &mut DefIdSet, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, allowed_def_ids: Option<&DefIdSet>, - attrs: Option<(&[ast::Attribute], Option)>, + attrs: Option<(&[hir::Attribute], Option)>, ) -> Vec { let mut items = Vec::new(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 25f88c8797f..9903d0faf43 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -201,7 +201,7 @@ fn generate_item_with_correct_attrs( }; let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); - let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); + let attrs = Attributes::from_hir_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); let name = renamed.or(Some(name)); let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg); @@ -1036,7 +1036,7 @@ fn clean_fn_or_proc_macro<'tcx>( /// This is needed to make it more "readable" when documenting functions using /// `rustc_legacy_const_generics`. More information in /// . -fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attribute]) { +fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attribute]) { for meta_item_list in attrs .iter() .filter(|a| a.has_name(sym::rustc_legacy_const_generics)) @@ -2578,7 +2578,7 @@ fn get_all_import_attributes<'hir>( import_def_id: LocalDefId, target_def_id: DefId, is_inline: bool, -) -> Vec<(Cow<'hir, ast::Attribute>, Option)> { +) -> Vec<(Cow<'hir, hir::Attribute>, Option)> { let mut attrs = Vec::new(); let mut first = true; for def_id in reexport_chain(cx.tcx, import_def_id, target_def_id) @@ -2631,9 +2631,9 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { /// Remove attributes from `normal` that should not be inherited by `use` re-export. /// Before calling this function, make sure `normal` is a `#[doc]` attribute. -fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { - match normal.item.args { - ast::AttrArgs::Delimited(ref mut args) => { +fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { + match args { + hir::AttrArgs::Delimited(ref mut args) => { let tokens = filter_tokens_from_list(&args.tokens, |token| { !matches!( token, @@ -2651,7 +2651,7 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { }); args.tokens = TokenStream::new(tokens); } - ast::AttrArgs::Empty | ast::AttrArgs::Eq { .. } => {} + hir::AttrArgs::Empty | hir::AttrArgs::Eq { .. } => {} } } @@ -2676,23 +2676,23 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { /// * `doc(no_inline)` /// * `doc(hidden)` fn add_without_unwanted_attributes<'hir>( - attrs: &mut Vec<(Cow<'hir, ast::Attribute>, Option)>, - new_attrs: &'hir [ast::Attribute], + attrs: &mut Vec<(Cow<'hir, hir::Attribute>, Option)>, + new_attrs: &'hir [hir::Attribute], is_inline: bool, import_parent: Option, ) { for attr in new_attrs { - if matches!(attr.kind, ast::AttrKind::DocComment(..)) { + if matches!(attr.kind, hir::AttrKind::DocComment(..)) { attrs.push((Cow::Borrowed(attr), import_parent)); continue; } let mut attr = attr.clone(); match attr.kind { - ast::AttrKind::Normal(ref mut normal) => { - if let [ident] = &*normal.item.path.segments { - let ident = ident.ident.name; + hir::AttrKind::Normal(ref mut normal) => { + if let [ident] = &*normal.path.segments { + let ident = ident.name; if ident == sym::doc { - filter_doc_attr(normal, is_inline); + filter_doc_attr(&mut normal.args, is_inline); attrs.push((Cow::Owned(attr), import_parent)); } else if is_inline || ident != sym::cfg { // If it's not a `cfg()` attribute, we keep it. diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cba947eb833..d4dc35b6c9c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -6,8 +6,6 @@ use std::{fmt, iter}; use arrayvec::ArrayVec; use rustc_abi::{ExternAbi, VariantIdx}; -use rustc_ast::MetaItemInner; -use rustc_ast_pretty::pprust; use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -454,14 +452,14 @@ impl Item { kind: ItemKind, cx: &mut DocContext<'_>, ) -> Item { - let ast_attrs = cx.tcx.get_attrs_unchecked(def_id); + let hir_attrs = cx.tcx.get_attrs_unchecked(def_id); Self::from_def_id_and_attrs_and_parts( def_id, name, kind, - Attributes::from_ast(ast_attrs), - ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), + Attributes::from_hir(hir_attrs), + hir_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) } @@ -742,10 +740,10 @@ impl Item { .iter() .filter_map(|attr| { if keep_as_is { - Some(pprust::attribute_to_string(attr)) + Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)) } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { Some( - pprust::attribute_to_string(attr) + rustc_hir_pretty::attribute_to_string(&tcx, attr) .replace("\\\n", "") .replace('\n', "") .replace(" ", " "), @@ -955,7 +953,7 @@ pub(crate) trait AttributesExt { type AttributeIterator<'a>: Iterator where Self: 'a; - type Attributes<'a>: Iterator + type Attributes<'a>: Iterator where Self: 'a; @@ -1009,7 +1007,7 @@ pub(crate) trait AttributesExt { // #[doc] if attr.doc_str().is_none() && attr.has_name(sym::doc) { // #[doc(...)] - if let Some(list) = attr.meta().as_ref().and_then(|mi| mi.meta_item_list()) { + if let Some(list) = attr.meta_item_list() { for item in list { // #[doc(hidden)] if !item.has_name(sym::cfg) { @@ -1042,7 +1040,7 @@ pub(crate) trait AttributesExt { let mut meta = attr.meta_item().unwrap().clone(); meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); - if let Ok(feat_cfg) = Cfg::parse(&MetaItemInner::MetaItem(meta)) { + if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) { cfg &= feat_cfg; } } @@ -1053,14 +1051,14 @@ pub(crate) trait AttributesExt { } } -impl AttributesExt for [ast::Attribute] { +impl AttributesExt for [hir::Attribute] { type AttributeIterator<'a> = impl Iterator + 'a; - type Attributes<'a> = impl Iterator + 'a; + type Attributes<'a> = impl Iterator + 'a; fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> { self.iter() .filter(move |attr| attr.has_name(name)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(ast::attr::AttributeExt::meta_item_list) .flatten() } @@ -1069,20 +1067,20 @@ impl AttributesExt for [ast::Attribute] { } } -impl AttributesExt for [(Cow<'_, ast::Attribute>, Option)] { +impl AttributesExt for [(Cow<'_, hir::Attribute>, Option)] { type AttributeIterator<'a> = impl Iterator + 'a where Self: 'a; type Attributes<'a> - = impl Iterator + 'a + = impl Iterator + 'a where Self: 'a; fn lists(&self, name: Symbol) -> Self::AttributeIterator<'_> { AttributesExt::iter(self) .filter(move |attr| attr.has_name(name)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(hir::Attribute::meta_item_list) .flatten() } @@ -1152,7 +1150,7 @@ pub struct RenderedLink { #[derive(Clone, Debug, Default)] pub(crate) struct Attributes { pub(crate) doc_strings: Vec, - pub(crate) other_attrs: ast::AttrVec, + pub(crate) other_attrs: Vec, } impl Attributes { @@ -1180,22 +1178,22 @@ impl Attributes { self.has_doc_flag(sym::hidden) } - pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes { - Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false) + pub(crate) fn from_hir(attrs: &[hir::Attribute]) -> Attributes { + Attributes::from_hir_iter(attrs.iter().map(|attr| (attr, None)), false) } - pub(crate) fn from_ast_with_additional( - attrs: &[ast::Attribute], - (additional_attrs, def_id): (&[ast::Attribute], DefId), + pub(crate) fn from_hir_with_additional( + attrs: &[hir::Attribute], + (additional_attrs, def_id): (&[hir::Attribute], DefId), ) -> Attributes { // Additional documentation should be shown before the original documentation. let attrs1 = additional_attrs.iter().map(|attr| (attr, Some(def_id))); let attrs2 = attrs.iter().map(|attr| (attr, None)); - Attributes::from_ast_iter(attrs1.chain(attrs2), false) + Attributes::from_hir_iter(attrs1.chain(attrs2), false) } - pub(crate) fn from_ast_iter<'a>( - attrs: impl Iterator)>, + pub(crate) fn from_hir_iter<'a>( + attrs: impl Iterator)>, doc_only: bool, ) -> Attributes { let (doc_strings, other_attrs) = attrs_to_doc_fragments(attrs, doc_only); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index d59b4e4081c..617a7ab8097 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -578,7 +578,7 @@ pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool { } pub(crate) fn attrs_have_doc_flag<'a>( - mut attrs: impl Iterator, + mut attrs: impl Iterator, flag: Symbol, ) -> bool { attrs diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 70d9269ae5c..6fee049cdf0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -13,10 +13,10 @@ use std::{panic, str}; pub(crate) use make::DocTestBuilder; pub(crate) use markdown::test as test_markdown; -use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagCtxtHandle}; +use rustc_hir as hir; use rustc_hir::CRATE_HIR_ID; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::interface; @@ -325,7 +325,7 @@ pub(crate) fn run_tests( // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade. fn scrape_test_config( crate_name: String, - attrs: &[ast::Attribute], + attrs: &[hir::Attribute], args_file: PathBuf, ) -> GlobalTestOptions { use rustc_ast_pretty::pprust; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index dc68f48f635..0903baddabe 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -110,7 +110,7 @@ impl HirCollector<'_> { // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with // anything else, this will combine them for us. - let attrs = Attributes::from_ast(ast_attrs); + let attrs = Attributes::from_hir(ast_attrs); if let Some(doc) = attrs.opt_doc_value() { let span = span_of_fragments(&attrs.doc_strings).unwrap_or(sp); self.collector.position = if span.edition().at_least_rust_2024() { diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs index d41bb580c6c..2325f914b0b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs @@ -1,7 +1,7 @@ use super::INLINE_ALWAYS; use super::utils::is_word; use clippy_utils::diagnostics::span_lint; -use rustc_ast::Attribute; +use rustc_hir::Attribute; use rustc_lint::LateContext; use rustc_span::symbol::Symbol; use rustc_span::{Span, sym}; diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs index 1d6b3388e59..b4ed8a68a32 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -2,14 +2,14 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind}; +use rustc_ast::{AttrArgs, AttrKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq { expr: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args { + if let AttrArgs::Eq { .. } = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index 383fae7992b..a1ff20dee72 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -5,9 +5,8 @@ use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn}; use core::ops::ControlFlow; -use rustc_ast::ast::Attribute; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, Expr, ExprKind, FnDecl}; +use rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; diff --git a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs index de7a2c2433f..099194d4e74 100644 --- a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs +++ b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs @@ -2,10 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{SpanRangeExt, snippet_indent}; use clippy_utils::tokenize_with_text; use itertools::Itertools; +use rustc_ast::AttrStyle; use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute}; use rustc_errors::{Applicability, Diag, SuggestionStyle}; -use rustc_hir::{ItemKind, Node}; +use rustc_hir::{AttrKind, Attribute, ItemKind, Node}; use rustc_lexer::TokenKind; use rustc_lint::LateContext; use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData}; diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs index f2886164a46..0bb16a0c77d 100644 --- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,18 +1,18 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute}; +use rustc_ast::{AttrStyle}; use rustc_errors::Applicability; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_hir::{Attribute, AttrKind, AttrArgs}; use super::DOC_INCLUDE_WITHOUT_CFG; pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { for attr in attrs { if !attr.span.from_expansion() - && let AttrKind::Normal(ref normal) = attr.kind - && normal.item.path == sym::doc - && let AttrArgs::Eq { expr: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrKind::Normal(ref item) = attr.kind + && attr.doc_str().is_some() + && let AttrArgs::Eq { expr: meta, .. } = &item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 88ac871acf6..f65acd7978a 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -16,10 +16,9 @@ use pulldown_cmark::Event::{ }; use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph}; use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd}; -use rustc_ast::ast::Attribute; use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AnonConst, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind}; +use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs index f6f942b10ca..84393213e6f 100644 --- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::AttrStyle; use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute}; use rustc_errors::Applicability; +use rustc_hir::Attribute; use rustc_lint::LateContext; use rustc_span::Span; @@ -35,7 +36,7 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { attrs .iter() .filter_map(|attr| { - if let AttrKind::DocComment(com_kind, sym) = attr.kind + if let Some((sym, com_kind)) = attr.doc_str_and_comment_kind() && let AttrStyle::Outer = attr.style && let Some(com) = sym.as_str().strip_prefix('!') { diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs index 0165d24c7df..0f9ff550853 100644 --- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs +++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs @@ -1,6 +1,5 @@ -use rustc_ast::ast::Attribute; use rustc_errors::Applicability; -use rustc_hir::{Item, ItemKind}; +use rustc_hir::{Attribute, Item, ItemKind}; use rustc_lint::LateContext; use clippy_utils::diagnostics::span_lint_and_then; diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 175d92d2d79..2b26285429a 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -1,9 +1,8 @@ use hir::FnSig; -use rustc_ast::ast::Attribute; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefIdSet; -use rustc_hir::{self as hir, QPath}; +use rustc_hir::{self as hir, Attribute, QPath}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index a0657a233c1..66d4c40ab5e 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -2,8 +2,8 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind}; -use rustc_hir::{Expr, ExprKind}; +use rustc_ast::{LitKind}; +use rustc_hir::{Expr, ExprKind, Attribute, AttrArgs, AttrKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, sym}; @@ -93,10 +93,10 @@ impl LateLintPass<'_> for LargeIncludeFile { if !attr.span.from_expansion() // Currently, rustc limits the usage of macro at the top-level of attributes, // so we don't need to recurse into each level. - && let AttrKind::Normal(ref normal) = attr.kind + && let AttrKind::Normal(ref item) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { expr: AttrArgsEq::Hir(ref meta), .. } = normal.item.args + && let AttrArgs::Eq { expr: meta, .. } = &item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 22aa681b681..3c669d94d69 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; use hir::def::{DefKind, Res}; -use rustc_ast::ast; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; @@ -104,7 +103,7 @@ impl LateLintPass<'_> for MacroUseImports { self.push_unique_macro_pat_ty(cx, item.span); } } - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) { if attr.span.from_expansion() { self.push_unique_macro(cx, attr.span); } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index 47472ab831f..223d0dc7656 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -2,9 +2,9 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; -use rustc_ast::{Attribute, LitKind}; +use rustc_ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath}; +use rustc_hir::{Arm, Attribute, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; use rustc_span::source_map::Spanned; diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 1300c7d1062..b6f49dcc163 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -10,8 +10,9 @@ use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_from_proc_macro; use clippy_utils::source::SpanRangeExt; -use rustc_ast::ast::{self, MetaItem, MetaItemKind}; +use rustc_ast::ast::MetaItemInner; use rustc_hir as hir; +use rustc_hir::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -67,9 +68,8 @@ impl MissingDoc { *self.doc_hidden_stack.last().expect("empty doc_hidden_stack") } - fn has_include(meta: Option) -> bool { - if let Some(meta) = meta - && let MetaItemKind::List(list) = meta.kind + fn has_include(meta: Option<&[MetaItemInner]>) -> bool { + if let Some(list) = meta && let Some(meta) = list.first() && let Some(name) = meta.ident() { @@ -83,7 +83,7 @@ impl MissingDoc { &self, cx: &LateContext<'_>, def_id: LocalDefId, - attrs: &[ast::Attribute], + attrs: &[Attribute], sp: Span, article: &'static str, desc: &'static str, @@ -129,7 +129,7 @@ impl MissingDoc { let has_doc = attrs .iter() - .any(|a| a.doc_str().is_some() || Self::has_include(a.meta())) + .any(|a| a.doc_str().is_some() || Self::has_include(a.meta_item_list().as_deref())) || matches!(self.search_span(sp), Some(span) if span_to_snippet_contains_docs(cx, span)); if !has_doc { @@ -172,12 +172,12 @@ impl MissingDoc { impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]); impl<'tcx> LateLintPass<'tcx> for MissingDoc { - fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { + fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs); self.doc_hidden_stack.push(doc_hidden); } - fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) { + fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index e587d695c84..11ff779d531 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; -use rustc_ast::ast; use rustc_hir as hir; +use rustc_hir::Attribute; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocItemContainer; use rustc_session::declare_lint_pass; @@ -63,7 +63,7 @@ declare_clippy_lint! { "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)" } -fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { +fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) { let has_inline = attrs.iter().any(|a| a.has_name(sym::inline)); if !has_inline { span_lint( diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 6f3f371a68d..30846fb46ac 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -5,12 +5,11 @@ use clippy_utils::source::{SpanRangeExt, snippet}; use clippy_utils::ty::{ implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item, }; -use rustc_ast::ast::Attribute; use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath, - TyKind, + Attribute, BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, + PatKind, QPath, TyKind, }; use rustc_hir_typeck::expr_use_visitor as euv; use rustc_lint::{LateContext, LateLintPass}; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 6df0748c117..623d9c76086 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -872,8 +872,7 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { match (l, r) { (Empty, Empty) => true, (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra), - (Eq { expr: AttrArgsEq::Ast(le), .. }, Eq{ expr: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re), - (Eq { expr: AttrArgsEq::Hir(ll), .. }, Eq{ expr: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind, + (Eq { eq_span: _, expr: le }, Eq { eq_span: _, expr: re }) => eq_expr(le, re), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index b2a6657baad..922afffb876 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -1,4 +1,5 @@ -use rustc_ast::{ast, attr}; +use rustc_ast::attr; +use rustc_ast::attr::AttributeExt; use rustc_errors::Applicability; use rustc_lexer::TokenKind; use rustc_lint::LateContext; @@ -51,33 +52,31 @@ impl LimitStack { pub fn limit(&self) -> u64 { *self.stack.last().expect("there should always be a value in the stack") } - pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { + pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| stack.push(val)); } - pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) { + pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val))); } } -pub fn get_attr<'a>( +pub fn get_attr<'a, A: AttributeExt + 'a>( sess: &'a Session, - attrs: &'a [ast::Attribute], + attrs: &'a [A], name: &'static str, -) -> impl Iterator { +) -> impl Iterator { attrs.iter().filter(move |attr| { - let attr = if let ast::AttrKind::Normal(ref normal) = attr.kind { - &normal.item - } else { + let Some(attr_segments) = attr.ident_path() else { return false; }; - let attr_segments = &attr.path.segments; - if attr_segments.len() == 2 && attr_segments[0].ident.name == sym::clippy { + + if attr_segments.len() == 2 && attr_segments[0].name == sym::clippy { BUILTIN_ATTRIBUTES .iter() .find_map(|&(builtin_name, ref deprecation_status)| { - if attr_segments[1].ident.name.as_str() == builtin_name { + if attr_segments[1].name.as_str() == builtin_name { Some(deprecation_status) } else { None @@ -85,14 +84,13 @@ pub fn get_attr<'a>( }) .map_or_else( || { - sess.dcx() - .span_err(attr_segments[1].ident.span, "usage of unknown attribute"); + sess.dcx().span_err(attr_segments[1].span, "usage of unknown attribute"); false }, |deprecation_status| { let mut diag = sess .dcx() - .struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute"); + .struct_span_err(attr_segments[1].span, "usage of deprecated attribute"); match *deprecation_status { DeprecationStatus::Deprecated => { diag.emit(); @@ -100,7 +98,7 @@ pub fn get_attr<'a>( }, DeprecationStatus::Replaced(new_name) => { diag.span_suggestion( - attr_segments[1].ident.span, + attr_segments[1].span, "consider using", new_name, Applicability::MachineApplicable, @@ -110,7 +108,7 @@ pub fn get_attr<'a>( }, DeprecationStatus::None => { diag.cancel(); - attr_segments[1].ident.name.as_str() == name + attr_segments[1].as_str() == name }, } }, @@ -121,31 +119,31 @@ pub fn get_attr<'a>( }) } -fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) { +fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt], name: &'static str, mut f: F) { for attr in get_attr(sess, attrs, name) { if let Some(ref value) = attr.value_str() { if let Ok(value) = FromStr::from_str(value.as_str()) { f(value); } else { - sess.dcx().span_err(attr.span, "not a number"); + sess.dcx().span_err(attr.span(), "not a number"); } } else { - sess.dcx().span_err(attr.span, "bad clippy attribute"); + sess.dcx().span_err(attr.span(), "bad clippy attribute"); } } } -pub fn get_unique_attr<'a>( +pub fn get_unique_attr<'a, A: AttributeExt>( sess: &'a Session, - attrs: &'a [ast::Attribute], + attrs: &'a [A], name: &'static str, -) -> Option<&'a ast::Attribute> { - let mut unique_attr: Option<&ast::Attribute> = None; +) -> Option<&'a A> { + let mut unique_attr: Option<&A> = None; for attr in get_attr(sess, attrs, name) { if let Some(duplicate) = unique_attr { sess.dcx() - .struct_span_err(attr.span, format!("`{name}` is defined multiple times")) - .with_span_note(duplicate.span, "first definition found here") + .struct_span_err(attr.span(), format!("`{name}` is defined multiple times")) + .with_span_note(duplicate.span(), "first definition found here") .emit(); } else { unique_attr = Some(attr); @@ -156,16 +154,16 @@ pub fn get_unique_attr<'a>( /// Returns true if the attributes contain any of `proc_macro`, /// `proc_macro_derive` or `proc_macro_attribute`, false otherwise -pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool { - attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr) +pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool { + attrs.iter().any(AttributeExt::is_proc_macro_attr) } /// Returns true if the attributes contain `#[doc(hidden)]` -pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool { +pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { attrs .iter() .filter(|attr| attr.has_name(sym::doc)) - .filter_map(ast::Attribute::meta_item_list) + .filter_map(AttributeExt::meta_item_list) .any(|l| attr::list_contains_name(&l, sym::hidden)) } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 8d48cdd3cbb..96139a08c3d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -135,13 +135,24 @@ use rustc_middle::hir::nested_filter; #[macro_export] macro_rules! extract_msrv_attr { - ($context:ident) => { - fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + (LateContext) => { + fn check_attributes(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes(sess, attrs); } - fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + fn check_attributes_post(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) { + let sess = rustc_lint::LintContext::sess(cx); + self.msrv.check_attributes_post(sess, attrs); + } + }; + (EarlyContext) => { + fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { + let sess = rustc_lint::LintContext::sess(cx); + self.msrv.check_attributes(sess, attrs); + } + + fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); self.msrv.check_attributes_post(sess, attrs); } @@ -1912,7 +1923,7 @@ pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 { (u << amt) >> amt } -pub fn has_attr(attrs: &[ast::Attribute], symbol: Symbol) -> bool { +pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { attrs.iter().any(|attr| attr.has_name(symbol)) } @@ -2263,21 +2274,13 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { - if let ast::AttrKind::Normal(ref normal) = attr.kind { - normal.item.path == sym::no_std - } else { - false - } + attr.name_or_empty() == sym::no_std }) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { - if let ast::AttrKind::Normal(ref normal) = attr.kind { - normal.item.path == sym::no_core - } else { - false - } + attr.name_or_empty() == sym::no_core }) } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 1eb7d54e133..5b1c3465d05 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -1,4 +1,4 @@ -use rustc_ast::Attribute; +use rustc_attr::AttributeExt; use rustc_attr::parse_version; use rustc_session::{RustcVersion, Session}; use rustc_span::{Symbol, sym}; @@ -124,15 +124,15 @@ impl Msrv { self.current().is_none_or(|msrv| msrv >= required) } - fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option { + fn parse_attr(sess: &Session, attrs: &[impl AttributeExt]) -> Option { let sym_msrv = Symbol::intern("msrv"); let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); if let Some(msrv_attr) = msrv_attrs.next() { if let Some(duplicate) = msrv_attrs.last() { sess.dcx() - .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") - .with_span_note(msrv_attr.span, "first definition found here") + .struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times") + .with_span_note(msrv_attr.span(), "first definition found here") .emit(); } @@ -142,22 +142,22 @@ impl Msrv { } sess.dcx() - .span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); + .span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version")); } else { - sess.dcx().span_err(msrv_attr.span, "bad clippy attribute"); + sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute"); } } None } - pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { if let Some(version) = Self::parse_attr(sess, attrs) { self.stack.push(version); } } - pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[impl AttributeExt]) { if Self::parse_attr(sess, attrs).is_some() { self.stack.pop(); } diff --git a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout index e9ee59abfae..e8c88d2dcdf 100644 --- a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout +++ b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout @@ -7,9 +7,7 @@ extern crate std; // issue#97006 macro_rules! m { ($attr_path: path) => { #[$attr_path] fn f() {} } } -#[ - -inline] +#[inline] fn f() { } fn main() { } -- cgit 1.4.1-3-g733a5 From 1341366af911a16c53513d5eda2cc8cf31c8c027 Mon Sep 17 00:00:00 2001 From: Jonathan Dönszelmann Date: Sat, 7 Dec 2024 15:27:17 +0100 Subject: split attributes --- .../rustc_attr/src/attributes/allow_unstable.rs | 49 + compiler/rustc_attr/src/attributes/cfg.rs | 255 ++++ compiler/rustc_attr/src/attributes/confusables.rs | 22 + compiler/rustc_attr/src/attributes/deprecation.rs | 149 +++ compiler/rustc_attr/src/attributes/mod.rs | 17 + compiler/rustc_attr/src/attributes/repr.rs | 216 ++++ compiler/rustc_attr/src/attributes/stability.rs | 385 ++++++ compiler/rustc_attr/src/attributes/transparency.rs | 35 + compiler/rustc_attr/src/attributes/util.rs | 36 + compiler/rustc_attr/src/builtin.rs | 1349 -------------------- compiler/rustc_attr/src/lib.rs | 35 +- compiler/rustc_attr/src/session_diagnostics.rs | 3 +- compiler/rustc_attr/src/types.rs | 262 ++++ compiler/rustc_codegen_ssa/src/base.rs | 5 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 3 +- compiler/rustc_expand/src/base.rs | 12 +- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 3 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 9 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 23 +- compiler/rustc_middle/src/middle/stability.rs | 4 +- compiler/rustc_passes/src/stability.rs | 26 +- compiler/rustc_resolve/src/build_reduced_graph.rs | 16 +- compiler/rustc_resolve/src/macros.rs | 3 +- compiler/rustc_resolve/src/rustdoc.rs | 2 +- src/librustdoc/clean/mod.rs | 8 +- src/librustdoc/clean/utils.rs | 3 +- src/tools/clippy/clippy_utils/src/msrvs.rs | 2 +- 29 files changed, 1521 insertions(+), 1415 deletions(-) create mode 100644 compiler/rustc_attr/src/attributes/allow_unstable.rs create mode 100644 compiler/rustc_attr/src/attributes/cfg.rs create mode 100644 compiler/rustc_attr/src/attributes/confusables.rs create mode 100644 compiler/rustc_attr/src/attributes/deprecation.rs create mode 100644 compiler/rustc_attr/src/attributes/mod.rs create mode 100644 compiler/rustc_attr/src/attributes/repr.rs create mode 100644 compiler/rustc_attr/src/attributes/stability.rs create mode 100644 compiler/rustc_attr/src/attributes/transparency.rs create mode 100644 compiler/rustc_attr/src/attributes/util.rs delete mode 100644 compiler/rustc_attr/src/builtin.rs create mode 100644 compiler/rustc_attr/src/types.rs (limited to 'src/tools') diff --git a/compiler/rustc_attr/src/attributes/allow_unstable.rs b/compiler/rustc_attr/src/attributes/allow_unstable.rs new file mode 100644 index 00000000000..b9f841800ab --- /dev/null +++ b/compiler/rustc_attr/src/attributes/allow_unstable.rs @@ -0,0 +1,49 @@ +use rustc_ast::attr::{AttributeExt, filter_by_name}; +use rustc_session::Session; +use rustc_span::symbol::{Symbol, sym}; + +use crate::session_diagnostics; + +pub fn allow_internal_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], +) -> impl Iterator + 'a { + allow_unstable(sess, attrs, sym::allow_internal_unstable) +} + +pub fn rustc_allow_const_fn_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], +) -> impl Iterator + 'a { + allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) +} + +fn allow_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], + symbol: Symbol, +) -> impl Iterator + 'a { + let attrs = filter_by_name(attrs, symbol); + let list = attrs + .filter_map(move |attr| { + attr.meta_item_list().or_else(|| { + sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList { + span: attr.span(), + name: symbol.to_ident_string(), + }); + None + }) + }) + .flatten(); + + list.into_iter().filter_map(move |it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.dcx().emit_err(session_diagnostics::ExpectsFeatures { + span: it.span(), + name: symbol.to_ident_string(), + }); + } + name + }) +} diff --git a/compiler/rustc_attr/src/attributes/cfg.rs b/compiler/rustc_attr/src/attributes/cfg.rs new file mode 100644 index 00000000000..2dfdb2e61b4 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/cfg.rs @@ -0,0 +1,255 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; +use rustc_ast_pretty::pprust; +use rustc_feature::{Features, GatedCfg, find_gated_cfg}; +use rustc_session::RustcVersion; +use rustc_session::Session; +use rustc_session::config::ExpectedValues; +use rustc_session::lint::BuiltinLintDiag; +use rustc_session::lint::builtin::UNEXPECTED_CFGS; +use rustc_session::parse::feature_err; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, kw, sym}; + +use crate::{fluent_generated, parse_version}; +use crate::session_diagnostics; +use crate::util::UnsupportedLiteralReason; + +#[derive(Clone, Debug)] +pub struct Condition { + pub name: Symbol, + pub name_span: Span, + pub value: Option, + pub value_span: Option, + pub span: Span, +} + +/// Tests if a cfg-pattern matches the cfg set +pub fn cfg_matches( + cfg: &ast::MetaItemInner, + sess: &Session, + lint_node_id: NodeId, + features: Option<&Features>, +) -> bool { + eval_condition(cfg, sess, features, &mut |cfg| { + try_gate_cfg(cfg.name, cfg.span, sess, features); + match sess.psess.check_config.expecteds.get(&cfg.name) { + Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { + sess.psess.buffer_lint( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + BuiltinLintDiag::UnexpectedCfgValue( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), + ); + } + None if sess.psess.check_config.exhaustive_names => { + sess.psess.buffer_lint( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + BuiltinLintDiag::UnexpectedCfgName( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), + ); + } + _ => { /* not unexpected */ } + } + sess.psess.config.contains(&(cfg.name, cfg.value)) + }) +} + +fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { + let gate = find_gated_cfg(|sym| sym == name); + if let (Some(feats), Some(gated_cfg)) = (features, gate) { + gate_cfg(gated_cfg, span, sess, feats); + } +} + +#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable +fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { + let (cfg, feature, has_feature) = gated_cfg; + if !has_feature(features) && !cfg_span.allows_unstable(*feature) { + let explain = format!("`cfg({cfg})` is experimental and subject to change"); + feature_err(sess, *feature, cfg_span, explain).emit(); + } +} + +/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to +/// evaluate individual items. +pub fn eval_condition( + cfg: &ast::MetaItemInner, + sess: &Session, + features: Option<&Features>, + eval: &mut impl FnMut(Condition) -> bool, +) -> bool { + let dcx = sess.dcx(); + + let cfg = match cfg { + ast::MetaItemInner::MetaItem(meta_item) => meta_item, + ast::MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { + if let Some(features) = features { + // we can't use `try_gate_cfg` as symbols don't differentiate between `r#true` + // and `true`, and we want to keep the former working without feature gate + gate_cfg( + &( + if *b { kw::True } else { kw::False }, + sym::cfg_boolean_literals, + |features: &Features| features.cfg_boolean_literals(), + ), + cfg.span(), + sess, + features, + ); + } + return *b; + } + _ => { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: cfg.span(), + reason: UnsupportedLiteralReason::CfgBoolean, + is_bytestr: false, + start_point_span: sess.source_map().start_point(cfg.span()), + }); + return false; + } + }; + + match &cfg.kind { + ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => { + try_gate_cfg(sym::version, cfg.span, sess, features); + let (min_version, span) = match &mis[..] { + [MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => { + (sym, span) + } + [ + MetaItemInner::Lit(MetaItemLit { span, .. }) + | MetaItemInner::MetaItem(MetaItem { span, .. }), + ] => { + dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); + return false; + } + [..] => { + dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { + span: cfg.span, + }); + return false; + } + }; + let Some(min_version) = parse_version(*min_version) else { + dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); + return false; + }; + + // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details + if sess.psess.assume_incomplete_release { + RustcVersion::CURRENT > min_version + } else { + RustcVersion::CURRENT >= min_version + } + } + ast::MetaItemKind::List(mis) => { + for mi in mis.iter() { + if mi.meta_item_or_bool().is_none() { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: mi.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(mi.span()), + }); + return false; + } + } + + // The unwraps below may look dangerous, but we've already asserted + // that they won't fail with the loop above. + match cfg.name_or_empty() { + sym::any => mis + .iter() + // We don't use any() here, because we want to evaluate all cfg condition + // as eval_condition can (and does) extra checks + .fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)), + sym::all => mis + .iter() + // We don't use all() here, because we want to evaluate all cfg condition + // as eval_condition can (and does) extra checks + .fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)), + sym::not => { + let [mi] = mis.as_slice() else { + dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); + return false; + }; + + !eval_condition(mi, sess, features, eval) + } + sym::target => { + if let Some(features) = features + && !features.cfg_target_compact() + { + feature_err( + sess, + sym::cfg_target_compact, + cfg.span, + fluent_generated::attr_unstable_cfg_target_compact, + ) + .emit(); + } + + mis.iter().fold(true, |res, mi| { + let Some(mut mi) = mi.meta_item().cloned() else { + dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { + span: mi.span(), + }); + return false; + }; + + if let [seg, ..] = &mut mi.path.segments[..] { + seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); + } + + res & eval_condition( + &ast::MetaItemInner::MetaItem(mi), + sess, + features, + eval, + ) + }) + } + _ => { + dcx.emit_err(session_diagnostics::InvalidPredicate { + span: cfg.span, + predicate: pprust::path_to_string(&cfg.path), + }); + false + } + } + } + ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { + dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); + true + } + MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::CfgString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); + true + } + ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { + let ident = cfg.ident().expect("multi-segment cfg predicate"); + eval(Condition { + name: ident.name, + name_span: ident.span, + value: cfg.value_str(), + value_span: cfg.name_value_literal_span(), + span: cfg.span, + }) + } + } +} diff --git a/compiler/rustc_attr/src/attributes/confusables.rs b/compiler/rustc_attr/src/attributes/confusables.rs new file mode 100644 index 00000000000..988cb32f244 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/confusables.rs @@ -0,0 +1,22 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::attr::AttributeExt; +use rustc_ast::MetaItemInner; +use rustc_span::symbol::Symbol; + + +/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names. +pub fn parse_confusables(attr: &impl AttributeExt) -> Option> { + let metas = attr.meta_item_list()?; + + let mut candidates = Vec::new(); + + for meta in metas { + let MetaItemInner::Lit(meta_lit) = meta else { + return None; + }; + candidates.push(meta_lit.symbol); + } + + Some(candidates) +} diff --git a/compiler/rustc_attr/src/attributes/deprecation.rs b/compiler/rustc_attr/src/attributes/deprecation.rs new file mode 100644 index 00000000000..c7f13fef276 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/deprecation.rs @@ -0,0 +1,149 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::attr::AttributeExt; +use rustc_ast::{MetaItemInner, MetaItem}; +use rustc_ast_pretty::pprust; +use rustc_feature::Features; +use crate::types::{DeprecatedSince, Deprecation}; +use rustc_session::Session; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, sym}; +use crate::{parse_version, session_diagnostics}; + +use super::util::UnsupportedLiteralReason; + +/// Finds the deprecation attribute. `None` if none exists. +pub fn find_deprecation( + sess: &Session, + features: &Features, + attrs: &[impl AttributeExt], +) -> Option<(Deprecation, Span)> { + let mut depr: Option<(Deprecation, Span)> = None; + let is_rustc = features.staged_api(); + + 'outer: for attr in attrs { + if !attr.has_name(sym::deprecated) { + continue; + } + + let mut since = None; + let mut note = None; + let mut suggestion = None; + + if attr.is_doc_comment() { + continue; + } else if attr.is_word() { + } else if let Some(value) = attr.value_str() { + note = Some(value) + } else if let Some(list) = attr.meta_item_list() { + let get = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); + return false; + } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + if let Some(lit) = meta.name_value_literal() { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); + } else { + sess.dcx() + .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + } + false + } + }; + + for meta in &list { + match meta { + MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { + sym::since => { + if !get(mi, &mut since) { + continue 'outer; + } + } + sym::note => { + if !get(mi, &mut note) { + continue 'outer; + } + } + sym::suggestion => { + if !features.deprecated_suggestion() { + sess.dcx().emit_err( + session_diagnostics::DeprecatedItemSuggestion { + span: mi.span, + is_nightly: sess.is_nightly_build(), + details: (), + }, + ); + } + + if !get(mi, &mut suggestion) { + continue 'outer; + } + } + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: if features.deprecated_suggestion() { + &["since", "note", "suggestion"] + } else { + &["since", "note"] + }, + }); + continue 'outer; + } + }, + MetaItemInner::Lit(lit) => { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedKvPair, + is_bytestr: false, + start_point_span: sess.source_map().start_point(lit.span), + }); + continue 'outer; + } + } + } + } else { + continue; + } + + let since = if let Some(since) = since { + if since.as_str() == "TBD" { + DeprecatedSince::Future + } else if !is_rustc { + DeprecatedSince::NonStandard(since) + } else if let Some(version) = parse_version(since) { + DeprecatedSince::RustcVersion(version) + } else { + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); + DeprecatedSince::Err + } + } else if is_rustc { + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); + DeprecatedSince::Err + } else { + DeprecatedSince::Unspecified + }; + + if is_rustc && note.is_none() { + sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() }); + continue; + } + + depr = Some((Deprecation { since, note, suggestion }, attr.span())); + } + + depr +} diff --git a/compiler/rustc_attr/src/attributes/mod.rs b/compiler/rustc_attr/src/attributes/mod.rs new file mode 100644 index 00000000000..a78e0b54b64 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/mod.rs @@ -0,0 +1,17 @@ +mod allow_unstable; +mod cfg; +mod confusables; +mod deprecation; +mod repr; +mod stability; +mod transparency; + +pub mod util; + +pub use allow_unstable::*; +pub use cfg::*; +pub use confusables::*; +pub use deprecation::*; +pub use repr::*; +pub use stability::*; +pub use transparency::*; diff --git a/compiler/rustc_attr/src/attributes/repr.rs b/compiler/rustc_attr/src/attributes/repr.rs new file mode 100644 index 00000000000..803aeabaf18 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/repr.rs @@ -0,0 +1,216 @@ +//! Parsing and validation of builtin attributes + +use rustc_abi::Align; +use rustc_ast::attr::AttributeExt; +use rustc_ast::{self as ast, MetaItemKind}; +use crate::types::{ + IntType, ReprAttr::*, +}; +use crate::ReprAttr; +use rustc_session::Session; +use rustc_span::symbol::{Symbol, sym}; +use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; + + +/// Parse #[repr(...)] forms. +/// +/// Valid repr contents: any of the primitive integral type names (see +/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use +/// the same discriminant size that the corresponding C enum would or C +/// structure layout, `packed` to remove padding, and `transparent` to delegate representation +/// concerns to the only non-ZST field. +pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec { + if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() } +} + +pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec { + assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); + let mut acc = Vec::new(); + let dcx = sess.dcx(); + + if let Some(items) = attr.meta_item_list() { + for item in items { + let mut recognised = false; + if item.is_word() { + let hint = match item.name_or_empty() { + sym::Rust => Some(ReprRust), + sym::C => Some(ReprC), + sym::packed => Some(ReprPacked(Align::ONE)), + sym::simd => Some(ReprSimd), + sym::transparent => Some(ReprTransparent), + sym::align => { + sess.dcx().emit_err(session_diagnostics::InvalidReprAlignNeedArg { + span: item.span(), + }); + recognised = true; + None + } + name => int_type_of_word(name).map(ReprInt), + }; + + if let Some(h) = hint { + recognised = true; + acc.push(h); + } + } else if let Some((name, value)) = item.singleton_lit_list() { + let mut literal_error = None; + let mut err_span = item.span(); + if name == sym::align { + recognised = true; + match parse_alignment(&value.kind) { + Ok(literal) => acc.push(ReprAlign(literal)), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } + }; + } else if name == sym::packed { + recognised = true; + match parse_alignment(&value.kind) { + Ok(literal) => acc.push(ReprPacked(literal)), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } + }; + } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) + || int_type_of_word(name).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { + span: item.span(), + name: name.to_ident_string(), + }); + } + if let Some(literal_error) = literal_error { + sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric { + span: err_span, + repr_arg: name.to_ident_string(), + error_part: literal_error, + }); + } + } else if let Some(meta_item) = item.meta_item() { + match &meta_item.kind { + MetaItemKind::NameValue(value) => { + if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { + let name = meta_item.name_or_empty().to_ident_string(); + recognised = true; + sess.dcx().emit_err(session_diagnostics::IncorrectReprFormatGeneric { + span: item.span(), + repr_arg: &name, + cause: IncorrectReprFormatGenericCause::from_lit_kind( + item.span(), + &value.kind, + &name, + ), + }); + } else if matches!( + meta_item.name_or_empty(), + sym::Rust | sym::C | sym::simd | sym::transparent + ) || int_type_of_word(meta_item.name_or_empty()).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoValue { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); + } + } + MetaItemKind::List(nested_items) => { + if meta_item.has_name(sym::align) { + recognised = true; + if let [nested_item] = nested_items.as_slice() { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatExpectInteger { + span: nested_item.span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatAlignOneArg { + span: meta_item.span, + }, + ); + } + } else if meta_item.has_name(sym::packed) { + recognised = true; + if let [nested_item] = nested_items.as_slice() { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedExpectInteger { + span: nested_item.span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { + span: meta_item.span, + }, + ); + } + } else if matches!( + meta_item.name_or_empty(), + sym::Rust | sym::C | sym::simd | sym::transparent + ) || int_type_of_word(meta_item.name_or_empty()).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); + } + } + _ => (), + } + } + if !recognised { + // Not a word we recognize. This will be caught and reported by + // the `check_mod_attrs` pass, but this pass doesn't always run + // (e.g. if we only pretty-print the source), so we have to gate + // the `span_delayed_bug` call as follows: + if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) { + dcx.span_delayed_bug(item.span(), "unrecognized representation hint"); + } + } + } + } + acc +} + +fn int_type_of_word(s: Symbol) -> Option { + use crate::types::IntType::*; + + match s { + sym::i8 => Some(SignedInt(ast::IntTy::I8)), + sym::u8 => Some(UnsignedInt(ast::UintTy::U8)), + sym::i16 => Some(SignedInt(ast::IntTy::I16)), + sym::u16 => Some(UnsignedInt(ast::UintTy::U16)), + sym::i32 => Some(SignedInt(ast::IntTy::I32)), + sym::u32 => Some(UnsignedInt(ast::UintTy::U32)), + sym::i64 => Some(SignedInt(ast::IntTy::I64)), + sym::u64 => Some(UnsignedInt(ast::UintTy::U64)), + sym::i128 => Some(SignedInt(ast::IntTy::I128)), + sym::u128 => Some(UnsignedInt(ast::UintTy::U128)), + sym::isize => Some(SignedInt(ast::IntTy::Isize)), + sym::usize => Some(UnsignedInt(ast::UintTy::Usize)), + _ => None, + } +} + +pub fn parse_alignment(node: &ast::LitKind) -> Result { + if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { + // `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first + if literal.get().is_power_of_two() { + // Only possible error is larger than 2^29 + literal + .get() + .try_into() + .ok() + .and_then(|v| Align::from_bytes(v).ok()) + .ok_or("larger than 2^29") + } else { + Err("not a power of two") + } + } else { + Err("not an unsuffixed integer") + } +} diff --git a/compiler/rustc_attr/src/attributes/stability.rs b/compiler/rustc_attr/src/attributes/stability.rs new file mode 100644 index 00000000000..01f10d927a3 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/stability.rs @@ -0,0 +1,385 @@ +//! Parsing and validation of builtin attributes + +use std::num::NonZero; + +use rustc_ast::attr::AttributeExt; +use rustc_ast::MetaItem; +use rustc_ast_pretty::pprust; +use rustc_errors::ErrorGuaranteed; +use crate::types::{ + ConstStability, DefaultBodyStability, + Stability, StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, +}; +use rustc_session::Session; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, sym}; + +use crate::{parse_version, session_diagnostics}; +use crate::attributes::util::UnsupportedLiteralReason; + +/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. +pub fn find_stability( + sess: &Session, + attrs: &[impl AttributeExt], + item_sp: Span, +) -> Option<(Stability, Span)> { + let mut stab: Option<(Stability, Span)> = None; + let mut allowed_through_unstable_modules = false; + + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, + sym::unstable => { + if stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span())); + } + } + sym::stable => { + if stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span())); + } + } + _ => {} + } + } + + if allowed_through_unstable_modules { + match &mut stab { + Some(( + Stability { + level: StabilityLevel::Stable { allowed_through_unstable_modules, .. }, + .. + }, + _, + )) => *allowed_through_unstable_modules = true, + _ => { + sess.dcx() + .emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); + } + } + } + + stab +} + +/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. +pub fn find_const_stability( + sess: &Session, + attrs: &[impl AttributeExt], + item_sp: Span, +) -> Option<(ConstStability, Span)> { + let mut const_stab: Option<(ConstStability, Span)> = None; + let mut promotable = false; + let mut const_stable_indirect = false; + + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_promotable => promotable = true, + sym::rustc_const_stable_indirect => const_stable_indirect = true, + sym::rustc_const_unstable => { + if const_stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + const_stab = Some(( + ConstStability { + level, + feature, + const_stable_indirect: false, + promotable: false, + }, + attr.span(), + )); + } + } + sym::rustc_const_stable => { + if const_stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + const_stab = Some(( + ConstStability { + level, + feature, + const_stable_indirect: false, + promotable: false, + }, + attr.span(), + )); + } + } + _ => {} + } + } + + // Merge promotable and const_stable_indirect into stability info + if promotable { + match &mut const_stab { + Some((stab, _)) => stab.promotable = promotable, + _ => { + _ = sess + .dcx() + .emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }) + } + } + } + if const_stable_indirect { + match &mut const_stab { + Some((stab, _)) => { + if stab.is_const_unstable() { + stab.const_stable_indirect = true; + } else { + _ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing { + span: item_sp, + }) + } + } + _ => { + // This function has no const stability attribute, but has `const_stable_indirect`. + // We ignore that; unmarked functions are subject to recursive const stability + // checks by default so we do carry out the user's intent. + } + } + } + + const_stab +} + +/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate +/// without the `staged_api` feature. +pub fn unmarked_crate_const_stab( + _sess: &Session, + attrs: &[impl AttributeExt], + regular_stab: Stability, +) -> ConstStability { + assert!(regular_stab.level.is_unstable()); + // The only attribute that matters here is `rustc_const_stable_indirect`. + // We enforce recursive const stability rules for those functions. + let const_stable_indirect = + attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect); + ConstStability { + feature: regular_stab.feature, + const_stable_indirect, + promotable: false, + level: regular_stab.level, + } +} + +/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. +/// Returns `None` if no stability attributes are found. +pub fn find_body_stability( + sess: &Session, + attrs: &[impl AttributeExt], +) -> Option<(DefaultBodyStability, Span)> { + let mut body_stab: Option<(DefaultBodyStability, Span)> = None; + + for attr in attrs { + if attr.has_name(sym::rustc_default_body_unstable) { + if body_stab.is_some() { + sess.dcx() + .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + body_stab = Some((DefaultBodyStability { level, feature }, attr.span())); + } + } + } + + body_stab +} + +fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) -> Option<()> { + if item.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); + None + } else if let Some(v) = meta.value_str() { + *item = Some(v); + Some(()) + } else { + sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + None + } +} + +/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and +/// its stability information. +fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; + + let mut feature = None; + let mut since = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); + return None; + }; + + match mi.name_or_empty() { + sym::feature => insert_or_error(sess, mi, &mut feature)?, + sym::since => insert_or_error(sess, mi, &mut since)?, + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "since"], + }); + return None; + } + } + } + + let feature = match feature { + Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), + Some(_bad_feature) => { + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) + } + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), + }; + + let since = if let Some(since) = since { + if since.as_str() == VERSION_PLACEHOLDER { + StableSince::Current + } else if let Some(version) = parse_version(since) { + StableSince::Version(version) + } else { + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); + StableSince::Err + } + } else { + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); + StableSince::Err + }; + + match feature { + Ok(feature) => { + let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; + Some((feature, level)) + } + Err(ErrorGuaranteed { .. }) => None, + } +} + +/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` +/// attribute, and return the feature name and its stability information. +fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; + + let mut feature = None; + let mut reason = None; + let mut issue = None; + let mut issue_num = None; + let mut is_soft = false; + let mut implied_by = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); + return None; + }; + + match mi.name_or_empty() { + sym::feature => insert_or_error(sess, mi, &mut feature)?, + sym::reason => insert_or_error(sess, mi, &mut reason)?, + sym::issue => { + insert_or_error(sess, mi, &mut issue)?; + + // These unwraps are safe because `insert_or_error` ensures the meta item + // is a name/value pair string literal. + issue_num = match issue.unwrap().as_str() { + "none" => None, + issue => match issue.parse::>() { + Ok(num) => Some(num), + Err(err) => { + sess.dcx().emit_err( + session_diagnostics::InvalidIssueString { + span: mi.span, + cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( + mi.name_value_literal_span().unwrap(), + err.kind(), + ), + }, + ); + return None; + } + }, + }; + } + sym::soft => { + if !mi.is_word() { + sess.dcx().emit_err(session_diagnostics::SoftNoArgs { span: mi.span }); + } + is_soft = true; + } + sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?, + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "reason", "issue", "soft", "implied_by"], + }); + return None; + } + } + } + + let feature = match feature { + Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), + Some(_bad_feature) => { + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) + } + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), + }; + + let issue = issue.ok_or_else(|| { + sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() }) + }); + + match (feature, issue) { + (Ok(feature), Ok(_)) => { + let level = StabilityLevel::Unstable { + reason: UnstableReason::from_opt_reason(reason), + issue: issue_num, + is_soft, + implied_by, + }; + Some((feature, level)) + } + (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None, + } +} diff --git a/compiler/rustc_attr/src/attributes/transparency.rs b/compiler/rustc_attr/src/attributes/transparency.rs new file mode 100644 index 00000000000..4d37df58cb6 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/transparency.rs @@ -0,0 +1,35 @@ +use rustc_ast::attr::AttributeExt; +use crate::types::TransparencyError; +use rustc_span::{hygiene::Transparency, sym}; + +pub fn find_transparency( + attrs: &[impl AttributeExt], + macro_rules: bool, +) -> (Transparency, Option) { + let mut transparency = None; + let mut error = None; + for attr in attrs { + if attr.has_name(sym::rustc_macro_transparency) { + if let Some((_, old_span)) = transparency { + error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span())); + break; + } else if let Some(value) = attr.value_str() { + transparency = Some(( + match value { + sym::transparent => Transparency::Transparent, + sym::semitransparent => Transparency::SemiTransparent, + sym::opaque => Transparency::Opaque, + _ => { + error = + Some(TransparencyError::UnknownTransparency(value, attr.span())); + continue; + } + }, + attr.span(), + )); + } + } + } + let fallback = if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque }; + (transparency.map_or(fallback, |t| t.0), error) +} diff --git a/compiler/rustc_attr/src/attributes/util.rs b/compiler/rustc_attr/src/attributes/util.rs new file mode 100644 index 00000000000..8539a1370d2 --- /dev/null +++ b/compiler/rustc_attr/src/attributes/util.rs @@ -0,0 +1,36 @@ +use rustc_ast::attr::{AttributeExt, first_attr_value_str_by_name}; +use rustc_feature::is_builtin_attr_name; +use rustc_session::RustcVersion; +use rustc_span::symbol::{Symbol, sym}; + +pub(crate) enum UnsupportedLiteralReason { + Generic, + CfgString, + CfgBoolean, + DeprecatedString, + DeprecatedKvPair, +} + +pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { + attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) +} + +pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { + first_attr_value_str_by_name(attrs, sym::crate_name) +} + +/// Parse a rustc version number written inside string literal in an attribute, +/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are +/// not accepted in this position, unlike when parsing CFG_RELEASE. +pub fn parse_version(s: Symbol) -> Option { + let mut components = s.as_str().split('-'); + let d = components.next()?; + if components.next().is_some() { + return None; + } + let mut digits = d.splitn(3, '.'); + let major = digits.next()?.parse().ok()?; + let minor = digits.next()?.parse().ok()?; + let patch = digits.next().unwrap_or("0").parse().ok()?; + Some(RustcVersion { major, minor, patch }) +} diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs deleted file mode 100644 index d5ee03d2b68..00000000000 --- a/compiler/rustc_attr/src/builtin.rs +++ /dev/null @@ -1,1349 +0,0 @@ -//! Parsing and validation of builtin attributes - -use std::num::NonZero; - -use rustc_abi::Align; -use rustc_ast::attr::AttributeExt; -use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; -use rustc_ast_pretty::pprust; -use rustc_errors::ErrorGuaranteed; -use rustc_feature::{Features, GatedCfg, find_gated_cfg, is_builtin_attr_name}; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; -use rustc_session::config::ExpectedValues; -use rustc_session::lint::BuiltinLintDiag; -use rustc_session::lint::builtin::UNEXPECTED_CFGS; -use rustc_session::parse::feature_err; -use rustc_session::{RustcVersion, Session}; -use rustc_span::Span; -use rustc_span::hygiene::Transparency; -use rustc_span::symbol::{Symbol, kw, sym}; - -use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; -use crate::{filter_by_name, first_attr_value_str_by_name, fluent_generated}; - -/// The version placeholder that recently stabilized features contain inside the -/// `since` field of the `#[stable]` attribute. -/// -/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). -pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; - -pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { - attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) -} - -pub(crate) enum UnsupportedLiteralReason { - Generic, - CfgString, - CfgBoolean, - DeprecatedString, - DeprecatedKvPair, -} - -#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum InlineAttr { - None, - Hint, - Always, - Never, -} - -#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] -pub enum InstructionSetAttr { - ArmA32, - ArmT32, -} - -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum OptimizeAttr { - None, - Speed, - Size, -} - -/// Represents the following attributes: -/// -/// - `#[stable]` -/// - `#[unstable]` -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct Stability { - pub level: StabilityLevel, - pub feature: Symbol, -} - -impl Stability { - pub fn is_unstable(&self) -> bool { - self.level.is_unstable() - } - - pub fn is_stable(&self) -> bool { - self.level.is_stable() - } - - pub fn stable_since(&self) -> Option { - self.level.stable_since() - } -} - -/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct ConstStability { - pub level: StabilityLevel, - pub feature: Symbol, - /// This is true iff the `const_stable_indirect` attribute is present. - pub const_stable_indirect: bool, - /// whether the function has a `#[rustc_promotable]` attribute - pub promotable: bool, -} - -impl ConstStability { - pub fn is_const_unstable(&self) -> bool { - self.level.is_unstable() - } - - pub fn is_const_stable(&self) -> bool { - self.level.is_stable() - } -} - -/// Represents the `#[rustc_default_body_unstable]` attribute. -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct DefaultBodyStability { - pub level: StabilityLevel, - pub feature: Symbol, -} - -/// The available stability levels. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] -#[derive(HashStable_Generic)] -pub enum StabilityLevel { - /// `#[unstable]` - Unstable { - /// Reason for the current stability level. - reason: UnstableReason, - /// Relevant `rust-lang/rust` issue. - issue: Option>, - is_soft: bool, - /// If part of a feature is stabilized and a new feature is added for the remaining parts, - /// then the `implied_by` attribute is used to indicate which now-stable feature previously - /// contained an item. - /// - /// ```pseudo-Rust - /// #[unstable(feature = "foo", issue = "...")] - /// fn foo() {} - /// #[unstable(feature = "foo", issue = "...")] - /// fn foobar() {} - /// ``` - /// - /// ...becomes... - /// - /// ```pseudo-Rust - /// #[stable(feature = "foo", since = "1.XX.X")] - /// fn foo() {} - /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")] - /// fn foobar() {} - /// ``` - implied_by: Option, - }, - /// `#[stable]` - Stable { - /// Rust release which stabilized this feature. - since: StableSince, - /// Is this item allowed to be referred to on stable, despite being contained in unstable - /// modules? - allowed_through_unstable_modules: bool, - }, -} - -/// Rust release in which a feature is stabilized. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable_Generic)] -pub enum StableSince { - Version(RustcVersion), - /// Stabilized in the upcoming version, whatever number that is. - Current, - /// Failed to parse a stabilization version. - Err, -} - -impl StabilityLevel { - pub fn is_unstable(&self) -> bool { - matches!(self, StabilityLevel::Unstable { .. }) - } - pub fn is_stable(&self) -> bool { - matches!(self, StabilityLevel::Stable { .. }) - } - pub fn stable_since(&self) -> Option { - match *self { - StabilityLevel::Stable { since, .. } => Some(since), - StabilityLevel::Unstable { .. } => None, - } - } -} - -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] -#[derive(HashStable_Generic)] -pub enum UnstableReason { - None, - Default, - Some(Symbol), -} - -impl UnstableReason { - fn from_opt_reason(reason: Option) -> Self { - // UnstableReason::Default constructed manually - match reason { - Some(r) => Self::Some(r), - None => Self::None, - } - } - - pub fn to_opt_reason(&self) -> Option { - match self { - Self::None => None, - Self::Default => Some(sym::unstable_location_reason_default), - Self::Some(r) => Some(*r), - } - } -} - -/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. -pub fn find_stability( - sess: &Session, - attrs: &[impl AttributeExt], - item_sp: Span, -) -> Option<(Stability, Span)> { - let mut stab: Option<(Stability, Span)> = None; - let mut allowed_through_unstable_modules = false; - - for attr in attrs { - match attr.name_or_empty() { - sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, - sym::unstable => { - if stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span())); - } - } - sym::stable => { - if stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - if let Some((feature, level)) = parse_stability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span())); - } - } - _ => {} - } - } - - if allowed_through_unstable_modules { - match &mut stab { - Some(( - Stability { - level: StabilityLevel::Stable { allowed_through_unstable_modules, .. }, - .. - }, - _, - )) => *allowed_through_unstable_modules = true, - _ => { - sess.dcx() - .emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); - } - } - } - - stab -} - -/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. -pub fn find_const_stability( - sess: &Session, - attrs: &[impl AttributeExt], - item_sp: Span, -) -> Option<(ConstStability, Span)> { - let mut const_stab: Option<(ConstStability, Span)> = None; - let mut promotable = false; - let mut const_stable_indirect = false; - - for attr in attrs { - match attr.name_or_empty() { - sym::rustc_promotable => promotable = true, - sym::rustc_const_stable_indirect => const_stable_indirect = true, - sym::rustc_const_unstable => { - if const_stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - const_stab = Some(( - ConstStability { - level, - feature, - const_stable_indirect: false, - promotable: false, - }, - attr.span(), - )); - } - } - sym::rustc_const_stable => { - if const_stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - if let Some((feature, level)) = parse_stability(sess, attr) { - const_stab = Some(( - ConstStability { - level, - feature, - const_stable_indirect: false, - promotable: false, - }, - attr.span(), - )); - } - } - _ => {} - } - } - - // Merge promotable and const_stable_indirect into stability info - if promotable { - match &mut const_stab { - Some((stab, _)) => stab.promotable = promotable, - _ => { - _ = sess - .dcx() - .emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }) - } - } - } - if const_stable_indirect { - match &mut const_stab { - Some((stab, _)) => { - if stab.is_const_unstable() { - stab.const_stable_indirect = true; - } else { - _ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing { - span: item_sp, - }) - } - } - _ => { - // This function has no const stability attribute, but has `const_stable_indirect`. - // We ignore that; unmarked functions are subject to recursive const stability - // checks by default so we do carry out the user's intent. - } - } - } - - const_stab -} - -/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate -/// without the `staged_api` feature. -pub fn unmarked_crate_const_stab( - _sess: &Session, - attrs: &[impl AttributeExt], - regular_stab: Stability, -) -> ConstStability { - assert!(regular_stab.level.is_unstable()); - // The only attribute that matters here is `rustc_const_stable_indirect`. - // We enforce recursive const stability rules for those functions. - let const_stable_indirect = - attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect); - ConstStability { - feature: regular_stab.feature, - const_stable_indirect, - promotable: false, - level: regular_stab.level, - } -} - -/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. -/// Returns `None` if no stability attributes are found. -pub fn find_body_stability( - sess: &Session, - attrs: &[impl AttributeExt], -) -> Option<(DefaultBodyStability, Span)> { - let mut body_stab: Option<(DefaultBodyStability, Span)> = None; - - for attr in attrs { - if attr.has_name(sym::rustc_default_body_unstable) { - if body_stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - body_stab = Some((DefaultBodyStability { level, feature }, attr.span())); - } - } - } - - body_stab -} - -fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) -> Option<()> { - if item.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleItem { - span: meta.span, - item: pprust::path_to_string(&meta.path), - }); - None - } else if let Some(v) = meta.value_str() { - *item = Some(v); - Some(()) - } else { - sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); - None - } -} - -/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and -/// its stability information. -fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { - let metas = attr.meta_item_list()?; - - let mut feature = None; - let mut since = None; - for meta in metas { - let Some(mi) = meta.meta_item() else { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: meta.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(meta.span()), - }); - return None; - }; - - match mi.name_or_empty() { - sym::feature => insert_or_error(sess, mi, &mut feature)?, - sym::since => insert_or_error(sess, mi, &mut since)?, - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: &["feature", "since"], - }); - return None; - } - } - } - - let feature = match feature { - Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), - Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) - } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), - }; - - let since = if let Some(since) = since { - if since.as_str() == VERSION_PLACEHOLDER { - StableSince::Current - } else if let Some(version) = parse_version(since) { - StableSince::Version(version) - } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); - StableSince::Err - } - } else { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); - StableSince::Err - }; - - match feature { - Ok(feature) => { - let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; - Some((feature, level)) - } - Err(ErrorGuaranteed { .. }) => None, - } -} - -/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` -/// attribute, and return the feature name and its stability information. -fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { - let metas = attr.meta_item_list()?; - - let mut feature = None; - let mut reason = None; - let mut issue = None; - let mut issue_num = None; - let mut is_soft = false; - let mut implied_by = None; - for meta in metas { - let Some(mi) = meta.meta_item() else { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: meta.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(meta.span()), - }); - return None; - }; - - match mi.name_or_empty() { - sym::feature => insert_or_error(sess, mi, &mut feature)?, - sym::reason => insert_or_error(sess, mi, &mut reason)?, - sym::issue => { - insert_or_error(sess, mi, &mut issue)?; - - // These unwraps are safe because `insert_or_error` ensures the meta item - // is a name/value pair string literal. - issue_num = match issue.unwrap().as_str() { - "none" => None, - issue => match issue.parse::>() { - Ok(num) => Some(num), - Err(err) => { - sess.dcx().emit_err( - session_diagnostics::InvalidIssueString { - span: mi.span, - cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( - mi.name_value_literal_span().unwrap(), - err.kind(), - ), - }, - ); - return None; - } - }, - }; - } - sym::soft => { - if !mi.is_word() { - sess.dcx().emit_err(session_diagnostics::SoftNoArgs { span: mi.span }); - } - is_soft = true; - } - sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?, - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: &["feature", "reason", "issue", "soft", "implied_by"], - }); - return None; - } - } - } - - let feature = match feature { - Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), - Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) - } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), - }; - - let issue = issue.ok_or_else(|| { - sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() }) - }); - - match (feature, issue) { - (Ok(feature), Ok(_)) => { - let level = StabilityLevel::Unstable { - reason: UnstableReason::from_opt_reason(reason), - issue: issue_num, - is_soft, - implied_by, - }; - Some((feature, level)) - } - (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None, - } -} - -pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { - first_attr_value_str_by_name(attrs, sym::crate_name) -} - -#[derive(Clone, Debug)] -pub struct Condition { - pub name: Symbol, - pub name_span: Span, - pub value: Option, - pub value_span: Option, - pub span: Span, -} - -/// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches( - cfg: &ast::MetaItemInner, - sess: &Session, - lint_node_id: NodeId, - features: Option<&Features>, -) -> bool { - eval_condition(cfg, sess, features, &mut |cfg| { - try_gate_cfg(cfg.name, cfg.span, sess, features); - match sess.psess.check_config.expecteds.get(&cfg.name) { - Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { - sess.psess.buffer_lint( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - BuiltinLintDiag::UnexpectedCfgValue( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), - ); - } - None if sess.psess.check_config.exhaustive_names => { - sess.psess.buffer_lint( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - BuiltinLintDiag::UnexpectedCfgName( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), - ); - } - _ => { /* not unexpected */ } - } - sess.psess.config.contains(&(cfg.name, cfg.value)) - }) -} - -fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| sym == name); - if let (Some(feats), Some(gated_cfg)) = (features, gate) { - gate_cfg(gated_cfg, span, sess, feats); - } -} - -#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { - let (cfg, feature, has_feature) = gated_cfg; - if !has_feature(features) && !cfg_span.allows_unstable(*feature) { - let explain = format!("`cfg({cfg})` is experimental and subject to change"); - feature_err(sess, *feature, cfg_span, explain).emit(); - } -} - -/// Parse a rustc version number written inside string literal in an attribute, -/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are -/// not accepted in this position, unlike when parsing CFG_RELEASE. -pub fn parse_version(s: Symbol) -> Option { - let mut components = s.as_str().split('-'); - let d = components.next()?; - if components.next().is_some() { - return None; - } - let mut digits = d.splitn(3, '.'); - let major = digits.next()?.parse().ok()?; - let minor = digits.next()?.parse().ok()?; - let patch = digits.next().unwrap_or("0").parse().ok()?; - Some(RustcVersion { major, minor, patch }) -} - -/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to -/// evaluate individual items. -pub fn eval_condition( - cfg: &ast::MetaItemInner, - sess: &Session, - features: Option<&Features>, - eval: &mut impl FnMut(Condition) -> bool, -) -> bool { - let dcx = sess.dcx(); - - let cfg = match cfg { - ast::MetaItemInner::MetaItem(meta_item) => meta_item, - ast::MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { - if let Some(features) = features { - // we can't use `try_gate_cfg` as symbols don't differentiate between `r#true` - // and `true`, and we want to keep the former working without feature gate - gate_cfg( - &( - if *b { kw::True } else { kw::False }, - sym::cfg_boolean_literals, - |features: &Features| features.cfg_boolean_literals(), - ), - cfg.span(), - sess, - features, - ); - } - return *b; - } - _ => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: cfg.span(), - reason: UnsupportedLiteralReason::CfgBoolean, - is_bytestr: false, - start_point_span: sess.source_map().start_point(cfg.span()), - }); - return false; - } - }; - - match &cfg.kind { - ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => { - try_gate_cfg(sym::version, cfg.span, sess, features); - let (min_version, span) = match &mis[..] { - [MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => { - (sym, span) - } - [ - MetaItemInner::Lit(MetaItemLit { span, .. }) - | MetaItemInner::MetaItem(MetaItem { span, .. }), - ] => { - dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); - return false; - } - [..] => { - dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { - span: cfg.span, - }); - return false; - } - }; - let Some(min_version) = parse_version(*min_version) else { - dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); - return false; - }; - - // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details - if sess.psess.assume_incomplete_release { - RustcVersion::CURRENT > min_version - } else { - RustcVersion::CURRENT >= min_version - } - } - ast::MetaItemKind::List(mis) => { - for mi in mis.iter() { - if mi.meta_item_or_bool().is_none() { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: mi.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(mi.span()), - }); - return false; - } - } - - // The unwraps below may look dangerous, but we've already asserted - // that they won't fail with the loop above. - match cfg.name_or_empty() { - sym::any => mis - .iter() - // We don't use any() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)), - sym::all => mis - .iter() - // We don't use all() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)), - sym::not => { - let [mi] = mis.as_slice() else { - dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); - return false; - }; - - !eval_condition(mi, sess, features, eval) - } - sym::target => { - if let Some(features) = features - && !features.cfg_target_compact() - { - feature_err( - sess, - sym::cfg_target_compact, - cfg.span, - fluent_generated::attr_unstable_cfg_target_compact, - ) - .emit(); - } - - mis.iter().fold(true, |res, mi| { - let Some(mut mi) = mi.meta_item().cloned() else { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { - span: mi.span(), - }); - return false; - }; - - if let [seg, ..] = &mut mi.path.segments[..] { - seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); - } - - res & eval_condition( - &ast::MetaItemInner::MetaItem(mi), - sess, - features, - eval, - ) - }) - } - _ => { - dcx.emit_err(session_diagnostics::InvalidPredicate { - span: cfg.span, - predicate: pprust::path_to_string(&cfg.path), - }); - false - } - } - } - ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); - true - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::CfgString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - true - } - ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { - let ident = cfg.ident().expect("multi-segment cfg predicate"); - eval(Condition { - name: ident.name, - name_span: ident.span, - value: cfg.value_str(), - value_span: cfg.name_value_literal_span(), - span: cfg.span, - }) - } - } -} - -#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] -pub struct Deprecation { - pub since: DeprecatedSince, - /// The note to issue a reason. - pub note: Option, - /// A text snippet used to completely replace any use of the deprecated item in an expression. - /// - /// This is currently unstable. - pub suggestion: Option, -} - -/// Release in which an API is deprecated. -#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] -pub enum DeprecatedSince { - RustcVersion(RustcVersion), - /// Deprecated in the future ("to be determined"). - Future, - /// `feature(staged_api)` is off. Deprecation versions outside the standard - /// library are allowed to be arbitrary strings, for better or worse. - NonStandard(Symbol), - /// Deprecation version is unspecified but optional. - Unspecified, - /// Failed to parse a deprecation version, or the deprecation version is - /// unspecified and required. An error has already been emitted. - Err, -} - -impl Deprecation { - /// Whether an item marked with #[deprecated(since = "X")] is currently - /// deprecated (i.e., whether X is not greater than the current rustc - /// version). - pub fn is_in_effect(&self) -> bool { - match self.since { - DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT, - DeprecatedSince::Future => false, - // The `since` field doesn't have semantic purpose without `#![staged_api]`. - DeprecatedSince::NonStandard(_) => true, - // Assume deprecation is in effect if "since" field is absent or invalid. - DeprecatedSince::Unspecified | DeprecatedSince::Err => true, - } - } - - pub fn is_since_rustc_version(&self) -> bool { - matches!(self.since, DeprecatedSince::RustcVersion(_)) - } -} - -/// Finds the deprecation attribute. `None` if none exists. -pub fn find_deprecation( - sess: &Session, - features: &Features, - attrs: &[impl AttributeExt], -) -> Option<(Deprecation, Span)> { - let mut depr: Option<(Deprecation, Span)> = None; - let is_rustc = features.staged_api(); - - 'outer: for attr in attrs { - if !attr.has_name(sym::deprecated) { - continue; - } - - let mut since = None; - let mut note = None; - let mut suggestion = None; - - if attr.is_doc_comment() { - continue; - } else if attr.is_word() { - } else if let Some(value) = attr.value_str() { - note = Some(value) - } else if let Some(list) = attr.meta_item_list() { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleItem { - span: meta.span, - item: pprust::path_to_string(&meta.path), - }); - return false; - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true - } else { - if let Some(lit) = meta.name_value_literal() { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - } else { - sess.dcx() - .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); - } - false - } - }; - - for meta in &list { - match meta { - MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { - sym::since => { - if !get(mi, &mut since) { - continue 'outer; - } - } - sym::note => { - if !get(mi, &mut note) { - continue 'outer; - } - } - sym::suggestion => { - if !features.deprecated_suggestion() { - sess.dcx().emit_err( - session_diagnostics::DeprecatedItemSuggestion { - span: mi.span, - is_nightly: sess.is_nightly_build(), - details: (), - }, - ); - } - - if !get(mi, &mut suggestion) { - continue 'outer; - } - } - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: if features.deprecated_suggestion() { - &["since", "note", "suggestion"] - } else { - &["since", "note"] - }, - }); - continue 'outer; - } - }, - MetaItemInner::Lit(lit) => { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedKvPair, - is_bytestr: false, - start_point_span: sess.source_map().start_point(lit.span), - }); - continue 'outer; - } - } - } - } else { - continue; - } - - let since = if let Some(since) = since { - if since.as_str() == "TBD" { - DeprecatedSince::Future - } else if !is_rustc { - DeprecatedSince::NonStandard(since) - } else if let Some(version) = parse_version(since) { - DeprecatedSince::RustcVersion(version) - } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); - DeprecatedSince::Err - } - } else if is_rustc { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); - DeprecatedSince::Err - } else { - DeprecatedSince::Unspecified - }; - - if is_rustc && note.is_none() { - sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() }); - continue; - } - - depr = Some((Deprecation { since, note, suggestion }, attr.span())); - } - - depr -} - -#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)] -pub enum ReprAttr { - ReprInt(IntType), - ReprRust, - ReprC, - ReprPacked(Align), - ReprSimd, - ReprTransparent, - ReprAlign(Align), -} - -#[derive(Eq, PartialEq, Debug, Copy, Clone)] -#[derive(Encodable, Decodable, HashStable_Generic)] -pub enum IntType { - SignedInt(ast::IntTy), - UnsignedInt(ast::UintTy), -} - -impl IntType { - #[inline] - pub fn is_signed(self) -> bool { - use IntType::*; - - match self { - SignedInt(..) => true, - UnsignedInt(..) => false, - } - } -} - -/// Parse #[repr(...)] forms. -/// -/// Valid repr contents: any of the primitive integral type names (see -/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use -/// the same discriminant size that the corresponding C enum would or C -/// structure layout, `packed` to remove padding, and `transparent` to delegate representation -/// concerns to the only non-ZST field. -pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec { - if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() } -} - -pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec { - assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); - use ReprAttr::*; - let mut acc = Vec::new(); - let dcx = sess.dcx(); - - if let Some(items) = attr.meta_item_list() { - for item in items { - let mut recognised = false; - if item.is_word() { - let hint = match item.name_or_empty() { - sym::Rust => Some(ReprRust), - sym::C => Some(ReprC), - sym::packed => Some(ReprPacked(Align::ONE)), - sym::simd => Some(ReprSimd), - sym::transparent => Some(ReprTransparent), - sym::align => { - sess.dcx().emit_err(session_diagnostics::InvalidReprAlignNeedArg { - span: item.span(), - }); - recognised = true; - None - } - name => int_type_of_word(name).map(ReprInt), - }; - - if let Some(h) = hint { - recognised = true; - acc.push(h); - } - } else if let Some((name, value)) = item.singleton_lit_list() { - let mut literal_error = None; - let mut err_span = item.span(); - if name == sym::align { - recognised = true; - match parse_alignment(&value.kind) { - Ok(literal) => acc.push(ReprAlign(literal)), - Err(message) => { - err_span = value.span; - literal_error = Some(message) - } - }; - } else if name == sym::packed { - recognised = true; - match parse_alignment(&value.kind) { - Ok(literal) => acc.push(ReprPacked(literal)), - Err(message) => { - err_span = value.span; - literal_error = Some(message) - } - }; - } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) - || int_type_of_word(name).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { - span: item.span(), - name: name.to_ident_string(), - }); - } - if let Some(literal_error) = literal_error { - sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric { - span: err_span, - repr_arg: name.to_ident_string(), - error_part: literal_error, - }); - } - } else if let Some(meta_item) = item.meta_item() { - match &meta_item.kind { - MetaItemKind::NameValue(value) => { - if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { - let name = meta_item.name_or_empty().to_ident_string(); - recognised = true; - sess.dcx().emit_err(session_diagnostics::IncorrectReprFormatGeneric { - span: item.span(), - repr_arg: &name, - cause: IncorrectReprFormatGenericCause::from_lit_kind( - item.span(), - &value.kind, - &name, - ), - }); - } else if matches!( - meta_item.name_or_empty(), - sym::Rust | sym::C | sym::simd | sym::transparent - ) || int_type_of_word(meta_item.name_or_empty()).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoValue { - span: meta_item.span, - name: meta_item.name_or_empty().to_ident_string(), - }); - } - } - MetaItemKind::List(nested_items) => { - if meta_item.has_name(sym::align) { - recognised = true; - if let [nested_item] = nested_items.as_slice() { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatExpectInteger { - span: nested_item.span(), - }, - ); - } else { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatAlignOneArg { - span: meta_item.span, - }, - ); - } - } else if meta_item.has_name(sym::packed) { - recognised = true; - if let [nested_item] = nested_items.as_slice() { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatPackedExpectInteger { - span: nested_item.span(), - }, - ); - } else { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { - span: meta_item.span, - }, - ); - } - } else if matches!( - meta_item.name_or_empty(), - sym::Rust | sym::C | sym::simd | sym::transparent - ) || int_type_of_word(meta_item.name_or_empty()).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { - span: meta_item.span, - name: meta_item.name_or_empty().to_ident_string(), - }); - } - } - _ => (), - } - } - if !recognised { - // Not a word we recognize. This will be caught and reported by - // the `check_mod_attrs` pass, but this pass doesn't always run - // (e.g. if we only pretty-print the source), so we have to gate - // the `span_delayed_bug` call as follows: - if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) { - dcx.span_delayed_bug(item.span(), "unrecognized representation hint"); - } - } - } - } - acc -} - -fn int_type_of_word(s: Symbol) -> Option { - use IntType::*; - - match s { - sym::i8 => Some(SignedInt(ast::IntTy::I8)), - sym::u8 => Some(UnsignedInt(ast::UintTy::U8)), - sym::i16 => Some(SignedInt(ast::IntTy::I16)), - sym::u16 => Some(UnsignedInt(ast::UintTy::U16)), - sym::i32 => Some(SignedInt(ast::IntTy::I32)), - sym::u32 => Some(UnsignedInt(ast::UintTy::U32)), - sym::i64 => Some(SignedInt(ast::IntTy::I64)), - sym::u64 => Some(UnsignedInt(ast::UintTy::U64)), - sym::i128 => Some(SignedInt(ast::IntTy::I128)), - sym::u128 => Some(UnsignedInt(ast::UintTy::U128)), - sym::isize => Some(SignedInt(ast::IntTy::Isize)), - sym::usize => Some(UnsignedInt(ast::UintTy::Usize)), - _ => None, - } -} - -pub enum TransparencyError { - UnknownTransparency(Symbol, Span), - MultipleTransparencyAttrs(Span, Span), -} - -pub fn find_transparency( - attrs: &[impl AttributeExt], - macro_rules: bool, -) -> (Transparency, Option) { - let mut transparency = None; - let mut error = None; - for attr in attrs { - if attr.has_name(sym::rustc_macro_transparency) { - if let Some((_, old_span)) = transparency { - error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span())); - break; - } else if let Some(value) = attr.value_str() { - transparency = Some(( - match value { - sym::transparent => Transparency::Transparent, - sym::semitransparent => Transparency::SemiTransparent, - sym::opaque => Transparency::Opaque, - _ => { - error = - Some(TransparencyError::UnknownTransparency(value, attr.span())); - continue; - } - }, - attr.span(), - )); - } - } - } - let fallback = if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque }; - (transparency.map_or(fallback, |t| t.0), error) -} - -pub fn allow_internal_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { - allow_unstable(sess, attrs, sym::allow_internal_unstable) -} - -pub fn rustc_allow_const_fn_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { - allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) -} - -fn allow_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], - symbol: Symbol, -) -> impl Iterator + 'a { - let attrs = filter_by_name(attrs, symbol); - let list = attrs - .filter_map(move |attr| { - attr.meta_item_list().or_else(|| { - sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList { - span: attr.span(), - name: symbol.to_ident_string(), - }); - None - }) - }) - .flatten(); - - list.into_iter().filter_map(move |it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.dcx().emit_err(session_diagnostics::ExpectsFeatures { - span: it.span(), - name: symbol.to_ident_string(), - }); - } - name - }) -} - -pub fn parse_alignment(node: &ast::LitKind) -> Result { - if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { - // `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first - if literal.get().is_power_of_two() { - // Only possible error is larger than 2^29 - literal - .get() - .try_into() - .ok() - .and_then(|v| Align::from_bytes(v).ok()) - .ok_or("larger than 2^29") - } else { - Err("not a power of two") - } - } else { - Err("not an unsuffixed integer") - } -} - -/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names. -pub fn parse_confusables(attr: &impl AttributeExt) -> Option> { - let metas = attr.meta_item_list()?; - - let mut candidates = Vec::new(); - - for meta in metas { - let MetaItemInner::Lit(meta_lit) = meta else { - return None; - }; - candidates.push(meta_lit.symbol); - } - - Some(candidates) -} diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index bb207c5c952..d34ff02c7ed 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -1,8 +1,24 @@ -//! Functions and types dealing with attributes and meta items. +//! Centralized logic for parsing and validating all attributes used after HIR. //! -//! FIXME(Centril): For now being, much of the logic is still in `rustc_ast::attr`. -//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` -//! to this crate. +//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/131229). +//! There used to be only one definition of attributes in the compiler: `ast::Attribute`. +//! These were then parsed or validated or both in places distributed all over the compiler. +//! +//! Attributes are markers on items. Most are actually attribute-like proc-macros, and are expanded +//! but some remain as the built-in attributes to guide compilation. +//! +//! In this crate, syntactical attributes (sequences of tokens that look like +//! `#[something(something else)]`) are parsed into more semantic attributes, markers on items. +//! Multiple syntactic attributes might influence a single semantic attribute. For example, +//! `#[stable(...)]` and `#[unstable()]` cannot occur together, and both semantically define +//! a "stability". Stability defines an [`AttributeExtractor`](attributes::AttributeExtractor) +//! that recognizes both `#[stable()]` and `#[unstable()]` syntactic attributes, and at the end +//! produce a single [`ParsedAttributeKind::Stability`]. +//! +//! FIXME(jdonszelmann): update devguide for best practices on attributes +//! FIXME(jdonszelmann): rename to `rustc_attr` in the future, integrating it into this crate. +//! +//! To define a new builtin, first add it // tidy-alphabetical-start #![allow(internal_features)] @@ -12,14 +28,13 @@ #![warn(unreachable_pub)] // tidy-alphabetical-end -mod builtin; +mod attributes; mod session_diagnostics; +mod types; -pub use IntType::*; -pub use ReprAttr::*; -pub use StabilityLevel::*; -pub use builtin::*; -pub use rustc_ast::attr::*; +pub use attributes::*; pub(crate) use rustc_session::HashStableContext; +pub use types::*; +pub use util::{find_crate_name, is_builtin_attr, parse_version}; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 9d08a9f5754..245221e9729 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -6,7 +6,8 @@ use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuar use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; -use crate::{UnsupportedLiteralReason, fluent_generated as fluent}; +use crate::attributes::util::UnsupportedLiteralReason; +use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(attr_expected_one_cfg_pattern, code = E0536)] diff --git a/compiler/rustc_attr/src/types.rs b/compiler/rustc_attr/src/types.rs new file mode 100644 index 00000000000..243a70c0a21 --- /dev/null +++ b/compiler/rustc_attr/src/types.rs @@ -0,0 +1,262 @@ +use std::num::NonZero; + +use rustc_abi::Align; +use rustc_ast as ast; +use rustc_macros::{Encodable, Decodable, HashStable_Generic}; +use rustc_session::RustcVersion; +use rustc_span::{sym, Span, Symbol}; + +/// The version placeholder that recently stabilized features contain inside the +/// `since` field of the `#[stable]` attribute. +/// +/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). +pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum InlineAttr { + None, + Hint, + Always, + Never, +} + +#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] +pub enum InstructionSetAttr { + ArmA32, + ArmT32, +} + +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum OptimizeAttr { + None, + Speed, + Size, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub enum DiagnosticAttribute { + // tidy-alphabetical-start + DoNotRecommend, + OnUnimplemented, + // tidy-alphabetical-end +} + +#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)] +pub enum ReprAttr { + ReprInt(IntType), + ReprRust, + ReprC, + ReprPacked(Align), + ReprSimd, + ReprTransparent, + ReprAlign(Align), +} +pub use ReprAttr::*; + +pub enum TransparencyError { + UnknownTransparency(Symbol, Span), + MultipleTransparencyAttrs(Span, Span), +} + +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +#[derive(Encodable, Decodable)] +pub enum IntType { + SignedInt(ast::IntTy), + UnsignedInt(ast::UintTy), +} + +/// Represents the following attributes: +/// +/// - `#[stable]` +/// - `#[unstable]` +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct Stability { + pub level: StabilityLevel, + pub feature: Symbol, +} + +impl Stability { + pub fn is_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_stable(&self) -> bool { + self.level.is_stable() + } + + pub fn stable_since(&self) -> Option { + self.level.stable_since() + } +} + +/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct ConstStability { + pub level: StabilityLevel, + pub feature: Symbol, + /// This is true iff the `const_stable_indirect` attribute is present. + pub const_stable_indirect: bool, + /// whether the function has a `#[rustc_promotable]` attribute + pub promotable: bool, +} + +impl ConstStability { + pub fn is_const_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_const_stable(&self) -> bool { + self.level.is_stable() + } +} + +/// Represents the `#[rustc_default_body_unstable]` attribute. +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct DefaultBodyStability { + pub level: StabilityLevel, + pub feature: Symbol, +} + +/// The available stability levels. +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(HashStable_Generic)] +pub enum StabilityLevel { + /// `#[unstable]` + Unstable { + /// Reason for the current stability level. + reason: UnstableReason, + /// Relevant `rust-lang/rust` issue. + issue: Option>, + is_soft: bool, + /// If part of a feature is stabilized and a new feature is added for the remaining parts, + /// then the `implied_by` attribute is used to indicate which now-stable feature previously + /// contained an item. + /// + /// ```pseudo-Rust + /// #[unstable(feature = "foo", issue = "...")] + /// fn foo() {} + /// #[unstable(feature = "foo", issue = "...")] + /// fn foobar() {} + /// ``` + /// + /// ...becomes... + /// + /// ```pseudo-Rust + /// #[stable(feature = "foo", since = "1.XX.X")] + /// fn foo() {} + /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")] + /// fn foobar() {} + /// ``` + implied_by: Option, + }, + /// `#[stable]` + Stable { + /// Rust release which stabilized this feature. + since: StableSince, + /// Is this item allowed to be referred to on stable, despite being contained in unstable + /// modules? + allowed_through_unstable_modules: bool, + }, +} + +/// Rust release in which a feature is stabilized. +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] +#[derive(HashStable_Generic)] +pub enum StableSince { + Version(RustcVersion), + /// Stabilized in the upcoming version, whatever number that is. + Current, + /// Failed to parse a stabilization version. + Err, +} + +impl StabilityLevel { + pub fn is_unstable(&self) -> bool { + matches!(self, StabilityLevel::Unstable { .. }) + } + pub fn is_stable(&self) -> bool { + matches!(self, StabilityLevel::Stable { .. }) + } + pub fn stable_since(&self) -> Option { + match *self { + StabilityLevel::Stable { since, .. } => Some(since), + StabilityLevel::Unstable { .. } => None, + } + } +} + +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(HashStable_Generic)] +pub enum UnstableReason { + None, + Default, + Some(Symbol), +} + +impl UnstableReason { + pub(crate) fn from_opt_reason(reason: Option) -> Self { + // UnstableReason::Default constructed manually + match reason { + Some(r) => Self::Some(r), + None => Self::None, + } + } + + pub fn to_opt_reason(&self) -> Option { + match self { + Self::None => None, + Self::Default => Some(sym::unstable_location_reason_default), + Self::Some(r) => Some(*r), + } + } +} + +#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] +pub struct Deprecation { + pub since: DeprecatedSince, + /// The note to issue a reason. + pub note: Option, + /// A text snippet used to completely replace any use of the deprecated item in an expression. + /// + /// This is currently unstable. + pub suggestion: Option, +} + +/// Release in which an API is deprecated. +#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] +pub enum DeprecatedSince { + RustcVersion(RustcVersion), + /// Deprecated in the future ("to be determined"). + Future, + /// `feature(staged_api)` is off. Deprecation versions outside the standard + /// library are allowed to be arbitrary strings, for better or worse. + NonStandard(Symbol), + /// Deprecation version is unspecified but optional. + Unspecified, + /// Failed to parse a deprecation version, or the deprecation version is + /// unspecified and required. An error has already been emitted. + Err, +} + +impl Deprecation { + /// Whether an item marked with #[deprecated(since = "X")] is currently + /// deprecated (i.e., whether X is not greater than the current rustc + /// version). + pub fn is_in_effect(&self) -> bool { + match self.since { + DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT, + DeprecatedSince::Future => false, + // The `since` field doesn't have semantic purpose without `#![staged_api]`. + DeprecatedSince::NonStandard(_) => true, + // Assume deprecation is in effect if "since" field is absent or invalid. + DeprecatedSince::Unspecified | DeprecatedSince::Err => true, + } + } + + pub fn is_since_rustc_version(&self) -> bool { + matches!(self.since, DeprecatedSince::RustcVersion(_)) + } +} diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 27c9cb0b31e..828f82ddde3 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -5,7 +5,6 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name}; -use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::{Lrc, par_map}; @@ -31,6 +30,7 @@ use rustc_trait_selection::infer::at::ToTrace; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; +use {rustc_ast as ast, rustc_attr as attr}; use crate::assert_module_sources::CguReuse; use crate::back::link::are_upstream_rust_objects_already_included; @@ -873,7 +873,8 @@ impl CrateInfo { crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect(); let local_crate_name = tcx.crate_name(LOCAL_CRATE); let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); - let subsystem = attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); + let subsystem = + ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { tcx.dcx().emit_fatal(errors::InvalidWindowsSubsystem { subsystem }); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 5edd18bd3f4..c88b625060e 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,5 +1,6 @@ +use rustc_ast::attr::list_contains_name; use rustc_ast::{MetaItemInner, attr}; -use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name}; +use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 8e42afb60d8..9f2765718b5 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -809,7 +809,7 @@ impl SyntaxExtension { /// | yes | yes | yes | yes | yes | fn get_collapse_debuginfo(sess: &Session, attrs: &[impl AttributeExt], ext: bool) -> bool { let flag = sess.opts.cg.collapse_macro_debuginfo; - let attr = attr::find_by_name(attrs, sym::collapse_debuginfo) + let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo) .and_then(|attr| { Self::collapse_debuginfo_by_name(attr) .map_err(|span| { @@ -818,7 +818,7 @@ impl SyntaxExtension { .ok() }) .unwrap_or_else(|| { - if attr::contains_name(attrs, sym::rustc_builtin_macro) { + if ast::attr::contains_name(attrs, sym::rustc_builtin_macro) { CollapseMacroDebuginfo::Yes } else { CollapseMacroDebuginfo::Unspecified @@ -850,14 +850,14 @@ impl SyntaxExtension { let allow_internal_unstable = rustc_attr::allow_internal_unstable(sess, attrs).collect::>(); - let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe); - let local_inner_macros = attr::find_by_name(attrs, sym::macro_export) + let allow_internal_unsafe = ast::attr::contains_name(attrs, sym::allow_internal_unsafe); + let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export) .and_then(|macro_export| macro_export.meta_item_list()) - .is_some_and(|l| attr::list_contains_name(&l, sym::local_inner_macros)); + .is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros)); let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local); tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe); - let (builtin_name, helper_attrs) = attr::find_by_name(attrs, sym::rustc_builtin_macro) + let (builtin_name, helper_attrs) = ast::attr::find_by_name(attrs, sym::rustc_builtin_macro) .map(|attr| { // Override `helper_attrs` passed above if it's a built-in macro, // marking `proc_macro_derive` macros as built-in is not a realistic use case. diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index dc6aa110f45..12298d43b89 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -362,7 +362,7 @@ impl<'a> StripUnconfigured<'a> { )); let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees))); - let attr = attr::mk_attr_from_item( + let attr = ast::attr::mk_attr_from_item( &self.sess.psess.attr_id_generator, item, tokens, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index f7e3403cd28..c666078fa3b 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -3,13 +3,14 @@ use std::collections::hash_map::Entry; use std::{mem, slice}; use ast::token::IdentIsRaw; +use rustc_ast::attr::AttributeExt; use rustc_ast::token::NtPatKind::*; use rustc_ast::token::TokenKind::*; use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId}; use rustc_ast_pretty::pprust; -use rustc_attr::{self as attr, AttributeExt, TransparencyError}; +use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_feature::Features; diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7ea6c63dbe6..04099cd9001 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,5 +1,5 @@ +use rustc_ast::attr::AttributeExt; use rustc_ast_pretty::pprust; -use rustc_attr::AttributeExt; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::{Features, GateIssue}; diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index ff464b76c0d..7d1c8139518 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -342,8 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then( - |attr| { + ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) + .and_then(|attr| { if let AttrKind::Normal(n) = &attr.kind && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: ref lit }, .. } = n.as_ref() @@ -371,8 +371,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } else { None } - }, - ) + }) }; if let Some(ident) = &crate_ident { @@ -503,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { let attrs = cx.tcx.hir().attrs(it.hir_id()); match it.kind { - hir::ItemKind::Static(..) if !attr::contains_name(attrs, sym::no_mangle) => { + hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); } hir::ItemKind::Const(..) => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 92c0e8c3a50..88906d71597 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -710,15 +710,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE), has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), - has_default_lib_allocator: attr::contains_name(attrs, sym::default_lib_allocator), + has_default_lib_allocator: ast::attr::contains_name( + attrs, + sym::default_lib_allocator, + ), proc_macro_data, debugger_visualizers, - compiler_builtins: attr::contains_name(attrs, sym::compiler_builtins), - needs_allocator: attr::contains_name(attrs, sym::needs_allocator), - needs_panic_runtime: attr::contains_name(attrs, sym::needs_panic_runtime), - no_builtins: attr::contains_name(attrs, sym::no_builtins), - panic_runtime: attr::contains_name(attrs, sym::panic_runtime), - profiler_runtime: attr::contains_name(attrs, sym::profiler_runtime), + compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins), + needs_allocator: ast::attr::contains_name(attrs, sym::needs_allocator), + needs_panic_runtime: ast::attr::contains_name(attrs, sym::needs_panic_runtime), + no_builtins: ast::attr::contains_name(attrs, sym::no_builtins), + panic_runtime: ast::attr::contains_name(attrs, sym::panic_runtime), + profiler_runtime: ast::attr::contains_name(attrs, sym::profiler_runtime), symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(), crate_deps, @@ -1917,11 +1920,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. let attrs = hir.attrs(proc_macro); - let macro_kind = if attr::contains_name(attrs, sym::proc_macro) { + let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) { MacroKind::Bang - } else if attr::contains_name(attrs, sym::proc_macro_attribute) { + } else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) { MacroKind::Attr - } else if let Some(attr) = attr::find_by_name(attrs, sym::proc_macro_derive) { + } else if let Some(attr) = ast::attr::find_by_name(attrs, sym::proc_macro_derive) { // This unwrap chain should have been checked by the proc-macro harness. name = attr.meta_item_list().unwrap()[0] .meta_item() diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 94d13021612..eda53ce2e9f 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -392,7 +392,7 @@ impl<'tcx> TyCtxt<'tcx> { match stability { Some(Stability { - level: attr::Unstable { reason, issue, is_soft, implied_by }, + level: attr::StabilityLevel::Unstable { reason, issue, is_soft, implied_by }, feature, .. }) => { @@ -475,7 +475,7 @@ impl<'tcx> TyCtxt<'tcx> { match stability { Some(DefaultBodyStability { - level: attr::Unstable { reason, issue, is_soft, .. }, + level: attr::StabilityLevel::Unstable { reason, issue, is_soft, .. }, feature, }) => { if span.allows_unstable(feature) { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 2809ad453ff..72705b43d6f 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -6,7 +6,7 @@ use std::num::NonZero; use rustc_attr::{ self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince, - Unstable, UnstableReason, VERSION_PLACEHOLDER, + UnstableReason, VERSION_PLACEHOLDER, }; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; @@ -199,7 +199,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // this is *almost surely* an accident. if let ( &Some(DeprecatedSince::RustcVersion(dep_since)), - &attr::Stable { since: stab_since, .. }, + &attr::StabilityLevel::Stable { since: stab_since, .. }, ) = (&depr.as_ref().map(|(d, _)| d.since), &stab.level) { match stab_since { @@ -224,15 +224,17 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Stable *language* features shouldn't be used as unstable library features. // (Not doing this for stable library features is checked by tidy.) - if let Stability { level: Unstable { .. }, feature } = stab { + if let Stability { level: StabilityLevel::Unstable { .. }, feature } = stab { if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() { self.tcx .dcx() .emit_err(errors::UnstableAttrForAlreadyStableFeature { span, item_sp }); } } - if let Stability { level: Unstable { implied_by: Some(implied_by), .. }, feature } = - stab + if let Stability { + level: StabilityLevel::Unstable { implied_by: Some(implied_by), .. }, + feature, + } = stab { self.index.implications.insert(implied_by, feature); } @@ -278,8 +280,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Stable *language* features shouldn't be used as unstable library features. // (Not doing this for stable library features is checked by tidy.) - if let Some((ConstStability { level: Unstable { .. }, feature, .. }, const_span)) = - const_stab + if let Some(( + ConstStability { level: StabilityLevel::Unstable { .. }, feature, .. }, + const_span, + )) = const_stab { if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() { self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature { @@ -314,7 +318,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { }); if let Some(ConstStability { - level: Unstable { implied_by: Some(implied_by), .. }, + level: StabilityLevel::Unstable { implied_by: Some(implied_by), .. }, feature, .. }) = const_stab @@ -780,7 +784,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // error if all involved types and traits are stable, because // it will have no effect. // See: https://github.com/rust-lang/rust/issues/55436 - if let Some((Stability { level: attr::Unstable { .. }, .. }, span)) = stab { + if let Some(( + Stability { level: attr::StabilityLevel::Unstable { .. }, .. }, + span, + )) = stab + { let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true }; c.visit_ty(self_ty); c.visit_trait_ref(t); diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 924b8afa329..e18c7edec30 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -634,7 +634,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } ast::UseTreeKind::Glob => { let kind = ImportKind::Glob { - is_prelude: attr::contains_name(&item.attrs, sym::prelude_import), + is_prelude: ast::attr::contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(None), id, }; @@ -777,7 +777,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { expansion.to_expn_id(), item.span, parent.no_implicit_prelude - || attr::contains_name(&item.attrs, sym::no_implicit_prelude), + || ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude), ); self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); @@ -835,7 +835,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. let mut ctor_vis = if vis.is_public() - && attr::contains_name(&item.attrs, sym::non_exhaustive) + && ast::attr::contains_name(&item.attrs, sym::non_exhaustive) { ty::Visibility::Restricted(CRATE_DEF_ID) } else { @@ -1176,11 +1176,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { - if attr::contains_name(&item.attrs, sym::proc_macro) { + if ast::attr::contains_name(&item.attrs, sym::proc_macro) { return Some((MacroKind::Bang, item.ident, item.span)); - } else if attr::contains_name(&item.attrs, sym::proc_macro_attribute) { + } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) { return Some((MacroKind::Attr, item.ident, item.span)); - } else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { + } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) { if let Some(meta_item_inner) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { @@ -1233,7 +1233,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if macro_rules { let ident = ident.normalize_to_macros_2_0(); self.r.macro_names.insert(ident); - let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export); + let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export); let vis = if is_macro_export { ty::Visibility::Public } else { @@ -1507,7 +1507,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // If the variant is marked as non_exhaustive then lower the visibility to within the crate. let ctor_vis = - if vis.is_public() && attr::contains_name(&variant.attrs, sym::non_exhaustive) { + if vis.is_public() && ast::attr::contains_name(&variant.attrs, sym::non_exhaustive) { ty::Visibility::Restricted(CRATE_DEF_ID) } else { vis diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6e2af9aae23..891bc494d0c 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -4,10 +4,11 @@ use std::cell::Cell; use std::mem; +use rustc_ast::attr::AttributeExt; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr}; use rustc_ast_pretty::pprust; -use rustc_attr::{AttributeExt, StabilityLevel}; +use rustc_attr::StabilityLevel; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, StashKey}; diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 8b14fe31d8c..ed421da0241 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -5,8 +5,8 @@ use pulldown_cmark::{ BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag, }; use rustc_ast as ast; +use rustc_ast::attr::AttributeExt; use rustc_ast::util::comments::beautify_doc_string; -use rustc_attr::AttributeExt; use rustc_data_structures::fx::FxIndexMap; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9903d0faf43..9e52f6884a4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -55,7 +55,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds; use thin_vec::ThinVec; use tracing::{debug, instrument}; use utils::*; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_hir as hir}; pub(crate) use self::types::*; pub(crate) use self::utils::{krate, register_res, synthesize_auto_trait_and_blanket_impls}; @@ -2895,7 +2895,7 @@ fn clean_extern_crate<'tcx>( && attrs.iter().any(|a| { a.has_name(sym::doc) && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, sym::inline), + Some(l) => ast::attr::list_contains_name(&l, sym::inline), None => false, } }) @@ -3000,8 +3000,8 @@ fn clean_use_statement_inner<'tcx>( a.has_name(sym::doc) && match a.meta_item_list() { Some(l) => { - attr::list_contains_name(&l, sym::no_inline) - || attr::list_contains_name(&l, sym::hidden) + ast::attr::list_contains_name(&l, sym::no_inline) + || ast::attr::list_contains_name(&l, sym::hidden) } None => false, } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 617a7ab8097..8aeebdde7bb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -581,8 +581,7 @@ pub(crate) fn attrs_have_doc_flag<'a>( mut attrs: impl Iterator, flag: Symbol, ) -> bool { - attrs - .any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag))) + attrs.any(|attr| attr.meta_item_list().is_some_and(|l| ast::attr::list_contains_name(&l, flag))) } /// A link to `doc.rust-lang.org` that includes the channel name. Use this instead of manual links diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 5b1c3465d05..55986acea3d 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -1,4 +1,4 @@ -use rustc_attr::AttributeExt; +use rustc_ast::attr::AttributeExt; use rustc_attr::parse_version; use rustc_session::{RustcVersion, Session}; use rustc_span::{Symbol, sym}; -- cgit 1.4.1-3-g733a5 From efb98b6552abd00c58a2c1dd171b9086edf28214 Mon Sep 17 00:00:00 2001 From: Jonathan Dönszelmann Date: Fri, 13 Dec 2024 14:47:11 +0100 Subject: rename rustc_attr to rustc_attr_parsing and create rustc_attr_data_structures --- Cargo.lock | 59 ++- compiler/rustc_ast_passes/Cargo.toml | 2 +- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_attr/Cargo.toml | 20 - compiler/rustc_attr/messages.ftl | 124 ------ .../rustc_attr/src/attributes/allow_unstable.rs | 49 --- compiler/rustc_attr/src/attributes/cfg.rs | 255 ------------- compiler/rustc_attr/src/attributes/confusables.rs | 22 -- compiler/rustc_attr/src/attributes/deprecation.rs | 149 -------- compiler/rustc_attr/src/attributes/mod.rs | 17 - compiler/rustc_attr/src/attributes/repr.rs | 216 ----------- compiler/rustc_attr/src/attributes/stability.rs | 385 ------------------- compiler/rustc_attr/src/attributes/transparency.rs | 35 -- compiler/rustc_attr/src/attributes/util.rs | 36 -- compiler/rustc_attr/src/lib.rs | 40 -- compiler/rustc_attr/src/session_diagnostics.rs | 407 -------------------- compiler/rustc_attr/src/types.rs | 262 ------------- compiler/rustc_attr_data_structures/Cargo.toml | 20 + .../rustc_attr_data_structures/src/attributes.rs | 106 ++++++ compiler/rustc_attr_data_structures/src/lib.rs | 16 + .../rustc_attr_data_structures/src/stability.rs | 200 ++++++++++ compiler/rustc_attr_data_structures/src/version.rs | 21 ++ compiler/rustc_attr_parsing/Cargo.toml | 21 ++ compiler/rustc_attr_parsing/messages.ftl | 124 ++++++ .../src/attributes/allow_unstable.rs | 49 +++ compiler/rustc_attr_parsing/src/attributes/cfg.rs | 254 +++++++++++++ .../src/attributes/confusables.rs | 21 ++ .../src/attributes/deprecation.rs | 149 ++++++++ compiler/rustc_attr_parsing/src/attributes/mod.rs | 17 + compiler/rustc_attr_parsing/src/attributes/repr.rs | 215 +++++++++++ .../rustc_attr_parsing/src/attributes/stability.rs | 385 +++++++++++++++++++ .../src/attributes/transparency.rs | 36 ++ compiler/rustc_attr_parsing/src/attributes/util.rs | 36 ++ compiler/rustc_attr_parsing/src/lib.rs | 22 ++ .../rustc_attr_parsing/src/session_diagnostics.rs | 419 +++++++++++++++++++++ compiler/rustc_builtin_macros/Cargo.toml | 2 +- compiler/rustc_builtin_macros/src/cfg.rs | 2 +- .../src/deriving/coerce_pointee.rs | 2 +- .../src/deriving/generic/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/attributes.rs | 4 +- compiler/rustc_codegen_gcc/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/Cargo.toml | 2 +- compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_codegen_llvm/src/callee.rs | 2 +- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- .../rustc_codegen_ssa/src/back/symbol_export.rs | 3 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/naked_asm.rs | 2 +- compiler/rustc_codegen_ssa/src/target_features.rs | 2 +- compiler/rustc_const_eval/Cargo.toml | 2 +- .../rustc_const_eval/src/check_consts/check.rs | 2 +- compiler/rustc_const_eval/src/check_consts/mod.rs | 2 +- compiler/rustc_driver_impl/Cargo.toml | 2 +- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_expand/Cargo.toml | 2 +- compiler/rustc_expand/src/base.rs | 4 +- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- compiler/rustc_hir_analysis/Cargo.toml | 2 +- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_typeck/Cargo.toml | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_interface/Cargo.toml | 2 +- compiler/rustc_interface/src/util.rs | 2 +- compiler/rustc_lint/Cargo.toml | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 2 +- compiler/rustc_lint/src/types/literal.rs | 2 +- compiler/rustc_metadata/Cargo.toml | 2 +- compiler/rustc_metadata/src/native_libs.rs | 2 +- .../src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/Cargo.toml | 2 +- .../rustc_middle/src/middle/codegen_fn_attrs.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 2 +- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/query/erase.rs | 14 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/parameterized.rs | 8 +- compiler/rustc_mir_transform/Cargo.toml | 2 +- .../rustc_mir_transform/src/cross_crate_inline.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_monomorphize/Cargo.toml | 2 +- compiler/rustc_monomorphize/src/partitioning.rs | 5 +- compiler/rustc_passes/Cargo.toml | 2 +- compiler/rustc_passes/src/lib_features.rs | 2 +- compiler/rustc_passes/src/stability.rs | 2 +- compiler/rustc_privacy/Cargo.toml | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_resolve/Cargo.toml | 2 +- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/macros.rs | 2 +- compiler/rustc_session/src/lib.rs | 3 - compiler/rustc_session/src/version.rs | 29 -- compiler/rustc_trait_selection/Cargo.toml | 2 +- .../src/error_reporting/traits/on_unimplemented.rs | 2 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/render/mod.rs | 5 +- src/librustdoc/json/conversions.rs | 6 +- src/librustdoc/lib.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 2 +- src/tools/clippy/clippy_lints/src/approx_const.rs | 3 +- src/tools/clippy/clippy_lints/src/booleans.rs | 3 +- .../clippy/clippy_lints/src/incompatible_msrv.rs | 4 +- src/tools/clippy/clippy_lints/src/lib.rs | 2 +- .../clippy/clippy_lints/src/std_instead_of_core.rs | 2 +- .../utils/internal_lints/lint_without_lint_pass.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- src/tools/clippy/clippy_utils/src/msrvs.rs | 4 +- .../clippy_utils/src/qualify_min_const_fn.rs | 6 +- src/tools/miri/src/lib.rs | 2 +- src/tools/miri/src/machine.rs | 2 +- 117 files changed, 2257 insertions(+), 2171 deletions(-) delete mode 100644 compiler/rustc_attr/Cargo.toml delete mode 100644 compiler/rustc_attr/messages.ftl delete mode 100644 compiler/rustc_attr/src/attributes/allow_unstable.rs delete mode 100644 compiler/rustc_attr/src/attributes/cfg.rs delete mode 100644 compiler/rustc_attr/src/attributes/confusables.rs delete mode 100644 compiler/rustc_attr/src/attributes/deprecation.rs delete mode 100644 compiler/rustc_attr/src/attributes/mod.rs delete mode 100644 compiler/rustc_attr/src/attributes/repr.rs delete mode 100644 compiler/rustc_attr/src/attributes/stability.rs delete mode 100644 compiler/rustc_attr/src/attributes/transparency.rs delete mode 100644 compiler/rustc_attr/src/attributes/util.rs delete mode 100644 compiler/rustc_attr/src/lib.rs delete mode 100644 compiler/rustc_attr/src/session_diagnostics.rs delete mode 100644 compiler/rustc_attr/src/types.rs create mode 100644 compiler/rustc_attr_data_structures/Cargo.toml create mode 100644 compiler/rustc_attr_data_structures/src/attributes.rs create mode 100644 compiler/rustc_attr_data_structures/src/lib.rs create mode 100644 compiler/rustc_attr_data_structures/src/stability.rs create mode 100644 compiler/rustc_attr_data_structures/src/version.rs create mode 100644 compiler/rustc_attr_parsing/Cargo.toml create mode 100644 compiler/rustc_attr_parsing/messages.ftl create mode 100644 compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/cfg.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/confusables.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/deprecation.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/mod.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/repr.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/stability.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/transparency.rs create mode 100644 compiler/rustc_attr_parsing/src/attributes/util.rs create mode 100644 compiler/rustc_attr_parsing/src/lib.rs create mode 100644 compiler/rustc_attr_parsing/src/session_diagnostics.rs delete mode 100644 compiler/rustc_session/src/version.rs (limited to 'src/tools') diff --git a/Cargo.lock b/Cargo.lock index 5eeb855aacb..5a8f2e2f9ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3354,7 +3354,7 @@ dependencies = [ "itertools", "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3380,7 +3380,7 @@ dependencies = [ ] [[package]] -name = "rustc_attr" +name = "rustc_attr_data_structures" version = "0.0.0" dependencies = [ "rustc_abi", @@ -3397,6 +3397,25 @@ dependencies = [ "rustc_span", ] +[[package]] +name = "rustc_attr_parsing" +version = "0.0.0" +dependencies = [ + "rustc_abi", + "rustc_ast", + "rustc_ast_pretty", + "rustc_attr_data_structures", + "rustc_data_structures", + "rustc_errors", + "rustc_feature", + "rustc_fluent_macro", + "rustc_lexer", + "rustc_macros", + "rustc_serialize", + "rustc_session", + "rustc_span", +] + [[package]] name = "rustc_baked_icu_data" version = "0.0.0" @@ -3441,7 +3460,7 @@ version = "0.0.0" dependencies = [ "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -3473,7 +3492,7 @@ dependencies = [ "rustc-demangle", "rustc_abi", "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_codegen_ssa", "rustc_data_structures", "rustc_errors", @@ -3515,7 +3534,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -3553,7 +3572,7 @@ dependencies = [ "rustc_abi", "rustc_apfloat", "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -3620,7 +3639,7 @@ dependencies = [ "rustc_ast_lowering", "rustc_ast_passes", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_borrowck", "rustc_builtin_macros", "rustc_codegen_ssa", @@ -3724,7 +3743,7 @@ dependencies = [ "rustc_ast", "rustc_ast_passes", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3799,7 +3818,7 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3838,7 +3857,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_ir", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -3927,7 +3946,7 @@ dependencies = [ "rustc_ast_lowering", "rustc_ast_passes", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_borrowck", "rustc_builtin_macros", "rustc_codegen_llvm", @@ -3983,7 +4002,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -4057,7 +4076,7 @@ dependencies = [ "odht", "rustc_abi", "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -4094,7 +4113,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_ast_ir", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_error_messages", "rustc_errors", @@ -4173,7 +4192,7 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_const_eval", "rustc_data_structures", "rustc_errors", @@ -4199,7 +4218,7 @@ name = "rustc_monomorphize" version = "0.0.0" dependencies = [ "rustc_abi", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4267,7 +4286,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -4314,7 +4333,7 @@ name = "rustc_privacy" version = "0.0.0" dependencies = [ "rustc_ast", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4378,7 +4397,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_ast_pretty", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -4535,7 +4554,7 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_ir", - "rustc_attr", + "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index eace5ce8208..8046765647e 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" itertools = "0.12" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a42e3445c8d..3f071f5ecb5 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -342,7 +342,7 @@ impl<'a> AstValidator<'a> { sym::forbid, sym::warn, ]; - !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(*attr) + !arr.contains(&attr.name_or_empty()) && rustc_attr_parsing::is_builtin_attr(*attr) }) .for_each(|attr| { if attr.is_doc_comment() { diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml deleted file mode 100644 index 3b24452450a..00000000000 --- a/compiler/rustc_attr/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "rustc_attr" -version = "0.0.0" -edition = "2021" - -[dependencies] -# tidy-alphabetical-start -rustc_abi = { path = "../rustc_abi" } -rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_data_structures = { path = "../rustc_data_structures" } -rustc_errors = { path = "../rustc_errors" } -rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } -rustc_lexer = { path = "../rustc_lexer" } -rustc_macros = { path = "../rustc_macros" } -rustc_serialize = { path = "../rustc_serialize" } -rustc_session = { path = "../rustc_session" } -rustc_span = { path = "../rustc_span" } -# tidy-alphabetical-end diff --git a/compiler/rustc_attr/messages.ftl b/compiler/rustc_attr/messages.ftl deleted file mode 100644 index 235ab7572c4..00000000000 --- a/compiler/rustc_attr/messages.ftl +++ /dev/null @@ -1,124 +0,0 @@ -attr_cfg_predicate_identifier = - `cfg` predicate key must be an identifier - -attr_deprecated_item_suggestion = - suggestions on deprecated items are unstable - .help = add `#![feature(deprecated_suggestion)]` to the crate root - .note = see #94785 for more details - -attr_expected_one_cfg_pattern = - expected 1 cfg-pattern - -attr_expected_single_version_literal = - expected single version literal - -attr_expected_version_literal = - expected a version literal - -attr_expects_feature_list = - `{$name}` expects a list of feature names - -attr_expects_features = - `{$name}` expects feature names - -attr_incorrect_meta_item = - incorrect meta item - -attr_incorrect_repr_format_align_one_arg = - incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - -attr_incorrect_repr_format_expect_literal_integer = - incorrect `repr(align)` attribute format: `align` expects a literal integer as argument - -attr_incorrect_repr_format_generic = - incorrect `repr({$repr_arg})` attribute format - .suggestion = use parentheses instead - -attr_incorrect_repr_format_packed_expect_integer = - incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument - -attr_incorrect_repr_format_packed_one_or_zero_arg = - incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all - -attr_invalid_issue_string = - `issue` must be a non-zero numeric string or "none" - .must_not_be_zero = `issue` must not be "0", use "none" instead - .empty = cannot parse integer from empty string - .invalid_digit = invalid digit found in string - .pos_overflow = number too large to fit in target type - .neg_overflow = number too small to fit in target type - -attr_invalid_predicate = - invalid predicate `{$predicate}` - -attr_invalid_repr_align_need_arg = - invalid `repr(align)` attribute: `align` needs an argument - .suggestion = supply an argument here - -attr_invalid_repr_generic = - invalid `repr({$repr_arg})` attribute: {$error_part} - -attr_invalid_repr_hint_no_paren = - invalid representation hint: `{$name}` does not take a parenthesized argument list - -attr_invalid_repr_hint_no_value = - invalid representation hint: `{$name}` does not take a value - -attr_invalid_since = - 'since' must be a Rust version number, such as "1.31.0" - -attr_missing_feature = - missing 'feature' - -attr_missing_issue = - missing 'issue' - -attr_missing_note = - missing 'note' - -attr_missing_since = - missing 'since' - -attr_multiple_item = - multiple '{$item}' items - -attr_multiple_stability_levels = - multiple stability levels - -attr_non_ident_feature = - 'feature' is not an identifier - -attr_rustc_allowed_unstable_pairing = - `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute - -attr_rustc_const_stable_indirect_pairing = - `const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied - -attr_rustc_promotable_pairing = - `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute - -attr_soft_no_args = - `soft` should not have any arguments - -attr_unknown_meta_item = - unknown meta item '{$item}' - .label = expected one of {$expected} - -attr_unknown_version_literal = - unknown version literal format, assuming it refers to a future version - -attr_unstable_cfg_target_compact = - compact `cfg(target(..))` is experimental and subject to change - -attr_unsupported_literal_cfg_boolean = - literal in `cfg` predicate value must be a boolean -attr_unsupported_literal_cfg_string = - literal in `cfg` predicate value must be a string -attr_unsupported_literal_deprecated_kv_pair = - item in `deprecated` must be a key/value pair -attr_unsupported_literal_deprecated_string = - literal in `deprecated` value must be a string -attr_unsupported_literal_generic = - unsupported literal -attr_unsupported_literal_suggestion = - consider removing the prefix diff --git a/compiler/rustc_attr/src/attributes/allow_unstable.rs b/compiler/rustc_attr/src/attributes/allow_unstable.rs deleted file mode 100644 index b9f841800ab..00000000000 --- a/compiler/rustc_attr/src/attributes/allow_unstable.rs +++ /dev/null @@ -1,49 +0,0 @@ -use rustc_ast::attr::{AttributeExt, filter_by_name}; -use rustc_session::Session; -use rustc_span::symbol::{Symbol, sym}; - -use crate::session_diagnostics; - -pub fn allow_internal_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { - allow_unstable(sess, attrs, sym::allow_internal_unstable) -} - -pub fn rustc_allow_const_fn_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { - allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) -} - -fn allow_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], - symbol: Symbol, -) -> impl Iterator + 'a { - let attrs = filter_by_name(attrs, symbol); - let list = attrs - .filter_map(move |attr| { - attr.meta_item_list().or_else(|| { - sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList { - span: attr.span(), - name: symbol.to_ident_string(), - }); - None - }) - }) - .flatten(); - - list.into_iter().filter_map(move |it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.dcx().emit_err(session_diagnostics::ExpectsFeatures { - span: it.span(), - name: symbol.to_ident_string(), - }); - } - name - }) -} diff --git a/compiler/rustc_attr/src/attributes/cfg.rs b/compiler/rustc_attr/src/attributes/cfg.rs deleted file mode 100644 index 2dfdb2e61b4..00000000000 --- a/compiler/rustc_attr/src/attributes/cfg.rs +++ /dev/null @@ -1,255 +0,0 @@ -//! Parsing and validation of builtin attributes - -use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; -use rustc_ast_pretty::pprust; -use rustc_feature::{Features, GatedCfg, find_gated_cfg}; -use rustc_session::RustcVersion; -use rustc_session::Session; -use rustc_session::config::ExpectedValues; -use rustc_session::lint::BuiltinLintDiag; -use rustc_session::lint::builtin::UNEXPECTED_CFGS; -use rustc_session::parse::feature_err; -use rustc_span::Span; -use rustc_span::symbol::{Symbol, kw, sym}; - -use crate::{fluent_generated, parse_version}; -use crate::session_diagnostics; -use crate::util::UnsupportedLiteralReason; - -#[derive(Clone, Debug)] -pub struct Condition { - pub name: Symbol, - pub name_span: Span, - pub value: Option, - pub value_span: Option, - pub span: Span, -} - -/// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches( - cfg: &ast::MetaItemInner, - sess: &Session, - lint_node_id: NodeId, - features: Option<&Features>, -) -> bool { - eval_condition(cfg, sess, features, &mut |cfg| { - try_gate_cfg(cfg.name, cfg.span, sess, features); - match sess.psess.check_config.expecteds.get(&cfg.name) { - Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { - sess.psess.buffer_lint( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - BuiltinLintDiag::UnexpectedCfgValue( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), - ); - } - None if sess.psess.check_config.exhaustive_names => { - sess.psess.buffer_lint( - UNEXPECTED_CFGS, - cfg.span, - lint_node_id, - BuiltinLintDiag::UnexpectedCfgName( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), - ); - } - _ => { /* not unexpected */ } - } - sess.psess.config.contains(&(cfg.name, cfg.value)) - }) -} - -fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| sym == name); - if let (Some(feats), Some(gated_cfg)) = (features, gate) { - gate_cfg(gated_cfg, span, sess, feats); - } -} - -#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { - let (cfg, feature, has_feature) = gated_cfg; - if !has_feature(features) && !cfg_span.allows_unstable(*feature) { - let explain = format!("`cfg({cfg})` is experimental and subject to change"); - feature_err(sess, *feature, cfg_span, explain).emit(); - } -} - -/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to -/// evaluate individual items. -pub fn eval_condition( - cfg: &ast::MetaItemInner, - sess: &Session, - features: Option<&Features>, - eval: &mut impl FnMut(Condition) -> bool, -) -> bool { - let dcx = sess.dcx(); - - let cfg = match cfg { - ast::MetaItemInner::MetaItem(meta_item) => meta_item, - ast::MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { - if let Some(features) = features { - // we can't use `try_gate_cfg` as symbols don't differentiate between `r#true` - // and `true`, and we want to keep the former working without feature gate - gate_cfg( - &( - if *b { kw::True } else { kw::False }, - sym::cfg_boolean_literals, - |features: &Features| features.cfg_boolean_literals(), - ), - cfg.span(), - sess, - features, - ); - } - return *b; - } - _ => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: cfg.span(), - reason: UnsupportedLiteralReason::CfgBoolean, - is_bytestr: false, - start_point_span: sess.source_map().start_point(cfg.span()), - }); - return false; - } - }; - - match &cfg.kind { - ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => { - try_gate_cfg(sym::version, cfg.span, sess, features); - let (min_version, span) = match &mis[..] { - [MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => { - (sym, span) - } - [ - MetaItemInner::Lit(MetaItemLit { span, .. }) - | MetaItemInner::MetaItem(MetaItem { span, .. }), - ] => { - dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); - return false; - } - [..] => { - dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { - span: cfg.span, - }); - return false; - } - }; - let Some(min_version) = parse_version(*min_version) else { - dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); - return false; - }; - - // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details - if sess.psess.assume_incomplete_release { - RustcVersion::CURRENT > min_version - } else { - RustcVersion::CURRENT >= min_version - } - } - ast::MetaItemKind::List(mis) => { - for mi in mis.iter() { - if mi.meta_item_or_bool().is_none() { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: mi.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(mi.span()), - }); - return false; - } - } - - // The unwraps below may look dangerous, but we've already asserted - // that they won't fail with the loop above. - match cfg.name_or_empty() { - sym::any => mis - .iter() - // We don't use any() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)), - sym::all => mis - .iter() - // We don't use all() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)), - sym::not => { - let [mi] = mis.as_slice() else { - dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); - return false; - }; - - !eval_condition(mi, sess, features, eval) - } - sym::target => { - if let Some(features) = features - && !features.cfg_target_compact() - { - feature_err( - sess, - sym::cfg_target_compact, - cfg.span, - fluent_generated::attr_unstable_cfg_target_compact, - ) - .emit(); - } - - mis.iter().fold(true, |res, mi| { - let Some(mut mi) = mi.meta_item().cloned() else { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { - span: mi.span(), - }); - return false; - }; - - if let [seg, ..] = &mut mi.path.segments[..] { - seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); - } - - res & eval_condition( - &ast::MetaItemInner::MetaItem(mi), - sess, - features, - eval, - ) - }) - } - _ => { - dcx.emit_err(session_diagnostics::InvalidPredicate { - span: cfg.span, - predicate: pprust::path_to_string(&cfg.path), - }); - false - } - } - } - ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); - true - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::CfgString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - true - } - ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { - let ident = cfg.ident().expect("multi-segment cfg predicate"); - eval(Condition { - name: ident.name, - name_span: ident.span, - value: cfg.value_str(), - value_span: cfg.name_value_literal_span(), - span: cfg.span, - }) - } - } -} diff --git a/compiler/rustc_attr/src/attributes/confusables.rs b/compiler/rustc_attr/src/attributes/confusables.rs deleted file mode 100644 index 988cb32f244..00000000000 --- a/compiler/rustc_attr/src/attributes/confusables.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Parsing and validation of builtin attributes - -use rustc_ast::attr::AttributeExt; -use rustc_ast::MetaItemInner; -use rustc_span::symbol::Symbol; - - -/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names. -pub fn parse_confusables(attr: &impl AttributeExt) -> Option> { - let metas = attr.meta_item_list()?; - - let mut candidates = Vec::new(); - - for meta in metas { - let MetaItemInner::Lit(meta_lit) = meta else { - return None; - }; - candidates.push(meta_lit.symbol); - } - - Some(candidates) -} diff --git a/compiler/rustc_attr/src/attributes/deprecation.rs b/compiler/rustc_attr/src/attributes/deprecation.rs deleted file mode 100644 index c7f13fef276..00000000000 --- a/compiler/rustc_attr/src/attributes/deprecation.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Parsing and validation of builtin attributes - -use rustc_ast::attr::AttributeExt; -use rustc_ast::{MetaItemInner, MetaItem}; -use rustc_ast_pretty::pprust; -use rustc_feature::Features; -use crate::types::{DeprecatedSince, Deprecation}; -use rustc_session::Session; -use rustc_span::Span; -use rustc_span::symbol::{Symbol, sym}; -use crate::{parse_version, session_diagnostics}; - -use super::util::UnsupportedLiteralReason; - -/// Finds the deprecation attribute. `None` if none exists. -pub fn find_deprecation( - sess: &Session, - features: &Features, - attrs: &[impl AttributeExt], -) -> Option<(Deprecation, Span)> { - let mut depr: Option<(Deprecation, Span)> = None; - let is_rustc = features.staged_api(); - - 'outer: for attr in attrs { - if !attr.has_name(sym::deprecated) { - continue; - } - - let mut since = None; - let mut note = None; - let mut suggestion = None; - - if attr.is_doc_comment() { - continue; - } else if attr.is_word() { - } else if let Some(value) = attr.value_str() { - note = Some(value) - } else if let Some(list) = attr.meta_item_list() { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleItem { - span: meta.span, - item: pprust::path_to_string(&meta.path), - }); - return false; - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true - } else { - if let Some(lit) = meta.name_value_literal() { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - } else { - sess.dcx() - .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); - } - false - } - }; - - for meta in &list { - match meta { - MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { - sym::since => { - if !get(mi, &mut since) { - continue 'outer; - } - } - sym::note => { - if !get(mi, &mut note) { - continue 'outer; - } - } - sym::suggestion => { - if !features.deprecated_suggestion() { - sess.dcx().emit_err( - session_diagnostics::DeprecatedItemSuggestion { - span: mi.span, - is_nightly: sess.is_nightly_build(), - details: (), - }, - ); - } - - if !get(mi, &mut suggestion) { - continue 'outer; - } - } - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: if features.deprecated_suggestion() { - &["since", "note", "suggestion"] - } else { - &["since", "note"] - }, - }); - continue 'outer; - } - }, - MetaItemInner::Lit(lit) => { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::DeprecatedKvPair, - is_bytestr: false, - start_point_span: sess.source_map().start_point(lit.span), - }); - continue 'outer; - } - } - } - } else { - continue; - } - - let since = if let Some(since) = since { - if since.as_str() == "TBD" { - DeprecatedSince::Future - } else if !is_rustc { - DeprecatedSince::NonStandard(since) - } else if let Some(version) = parse_version(since) { - DeprecatedSince::RustcVersion(version) - } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); - DeprecatedSince::Err - } - } else if is_rustc { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); - DeprecatedSince::Err - } else { - DeprecatedSince::Unspecified - }; - - if is_rustc && note.is_none() { - sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() }); - continue; - } - - depr = Some((Deprecation { since, note, suggestion }, attr.span())); - } - - depr -} diff --git a/compiler/rustc_attr/src/attributes/mod.rs b/compiler/rustc_attr/src/attributes/mod.rs deleted file mode 100644 index a78e0b54b64..00000000000 --- a/compiler/rustc_attr/src/attributes/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod allow_unstable; -mod cfg; -mod confusables; -mod deprecation; -mod repr; -mod stability; -mod transparency; - -pub mod util; - -pub use allow_unstable::*; -pub use cfg::*; -pub use confusables::*; -pub use deprecation::*; -pub use repr::*; -pub use stability::*; -pub use transparency::*; diff --git a/compiler/rustc_attr/src/attributes/repr.rs b/compiler/rustc_attr/src/attributes/repr.rs deleted file mode 100644 index 803aeabaf18..00000000000 --- a/compiler/rustc_attr/src/attributes/repr.rs +++ /dev/null @@ -1,216 +0,0 @@ -//! Parsing and validation of builtin attributes - -use rustc_abi::Align; -use rustc_ast::attr::AttributeExt; -use rustc_ast::{self as ast, MetaItemKind}; -use crate::types::{ - IntType, ReprAttr::*, -}; -use crate::ReprAttr; -use rustc_session::Session; -use rustc_span::symbol::{Symbol, sym}; -use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; - - -/// Parse #[repr(...)] forms. -/// -/// Valid repr contents: any of the primitive integral type names (see -/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use -/// the same discriminant size that the corresponding C enum would or C -/// structure layout, `packed` to remove padding, and `transparent` to delegate representation -/// concerns to the only non-ZST field. -pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec { - if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() } -} - -pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec { - assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); - let mut acc = Vec::new(); - let dcx = sess.dcx(); - - if let Some(items) = attr.meta_item_list() { - for item in items { - let mut recognised = false; - if item.is_word() { - let hint = match item.name_or_empty() { - sym::Rust => Some(ReprRust), - sym::C => Some(ReprC), - sym::packed => Some(ReprPacked(Align::ONE)), - sym::simd => Some(ReprSimd), - sym::transparent => Some(ReprTransparent), - sym::align => { - sess.dcx().emit_err(session_diagnostics::InvalidReprAlignNeedArg { - span: item.span(), - }); - recognised = true; - None - } - name => int_type_of_word(name).map(ReprInt), - }; - - if let Some(h) = hint { - recognised = true; - acc.push(h); - } - } else if let Some((name, value)) = item.singleton_lit_list() { - let mut literal_error = None; - let mut err_span = item.span(); - if name == sym::align { - recognised = true; - match parse_alignment(&value.kind) { - Ok(literal) => acc.push(ReprAlign(literal)), - Err(message) => { - err_span = value.span; - literal_error = Some(message) - } - }; - } else if name == sym::packed { - recognised = true; - match parse_alignment(&value.kind) { - Ok(literal) => acc.push(ReprPacked(literal)), - Err(message) => { - err_span = value.span; - literal_error = Some(message) - } - }; - } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) - || int_type_of_word(name).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { - span: item.span(), - name: name.to_ident_string(), - }); - } - if let Some(literal_error) = literal_error { - sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric { - span: err_span, - repr_arg: name.to_ident_string(), - error_part: literal_error, - }); - } - } else if let Some(meta_item) = item.meta_item() { - match &meta_item.kind { - MetaItemKind::NameValue(value) => { - if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { - let name = meta_item.name_or_empty().to_ident_string(); - recognised = true; - sess.dcx().emit_err(session_diagnostics::IncorrectReprFormatGeneric { - span: item.span(), - repr_arg: &name, - cause: IncorrectReprFormatGenericCause::from_lit_kind( - item.span(), - &value.kind, - &name, - ), - }); - } else if matches!( - meta_item.name_or_empty(), - sym::Rust | sym::C | sym::simd | sym::transparent - ) || int_type_of_word(meta_item.name_or_empty()).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoValue { - span: meta_item.span, - name: meta_item.name_or_empty().to_ident_string(), - }); - } - } - MetaItemKind::List(nested_items) => { - if meta_item.has_name(sym::align) { - recognised = true; - if let [nested_item] = nested_items.as_slice() { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatExpectInteger { - span: nested_item.span(), - }, - ); - } else { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatAlignOneArg { - span: meta_item.span, - }, - ); - } - } else if meta_item.has_name(sym::packed) { - recognised = true; - if let [nested_item] = nested_items.as_slice() { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatPackedExpectInteger { - span: nested_item.span(), - }, - ); - } else { - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { - span: meta_item.span, - }, - ); - } - } else if matches!( - meta_item.name_or_empty(), - sym::Rust | sym::C | sym::simd | sym::transparent - ) || int_type_of_word(meta_item.name_or_empty()).is_some() - { - recognised = true; - sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { - span: meta_item.span, - name: meta_item.name_or_empty().to_ident_string(), - }); - } - } - _ => (), - } - } - if !recognised { - // Not a word we recognize. This will be caught and reported by - // the `check_mod_attrs` pass, but this pass doesn't always run - // (e.g. if we only pretty-print the source), so we have to gate - // the `span_delayed_bug` call as follows: - if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) { - dcx.span_delayed_bug(item.span(), "unrecognized representation hint"); - } - } - } - } - acc -} - -fn int_type_of_word(s: Symbol) -> Option { - use crate::types::IntType::*; - - match s { - sym::i8 => Some(SignedInt(ast::IntTy::I8)), - sym::u8 => Some(UnsignedInt(ast::UintTy::U8)), - sym::i16 => Some(SignedInt(ast::IntTy::I16)), - sym::u16 => Some(UnsignedInt(ast::UintTy::U16)), - sym::i32 => Some(SignedInt(ast::IntTy::I32)), - sym::u32 => Some(UnsignedInt(ast::UintTy::U32)), - sym::i64 => Some(SignedInt(ast::IntTy::I64)), - sym::u64 => Some(UnsignedInt(ast::UintTy::U64)), - sym::i128 => Some(SignedInt(ast::IntTy::I128)), - sym::u128 => Some(UnsignedInt(ast::UintTy::U128)), - sym::isize => Some(SignedInt(ast::IntTy::Isize)), - sym::usize => Some(UnsignedInt(ast::UintTy::Usize)), - _ => None, - } -} - -pub fn parse_alignment(node: &ast::LitKind) -> Result { - if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { - // `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first - if literal.get().is_power_of_two() { - // Only possible error is larger than 2^29 - literal - .get() - .try_into() - .ok() - .and_then(|v| Align::from_bytes(v).ok()) - .ok_or("larger than 2^29") - } else { - Err("not a power of two") - } - } else { - Err("not an unsuffixed integer") - } -} diff --git a/compiler/rustc_attr/src/attributes/stability.rs b/compiler/rustc_attr/src/attributes/stability.rs deleted file mode 100644 index 01f10d927a3..00000000000 --- a/compiler/rustc_attr/src/attributes/stability.rs +++ /dev/null @@ -1,385 +0,0 @@ -//! Parsing and validation of builtin attributes - -use std::num::NonZero; - -use rustc_ast::attr::AttributeExt; -use rustc_ast::MetaItem; -use rustc_ast_pretty::pprust; -use rustc_errors::ErrorGuaranteed; -use crate::types::{ - ConstStability, DefaultBodyStability, - Stability, StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, -}; -use rustc_session::Session; -use rustc_span::Span; -use rustc_span::symbol::{Symbol, sym}; - -use crate::{parse_version, session_diagnostics}; -use crate::attributes::util::UnsupportedLiteralReason; - -/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. -pub fn find_stability( - sess: &Session, - attrs: &[impl AttributeExt], - item_sp: Span, -) -> Option<(Stability, Span)> { - let mut stab: Option<(Stability, Span)> = None; - let mut allowed_through_unstable_modules = false; - - for attr in attrs { - match attr.name_or_empty() { - sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, - sym::unstable => { - if stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span())); - } - } - sym::stable => { - if stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - if let Some((feature, level)) = parse_stability(sess, attr) { - stab = Some((Stability { level, feature }, attr.span())); - } - } - _ => {} - } - } - - if allowed_through_unstable_modules { - match &mut stab { - Some(( - Stability { - level: StabilityLevel::Stable { allowed_through_unstable_modules, .. }, - .. - }, - _, - )) => *allowed_through_unstable_modules = true, - _ => { - sess.dcx() - .emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); - } - } - } - - stab -} - -/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. -pub fn find_const_stability( - sess: &Session, - attrs: &[impl AttributeExt], - item_sp: Span, -) -> Option<(ConstStability, Span)> { - let mut const_stab: Option<(ConstStability, Span)> = None; - let mut promotable = false; - let mut const_stable_indirect = false; - - for attr in attrs { - match attr.name_or_empty() { - sym::rustc_promotable => promotable = true, - sym::rustc_const_stable_indirect => const_stable_indirect = true, - sym::rustc_const_unstable => { - if const_stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - const_stab = Some(( - ConstStability { - level, - feature, - const_stable_indirect: false, - promotable: false, - }, - attr.span(), - )); - } - } - sym::rustc_const_stable => { - if const_stab.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { - span: attr.span(), - }); - break; - } - if let Some((feature, level)) = parse_stability(sess, attr) { - const_stab = Some(( - ConstStability { - level, - feature, - const_stable_indirect: false, - promotable: false, - }, - attr.span(), - )); - } - } - _ => {} - } - } - - // Merge promotable and const_stable_indirect into stability info - if promotable { - match &mut const_stab { - Some((stab, _)) => stab.promotable = promotable, - _ => { - _ = sess - .dcx() - .emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }) - } - } - } - if const_stable_indirect { - match &mut const_stab { - Some((stab, _)) => { - if stab.is_const_unstable() { - stab.const_stable_indirect = true; - } else { - _ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing { - span: item_sp, - }) - } - } - _ => { - // This function has no const stability attribute, but has `const_stable_indirect`. - // We ignore that; unmarked functions are subject to recursive const stability - // checks by default so we do carry out the user's intent. - } - } - } - - const_stab -} - -/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate -/// without the `staged_api` feature. -pub fn unmarked_crate_const_stab( - _sess: &Session, - attrs: &[impl AttributeExt], - regular_stab: Stability, -) -> ConstStability { - assert!(regular_stab.level.is_unstable()); - // The only attribute that matters here is `rustc_const_stable_indirect`. - // We enforce recursive const stability rules for those functions. - let const_stable_indirect = - attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect); - ConstStability { - feature: regular_stab.feature, - const_stable_indirect, - promotable: false, - level: regular_stab.level, - } -} - -/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. -/// Returns `None` if no stability attributes are found. -pub fn find_body_stability( - sess: &Session, - attrs: &[impl AttributeExt], -) -> Option<(DefaultBodyStability, Span)> { - let mut body_stab: Option<(DefaultBodyStability, Span)> = None; - - for attr in attrs { - if attr.has_name(sym::rustc_default_body_unstable) { - if body_stab.is_some() { - sess.dcx() - .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() }); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - body_stab = Some((DefaultBodyStability { level, feature }, attr.span())); - } - } - } - - body_stab -} - -fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) -> Option<()> { - if item.is_some() { - sess.dcx().emit_err(session_diagnostics::MultipleItem { - span: meta.span, - item: pprust::path_to_string(&meta.path), - }); - None - } else if let Some(v) = meta.value_str() { - *item = Some(v); - Some(()) - } else { - sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); - None - } -} - -/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and -/// its stability information. -fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { - let metas = attr.meta_item_list()?; - - let mut feature = None; - let mut since = None; - for meta in metas { - let Some(mi) = meta.meta_item() else { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: meta.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(meta.span()), - }); - return None; - }; - - match mi.name_or_empty() { - sym::feature => insert_or_error(sess, mi, &mut feature)?, - sym::since => insert_or_error(sess, mi, &mut since)?, - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: &["feature", "since"], - }); - return None; - } - } - } - - let feature = match feature { - Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), - Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) - } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), - }; - - let since = if let Some(since) = since { - if since.as_str() == VERSION_PLACEHOLDER { - StableSince::Current - } else if let Some(version) = parse_version(since) { - StableSince::Version(version) - } else { - sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); - StableSince::Err - } - } else { - sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); - StableSince::Err - }; - - match feature { - Ok(feature) => { - let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; - Some((feature, level)) - } - Err(ErrorGuaranteed { .. }) => None, - } -} - -/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` -/// attribute, and return the feature name and its stability information. -fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { - let metas = attr.meta_item_list()?; - - let mut feature = None; - let mut reason = None; - let mut issue = None; - let mut issue_num = None; - let mut is_soft = false; - let mut implied_by = None; - for meta in metas { - let Some(mi) = meta.meta_item() else { - sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { - span: meta.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(meta.span()), - }); - return None; - }; - - match mi.name_or_empty() { - sym::feature => insert_or_error(sess, mi, &mut feature)?, - sym::reason => insert_or_error(sess, mi, &mut reason)?, - sym::issue => { - insert_or_error(sess, mi, &mut issue)?; - - // These unwraps are safe because `insert_or_error` ensures the meta item - // is a name/value pair string literal. - issue_num = match issue.unwrap().as_str() { - "none" => None, - issue => match issue.parse::>() { - Ok(num) => Some(num), - Err(err) => { - sess.dcx().emit_err( - session_diagnostics::InvalidIssueString { - span: mi.span, - cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( - mi.name_value_literal_span().unwrap(), - err.kind(), - ), - }, - ); - return None; - } - }, - }; - } - sym::soft => { - if !mi.is_word() { - sess.dcx().emit_err(session_diagnostics::SoftNoArgs { span: mi.span }); - } - is_soft = true; - } - sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?, - _ => { - sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { - span: meta.span(), - item: pprust::path_to_string(&mi.path), - expected: &["feature", "reason", "issue", "soft", "implied_by"], - }); - return None; - } - } - } - - let feature = match feature { - Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), - Some(_bad_feature) => { - Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) - } - None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), - }; - - let issue = issue.ok_or_else(|| { - sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() }) - }); - - match (feature, issue) { - (Ok(feature), Ok(_)) => { - let level = StabilityLevel::Unstable { - reason: UnstableReason::from_opt_reason(reason), - issue: issue_num, - is_soft, - implied_by, - }; - Some((feature, level)) - } - (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None, - } -} diff --git a/compiler/rustc_attr/src/attributes/transparency.rs b/compiler/rustc_attr/src/attributes/transparency.rs deleted file mode 100644 index 4d37df58cb6..00000000000 --- a/compiler/rustc_attr/src/attributes/transparency.rs +++ /dev/null @@ -1,35 +0,0 @@ -use rustc_ast::attr::AttributeExt; -use crate::types::TransparencyError; -use rustc_span::{hygiene::Transparency, sym}; - -pub fn find_transparency( - attrs: &[impl AttributeExt], - macro_rules: bool, -) -> (Transparency, Option) { - let mut transparency = None; - let mut error = None; - for attr in attrs { - if attr.has_name(sym::rustc_macro_transparency) { - if let Some((_, old_span)) = transparency { - error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span())); - break; - } else if let Some(value) = attr.value_str() { - transparency = Some(( - match value { - sym::transparent => Transparency::Transparent, - sym::semitransparent => Transparency::SemiTransparent, - sym::opaque => Transparency::Opaque, - _ => { - error = - Some(TransparencyError::UnknownTransparency(value, attr.span())); - continue; - } - }, - attr.span(), - )); - } - } - } - let fallback = if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque }; - (transparency.map_or(fallback, |t| t.0), error) -} diff --git a/compiler/rustc_attr/src/attributes/util.rs b/compiler/rustc_attr/src/attributes/util.rs deleted file mode 100644 index 8539a1370d2..00000000000 --- a/compiler/rustc_attr/src/attributes/util.rs +++ /dev/null @@ -1,36 +0,0 @@ -use rustc_ast::attr::{AttributeExt, first_attr_value_str_by_name}; -use rustc_feature::is_builtin_attr_name; -use rustc_session::RustcVersion; -use rustc_span::symbol::{Symbol, sym}; - -pub(crate) enum UnsupportedLiteralReason { - Generic, - CfgString, - CfgBoolean, - DeprecatedString, - DeprecatedKvPair, -} - -pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { - attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) -} - -pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { - first_attr_value_str_by_name(attrs, sym::crate_name) -} - -/// Parse a rustc version number written inside string literal in an attribute, -/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are -/// not accepted in this position, unlike when parsing CFG_RELEASE. -pub fn parse_version(s: Symbol) -> Option { - let mut components = s.as_str().split('-'); - let d = components.next()?; - if components.next().is_some() { - return None; - } - let mut digits = d.splitn(3, '.'); - let major = digits.next()?.parse().ok()?; - let minor = digits.next()?.parse().ok()?; - let patch = digits.next().unwrap_or("0").parse().ok()?; - Some(RustcVersion { major, minor, patch }) -} diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs deleted file mode 100644 index d34ff02c7ed..00000000000 --- a/compiler/rustc_attr/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Centralized logic for parsing and validating all attributes used after HIR. -//! -//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/131229). -//! There used to be only one definition of attributes in the compiler: `ast::Attribute`. -//! These were then parsed or validated or both in places distributed all over the compiler. -//! -//! Attributes are markers on items. Most are actually attribute-like proc-macros, and are expanded -//! but some remain as the built-in attributes to guide compilation. -//! -//! In this crate, syntactical attributes (sequences of tokens that look like -//! `#[something(something else)]`) are parsed into more semantic attributes, markers on items. -//! Multiple syntactic attributes might influence a single semantic attribute. For example, -//! `#[stable(...)]` and `#[unstable()]` cannot occur together, and both semantically define -//! a "stability". Stability defines an [`AttributeExtractor`](attributes::AttributeExtractor) -//! that recognizes both `#[stable()]` and `#[unstable()]` syntactic attributes, and at the end -//! produce a single [`ParsedAttributeKind::Stability`]. -//! -//! FIXME(jdonszelmann): update devguide for best practices on attributes -//! FIXME(jdonszelmann): rename to `rustc_attr` in the future, integrating it into this crate. -//! -//! To define a new builtin, first add it - -// tidy-alphabetical-start -#![allow(internal_features)] -#![doc(rust_logo)] -#![feature(let_chains)] -#![feature(rustdoc_internals)] -#![warn(unreachable_pub)] -// tidy-alphabetical-end - -mod attributes; -mod session_diagnostics; -mod types; - -pub use attributes::*; -pub(crate) use rustc_session::HashStableContext; -pub use types::*; -pub use util::{find_crate_name, is_builtin_attr, parse_version}; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs deleted file mode 100644 index 245221e9729..00000000000 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ /dev/null @@ -1,407 +0,0 @@ -use std::num::IntErrorKind; - -use rustc_ast as ast; -use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; -use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_span::{Span, Symbol}; - -use crate::attributes::util::UnsupportedLiteralReason; -use crate::fluent_generated as fluent; - -#[derive(Diagnostic)] -#[diag(attr_expected_one_cfg_pattern, code = E0536)] -pub(crate) struct ExpectedOneCfgPattern { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_predicate, code = E0537)] -pub(crate) struct InvalidPredicate { - #[primary_span] - pub span: Span, - - pub predicate: String, -} - -#[derive(Diagnostic)] -#[diag(attr_multiple_item, code = E0538)] -pub(crate) struct MultipleItem { - #[primary_span] - pub span: Span, - - pub item: String, -} - -#[derive(Diagnostic)] -#[diag(attr_incorrect_meta_item, code = E0539)] -pub(crate) struct IncorrectMetaItem { - #[primary_span] - pub span: Span, -} - -/// Error code: E0541 -pub(crate) struct UnknownMetaItem<'a> { - pub span: Span, - pub item: String, - pub expected: &'a [&'a str], -} - -// Manual implementation to be able to format `expected` items correctly. -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); - Diag::new(dcx, level, fluent::attr_unknown_meta_item) - .with_span(self.span) - .with_code(E0541) - .with_arg("item", self.item) - .with_arg("expected", expected.join(", ")) - .with_span_label(self.span, fluent::attr_label) - } -} - -#[derive(Diagnostic)] -#[diag(attr_missing_since, code = E0542)] -pub(crate) struct MissingSince { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_missing_note, code = E0543)] -pub(crate) struct MissingNote { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_multiple_stability_levels, code = E0544)] -pub(crate) struct MultipleStabilityLevels { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_issue_string, code = E0545)] -pub(crate) struct InvalidIssueString { - #[primary_span] - pub span: Span, - - #[subdiagnostic] - pub cause: Option, -} - -// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be -// translatable. -#[derive(Subdiagnostic)] -pub(crate) enum InvalidIssueStringCause { - #[label(attr_must_not_be_zero)] - MustNotBeZero { - #[primary_span] - span: Span, - }, - - #[label(attr_empty)] - Empty { - #[primary_span] - span: Span, - }, - - #[label(attr_invalid_digit)] - InvalidDigit { - #[primary_span] - span: Span, - }, - - #[label(attr_pos_overflow)] - PosOverflow { - #[primary_span] - span: Span, - }, - - #[label(attr_neg_overflow)] - NegOverflow { - #[primary_span] - span: Span, - }, -} - -impl InvalidIssueStringCause { - pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option { - match kind { - IntErrorKind::Empty => Some(Self::Empty { span }), - IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }), - IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }), - IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }), - IntErrorKind::Zero => Some(Self::MustNotBeZero { span }), - _ => None, - } - } -} - -#[derive(Diagnostic)] -#[diag(attr_missing_feature, code = E0546)] -pub(crate) struct MissingFeature { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_non_ident_feature, code = E0546)] -pub(crate) struct NonIdentFeature { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_missing_issue, code = E0547)] -pub(crate) struct MissingIssue { - #[primary_span] - pub span: Span, -} - -// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? -// It is more similar to `IncorrectReprFormatGeneric`. -#[derive(Diagnostic)] -#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)] -pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { - #[primary_span] - pub span: Span, -} -#[derive(Diagnostic)] -#[diag(attr_incorrect_repr_format_packed_expect_integer, code = E0552)] -pub(crate) struct IncorrectReprFormatPackedExpectInteger { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_repr_hint_no_paren, code = E0552)] -pub(crate) struct InvalidReprHintNoParen { - #[primary_span] - pub span: Span, - - pub name: String, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_repr_hint_no_value, code = E0552)] -pub(crate) struct InvalidReprHintNoValue { - #[primary_span] - pub span: Span, - - pub name: String, -} - -/// Error code: E0565 -pub(crate) struct UnsupportedLiteral { - pub span: Span, - pub reason: UnsupportedLiteralReason, - pub is_bytestr: bool, - pub start_point_span: Span, -} - -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = Diag::new(dcx, level, match self.reason { - UnsupportedLiteralReason::Generic => fluent::attr_unsupported_literal_generic, - UnsupportedLiteralReason::CfgString => fluent::attr_unsupported_literal_cfg_string, - UnsupportedLiteralReason::CfgBoolean => fluent::attr_unsupported_literal_cfg_boolean, - UnsupportedLiteralReason::DeprecatedString => { - fluent::attr_unsupported_literal_deprecated_string - } - UnsupportedLiteralReason::DeprecatedKvPair => { - fluent::attr_unsupported_literal_deprecated_kv_pair - } - }); - diag.span(self.span); - diag.code(E0565); - if self.is_bytestr { - diag.span_suggestion( - self.start_point_span, - fluent::attr_unsupported_literal_suggestion, - "", - Applicability::MaybeIncorrect, - ); - } - diag - } -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_repr_align_need_arg, code = E0589)] -pub(crate) struct InvalidReprAlignNeedArg { - #[primary_span] - #[suggestion(code = "align(...)", applicability = "has-placeholders")] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_repr_generic, code = E0589)] -pub(crate) struct InvalidReprGeneric<'a> { - #[primary_span] - pub span: Span, - - pub repr_arg: String, - pub error_part: &'a str, -} - -#[derive(Diagnostic)] -#[diag(attr_incorrect_repr_format_align_one_arg, code = E0693)] -pub(crate) struct IncorrectReprFormatAlignOneArg { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_incorrect_repr_format_expect_literal_integer, code = E0693)] -pub(crate) struct IncorrectReprFormatExpectInteger { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_incorrect_repr_format_generic, code = E0693)] -pub(crate) struct IncorrectReprFormatGeneric<'a> { - #[primary_span] - pub span: Span, - - pub repr_arg: &'a str, - - #[subdiagnostic] - pub cause: Option>, -} - -#[derive(Subdiagnostic)] -pub(crate) enum IncorrectReprFormatGenericCause<'a> { - #[suggestion(attr_suggestion, code = "{name}({int})", applicability = "machine-applicable")] - Int { - #[primary_span] - span: Span, - - #[skip_arg] - name: &'a str, - - #[skip_arg] - int: u128, - }, - - #[suggestion(attr_suggestion, code = "{name}({symbol})", applicability = "machine-applicable")] - Symbol { - #[primary_span] - span: Span, - - #[skip_arg] - name: &'a str, - - #[skip_arg] - symbol: Symbol, - }, -} - -impl<'a> IncorrectReprFormatGenericCause<'a> { - pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { - match kind { - ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - Some(Self::Int { span, name, int: int.get() }) - } - ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }), - _ => None, - } - } -} - -#[derive(Diagnostic)] -#[diag(attr_rustc_promotable_pairing, code = E0717)] -pub(crate) struct RustcPromotablePairing { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_rustc_const_stable_indirect_pairing)] -pub(crate) struct RustcConstStableIndirectPairing { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_rustc_allowed_unstable_pairing, code = E0789)] -pub(crate) struct RustcAllowedUnstablePairing { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_cfg_predicate_identifier)] -pub(crate) struct CfgPredicateIdentifier { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_deprecated_item_suggestion)] -pub(crate) struct DeprecatedItemSuggestion { - #[primary_span] - pub span: Span, - - #[help] - pub is_nightly: bool, - - #[note] - pub details: (), -} - -#[derive(Diagnostic)] -#[diag(attr_expected_single_version_literal)] -pub(crate) struct ExpectedSingleVersionLiteral { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_expected_version_literal)] -pub(crate) struct ExpectedVersionLiteral { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_expects_feature_list)] -pub(crate) struct ExpectsFeatureList { - #[primary_span] - pub span: Span, - - pub name: String, -} - -#[derive(Diagnostic)] -#[diag(attr_expects_features)] -pub(crate) struct ExpectsFeatures { - #[primary_span] - pub span: Span, - - pub name: String, -} - -#[derive(Diagnostic)] -#[diag(attr_invalid_since)] -pub(crate) struct InvalidSince { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_soft_no_args)] -pub(crate) struct SoftNoArgs { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(attr_unknown_version_literal)] -pub(crate) struct UnknownVersionLiteral { - #[primary_span] - pub span: Span, -} diff --git a/compiler/rustc_attr/src/types.rs b/compiler/rustc_attr/src/types.rs deleted file mode 100644 index 243a70c0a21..00000000000 --- a/compiler/rustc_attr/src/types.rs +++ /dev/null @@ -1,262 +0,0 @@ -use std::num::NonZero; - -use rustc_abi::Align; -use rustc_ast as ast; -use rustc_macros::{Encodable, Decodable, HashStable_Generic}; -use rustc_session::RustcVersion; -use rustc_span::{sym, Span, Symbol}; - -/// The version placeholder that recently stabilized features contain inside the -/// `since` field of the `#[stable]` attribute. -/// -/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). -pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; - -#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum InlineAttr { - None, - Hint, - Always, - Never, -} - -#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] -pub enum InstructionSetAttr { - ArmA32, - ArmT32, -} - -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum OptimizeAttr { - None, - Speed, - Size, -} - -#[derive(Clone, Debug, Encodable, Decodable)] -pub enum DiagnosticAttribute { - // tidy-alphabetical-start - DoNotRecommend, - OnUnimplemented, - // tidy-alphabetical-end -} - -#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)] -pub enum ReprAttr { - ReprInt(IntType), - ReprRust, - ReprC, - ReprPacked(Align), - ReprSimd, - ReprTransparent, - ReprAlign(Align), -} -pub use ReprAttr::*; - -pub enum TransparencyError { - UnknownTransparency(Symbol, Span), - MultipleTransparencyAttrs(Span, Span), -} - -#[derive(Eq, PartialEq, Debug, Copy, Clone)] -#[derive(Encodable, Decodable)] -pub enum IntType { - SignedInt(ast::IntTy), - UnsignedInt(ast::UintTy), -} - -/// Represents the following attributes: -/// -/// - `#[stable]` -/// - `#[unstable]` -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct Stability { - pub level: StabilityLevel, - pub feature: Symbol, -} - -impl Stability { - pub fn is_unstable(&self) -> bool { - self.level.is_unstable() - } - - pub fn is_stable(&self) -> bool { - self.level.is_stable() - } - - pub fn stable_since(&self) -> Option { - self.level.stable_since() - } -} - -/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct ConstStability { - pub level: StabilityLevel, - pub feature: Symbol, - /// This is true iff the `const_stable_indirect` attribute is present. - pub const_stable_indirect: bool, - /// whether the function has a `#[rustc_promotable]` attribute - pub promotable: bool, -} - -impl ConstStability { - pub fn is_const_unstable(&self) -> bool { - self.level.is_unstable() - } - - pub fn is_const_stable(&self) -> bool { - self.level.is_stable() - } -} - -/// Represents the `#[rustc_default_body_unstable]` attribute. -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic)] -pub struct DefaultBodyStability { - pub level: StabilityLevel, - pub feature: Symbol, -} - -/// The available stability levels. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] -#[derive(HashStable_Generic)] -pub enum StabilityLevel { - /// `#[unstable]` - Unstable { - /// Reason for the current stability level. - reason: UnstableReason, - /// Relevant `rust-lang/rust` issue. - issue: Option>, - is_soft: bool, - /// If part of a feature is stabilized and a new feature is added for the remaining parts, - /// then the `implied_by` attribute is used to indicate which now-stable feature previously - /// contained an item. - /// - /// ```pseudo-Rust - /// #[unstable(feature = "foo", issue = "...")] - /// fn foo() {} - /// #[unstable(feature = "foo", issue = "...")] - /// fn foobar() {} - /// ``` - /// - /// ...becomes... - /// - /// ```pseudo-Rust - /// #[stable(feature = "foo", since = "1.XX.X")] - /// fn foo() {} - /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")] - /// fn foobar() {} - /// ``` - implied_by: Option, - }, - /// `#[stable]` - Stable { - /// Rust release which stabilized this feature. - since: StableSince, - /// Is this item allowed to be referred to on stable, despite being contained in unstable - /// modules? - allowed_through_unstable_modules: bool, - }, -} - -/// Rust release in which a feature is stabilized. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable_Generic)] -pub enum StableSince { - Version(RustcVersion), - /// Stabilized in the upcoming version, whatever number that is. - Current, - /// Failed to parse a stabilization version. - Err, -} - -impl StabilityLevel { - pub fn is_unstable(&self) -> bool { - matches!(self, StabilityLevel::Unstable { .. }) - } - pub fn is_stable(&self) -> bool { - matches!(self, StabilityLevel::Stable { .. }) - } - pub fn stable_since(&self) -> Option { - match *self { - StabilityLevel::Stable { since, .. } => Some(since), - StabilityLevel::Unstable { .. } => None, - } - } -} - -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] -#[derive(HashStable_Generic)] -pub enum UnstableReason { - None, - Default, - Some(Symbol), -} - -impl UnstableReason { - pub(crate) fn from_opt_reason(reason: Option) -> Self { - // UnstableReason::Default constructed manually - match reason { - Some(r) => Self::Some(r), - None => Self::None, - } - } - - pub fn to_opt_reason(&self) -> Option { - match self { - Self::None => None, - Self::Default => Some(sym::unstable_location_reason_default), - Self::Some(r) => Some(*r), - } - } -} - -#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] -pub struct Deprecation { - pub since: DeprecatedSince, - /// The note to issue a reason. - pub note: Option, - /// A text snippet used to completely replace any use of the deprecated item in an expression. - /// - /// This is currently unstable. - pub suggestion: Option, -} - -/// Release in which an API is deprecated. -#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] -pub enum DeprecatedSince { - RustcVersion(RustcVersion), - /// Deprecated in the future ("to be determined"). - Future, - /// `feature(staged_api)` is off. Deprecation versions outside the standard - /// library are allowed to be arbitrary strings, for better or worse. - NonStandard(Symbol), - /// Deprecation version is unspecified but optional. - Unspecified, - /// Failed to parse a deprecation version, or the deprecation version is - /// unspecified and required. An error has already been emitted. - Err, -} - -impl Deprecation { - /// Whether an item marked with #[deprecated(since = "X")] is currently - /// deprecated (i.e., whether X is not greater than the current rustc - /// version). - pub fn is_in_effect(&self) -> bool { - match self.since { - DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT, - DeprecatedSince::Future => false, - // The `since` field doesn't have semantic purpose without `#![staged_api]`. - DeprecatedSince::NonStandard(_) => true, - // Assume deprecation is in effect if "since" field is absent or invalid. - DeprecatedSince::Unspecified | DeprecatedSince::Err => true, - } - } - - pub fn is_since_rustc_version(&self) -> bool { - matches!(self.since, DeprecatedSince::RustcVersion(_)) - } -} diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml new file mode 100644 index 00000000000..2ee58f24470 --- /dev/null +++ b/compiler/rustc_attr_data_structures/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rustc_attr_data_structures" +version = "0.0.0" +edition = "2021" + +[dependencies] +# tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } +rustc_ast = { path = "../rustc_ast" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +# tidy-alphabetical-end diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs new file mode 100644 index 00000000000..8986bec57de --- /dev/null +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -0,0 +1,106 @@ +use rustc_abi::Align; +use rustc_ast as ast; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_span::{Span, Symbol}; + +use crate::RustcVersion; + +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum InlineAttr { + None, + Hint, + Always, + Never, +} + +#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] +pub enum InstructionSetAttr { + ArmA32, + ArmT32, +} + +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum OptimizeAttr { + None, + Speed, + Size, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub enum DiagnosticAttribute { + // tidy-alphabetical-start + DoNotRecommend, + OnUnimplemented, + // tidy-alphabetical-end +} + +#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)] +pub enum ReprAttr { + ReprInt(IntType), + ReprRust, + ReprC, + ReprPacked(Align), + ReprSimd, + ReprTransparent, + ReprAlign(Align), +} +pub use ReprAttr::*; + +pub enum TransparencyError { + UnknownTransparency(Symbol, Span), + MultipleTransparencyAttrs(Span, Span), +} + +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +#[derive(Encodable, Decodable)] +pub enum IntType { + SignedInt(ast::IntTy), + UnsignedInt(ast::UintTy), +} + +#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] +pub struct Deprecation { + pub since: DeprecatedSince, + /// The note to issue a reason. + pub note: Option, + /// A text snippet used to completely replace any use of the deprecated item in an expression. + /// + /// This is currently unstable. + pub suggestion: Option, +} + +/// Release in which an API is deprecated. +#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] +pub enum DeprecatedSince { + RustcVersion(RustcVersion), + /// Deprecated in the future ("to be determined"). + Future, + /// `feature(staged_api)` is off. Deprecation versions outside the standard + /// library are allowed to be arbitrary strings, for better or worse. + NonStandard(Symbol), + /// Deprecation version is unspecified but optional. + Unspecified, + /// Failed to parse a deprecation version, or the deprecation version is + /// unspecified and required. An error has already been emitted. + Err, +} + +impl Deprecation { + /// Whether an item marked with #[deprecated(since = "X")] is currently + /// deprecated (i.e., whether X is not greater than the current rustc + /// version). + pub fn is_in_effect(&self) -> bool { + match self.since { + DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT, + DeprecatedSince::Future => false, + // The `since` field doesn't have semantic purpose without `#![staged_api]`. + DeprecatedSince::NonStandard(_) => true, + // Assume deprecation is in effect if "since" field is absent or invalid. + DeprecatedSince::Unspecified | DeprecatedSince::Err => true, + } + } + + pub fn is_since_rustc_version(&self) -> bool { + matches!(self.since, DeprecatedSince::RustcVersion(_)) + } +} diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs new file mode 100644 index 00000000000..4f204aeab64 --- /dev/null +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -0,0 +1,16 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![doc(rust_logo)] +#![feature(let_chains)] +#![feature(rustdoc_internals)] +#![warn(unreachable_pub)] +// tidy-alphabetical-end + +mod attributes; +mod stability; +mod version; + +pub use attributes::*; +pub(crate) use rustc_session::HashStableContext; +pub use stability::*; +pub use version::*; diff --git a/compiler/rustc_attr_data_structures/src/stability.rs b/compiler/rustc_attr_data_structures/src/stability.rs new file mode 100644 index 00000000000..021fe40e3e0 --- /dev/null +++ b/compiler/rustc_attr_data_structures/src/stability.rs @@ -0,0 +1,200 @@ +use std::num::NonZero; + +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_span::{Symbol, sym}; + +use crate::RustcVersion; + +/// The version placeholder that recently stabilized features contain inside the +/// `since` field of the `#[stable]` attribute. +/// +/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). +pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + +/// Represents the following attributes: +/// +/// - `#[stable]` +/// - `#[unstable]` +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct Stability { + pub level: StabilityLevel, + pub feature: Symbol, +} + +impl Stability { + pub fn is_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_stable(&self) -> bool { + self.level.is_stable() + } + + pub fn stable_since(&self) -> Option { + self.level.stable_since() + } +} + +/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes. +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct ConstStability { + pub level: StabilityLevel, + pub feature: Symbol, + /// whether the function has a `#[rustc_promotable]` attribute + pub promotable: bool, + /// This is true iff the `const_stable_indirect` attribute is present. + pub const_stable_indirect: bool, +} + +impl ConstStability { + pub fn from_partial( + PartialConstStability { level, feature, promotable }: PartialConstStability, + const_stable_indirect: bool, + ) -> Self { + Self { const_stable_indirect, level, feature, promotable } + } + + /// The stability assigned to unmarked items when -Zforce-unstable-if-unmarked is set. + pub fn unmarked(const_stable_indirect: bool, regular_stab: Stability) -> Self { + Self { + feature: regular_stab.feature, + promotable: false, + level: regular_stab.level, + const_stable_indirect, + } + } + + pub fn is_const_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_const_stable(&self) -> bool { + self.level.is_stable() + } +} + +/// Excludes `const_stable_indirect`. This is necessary because when `-Zforce-unstable-if-unmarked` +/// is set, we need to encode standalone `#[rustc_const_stable_indirect]` attributes +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct PartialConstStability { + pub level: StabilityLevel, + pub feature: Symbol, + /// whether the function has a `#[rustc_promotable]` attribute + pub promotable: bool, +} + +impl PartialConstStability { + pub fn is_const_unstable(&self) -> bool { + self.level.is_unstable() + } + + pub fn is_const_stable(&self) -> bool { + self.level.is_stable() + } +} + +/// The available stability levels. +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(HashStable_Generic)] +pub enum StabilityLevel { + /// `#[unstable]` + Unstable { + /// Reason for the current stability level. + reason: UnstableReason, + /// Relevant `rust-lang/rust` issue. + issue: Option>, + is_soft: bool, + /// If part of a feature is stabilized and a new feature is added for the remaining parts, + /// then the `implied_by` attribute is used to indicate which now-stable feature previously + /// contained an item. + /// + /// ```pseudo-Rust + /// #[unstable(feature = "foo", issue = "...")] + /// fn foo() {} + /// #[unstable(feature = "foo", issue = "...")] + /// fn foobar() {} + /// ``` + /// + /// ...becomes... + /// + /// ```pseudo-Rust + /// #[stable(feature = "foo", since = "1.XX.X")] + /// fn foo() {} + /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")] + /// fn foobar() {} + /// ``` + implied_by: Option, + }, + /// `#[stable]` + Stable { + /// Rust release which stabilized this feature. + since: StableSince, + /// Is this item allowed to be referred to on stable, despite being contained in unstable + /// modules? + allowed_through_unstable_modules: bool, + }, +} + +/// Rust release in which a feature is stabilized. +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] +#[derive(HashStable_Generic)] +pub enum StableSince { + /// also stores the original symbol for printing + Version(RustcVersion), + /// Stabilized in the upcoming version, whatever number that is. + Current, + /// Failed to parse a stabilization version. + Err, +} + +impl StabilityLevel { + pub fn is_unstable(&self) -> bool { + matches!(self, StabilityLevel::Unstable { .. }) + } + pub fn is_stable(&self) -> bool { + matches!(self, StabilityLevel::Stable { .. }) + } + pub fn stable_since(&self) -> Option { + match *self { + StabilityLevel::Stable { since, .. } => Some(since), + StabilityLevel::Unstable { .. } => None, + } + } +} + +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(HashStable_Generic)] +pub enum UnstableReason { + None, + Default, + Some(Symbol), +} + +/// Represents the `#[rustc_default_body_unstable]` attribute. +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct DefaultBodyStability { + pub level: StabilityLevel, + pub feature: Symbol, +} + +impl UnstableReason { + pub fn from_opt_reason(reason: Option) -> Self { + // UnstableReason::Default constructed manually + match reason { + Some(r) => Self::Some(r), + None => Self::None, + } + } + + pub fn to_opt_reason(&self) -> Option { + match self { + Self::None => None, + Self::Default => Some(sym::unstable_location_reason_default), + Self::Some(r) => Some(*r), + } + } +} diff --git a/compiler/rustc_attr_data_structures/src/version.rs b/compiler/rustc_attr_data_structures/src/version.rs new file mode 100644 index 00000000000..6be875ad4be --- /dev/null +++ b/compiler/rustc_attr_data_structures/src/version.rs @@ -0,0 +1,21 @@ +use std::fmt::{self, Display}; + +use rustc_macros::{Decodable, Encodable, HashStable_Generic, current_rustc_version}; + +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(HashStable_Generic)] +pub struct RustcVersion { + pub major: u16, + pub minor: u16, + pub patch: u16, +} + +impl RustcVersion { + pub const CURRENT: Self = current_rustc_version!(); +} + +impl Display for RustcVersion { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) + } +} diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml new file mode 100644 index 00000000000..7ccedf40c3f --- /dev/null +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "rustc_attr_parsing" +version = "0.0.0" +edition = "2021" + +[dependencies] +# tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } +rustc_ast = { path = "../rustc_ast" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +# tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl new file mode 100644 index 00000000000..faa2865cb91 --- /dev/null +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -0,0 +1,124 @@ +attr_parsing_cfg_predicate_identifier = + `cfg` predicate key must be an identifier + +attr_parsing_deprecated_item_suggestion = + suggestions on deprecated items are unstable + .help = add `#![feature(deprecated_suggestion)]` to the crate root + .note = see #94785 for more details + +attr_parsing_expected_one_cfg_pattern = + expected 1 cfg-pattern + +attr_parsing_expected_single_version_literal = + expected single version literal + +attr_parsing_expected_version_literal = + expected a version literal + +attr_parsing_expects_feature_list = + `{$name}` expects a list of feature names + +attr_parsing_expects_features = + `{$name}` expects feature names + +attr_parsing_incorrect_meta_item = + incorrect meta item + +attr_parsing_incorrect_repr_format_align_one_arg = + incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + +attr_parsing_incorrect_repr_format_expect_literal_integer = + incorrect `repr(align)` attribute format: `align` expects a literal integer as argument + +attr_parsing_incorrect_repr_format_generic = + incorrect `repr({$repr_arg})` attribute format + .suggestion = use parentheses instead + +attr_parsing_incorrect_repr_format_packed_expect_integer = + incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument + +attr_parsing_incorrect_repr_format_packed_one_or_zero_arg = + incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all + +attr_parsing_invalid_issue_string = + `issue` must be a non-zero numeric string or "none" + .must_not_be_zero = `issue` must not be "0", use "none" instead + .empty = cannot parse integer from empty string + .invalid_digit = invalid digit found in string + .pos_overflow = number too large to fit in target type + .neg_overflow = number too small to fit in target type + +attr_parsing_invalid_predicate = + invalid predicate `{$predicate}` + +attr_parsing_invalid_repr_align_need_arg = + invalid `repr(align)` attribute: `align` needs an argument + .suggestion = supply an argument here + +attr_parsing_invalid_repr_generic = + invalid `repr({$repr_arg})` attribute: {$error_part} + +attr_parsing_invalid_repr_hint_no_paren = + invalid representation hint: `{$name}` does not take a parenthesized argument list + +attr_parsing_invalid_repr_hint_no_value = + invalid representation hint: `{$name}` does not take a value + +attr_parsing_invalid_since = + 'since' must be a Rust version number, such as "1.31.0" + +attr_parsing_missing_feature = + missing 'feature' + +attr_parsing_missing_issue = + missing 'issue' + +attr_parsing_missing_note = + missing 'note' + +attr_parsing_missing_since = + missing 'since' + +attr_parsing_multiple_item = + multiple '{$item}' items + +attr_parsing_multiple_stability_levels = + multiple stability levels + +attr_parsing_non_ident_feature = + 'feature' is not an identifier + +attr_parsing_rustc_allowed_unstable_pairing = + `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute + +attr_parsing_rustc_const_stable_indirect_pairing = + `const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied + +attr_parsing_rustc_promotable_pairing = + `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute + +attr_parsing_soft_no_args = + `soft` should not have any arguments + +attr_parsing_unknown_meta_item = + unknown meta item '{$item}' + .label = expected one of {$expected} + +attr_parsing_unknown_version_literal = + unknown version literal format, assuming it refers to a future version + +attr_parsing_unstable_cfg_target_compact = + compact `cfg(target(..))` is experimental and subject to change + +attr_parsing_unsupported_literal_cfg_boolean = + literal in `cfg` predicate value must be a boolean +attr_parsing_unsupported_literal_cfg_string = + literal in `cfg` predicate value must be a string +attr_parsing_unsupported_literal_deprecated_kv_pair = + item in `deprecated` must be a key/value pair +attr_parsing_unsupported_literal_deprecated_string = + literal in `deprecated` value must be a string +attr_parsing_unsupported_literal_generic = + unsupported literal +attr_parsing_unsupported_literal_suggestion = + consider removing the prefix diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs new file mode 100644 index 00000000000..b9f841800ab --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -0,0 +1,49 @@ +use rustc_ast::attr::{AttributeExt, filter_by_name}; +use rustc_session::Session; +use rustc_span::symbol::{Symbol, sym}; + +use crate::session_diagnostics; + +pub fn allow_internal_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], +) -> impl Iterator + 'a { + allow_unstable(sess, attrs, sym::allow_internal_unstable) +} + +pub fn rustc_allow_const_fn_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], +) -> impl Iterator + 'a { + allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) +} + +fn allow_unstable<'a>( + sess: &'a Session, + attrs: &'a [impl AttributeExt], + symbol: Symbol, +) -> impl Iterator + 'a { + let attrs = filter_by_name(attrs, symbol); + let list = attrs + .filter_map(move |attr| { + attr.meta_item_list().or_else(|| { + sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList { + span: attr.span(), + name: symbol.to_ident_string(), + }); + None + }) + }) + .flatten(); + + list.into_iter().filter_map(move |it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.dcx().emit_err(session_diagnostics::ExpectsFeatures { + span: it.span(), + name: symbol.to_ident_string(), + }); + } + name + }) +} diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs new file mode 100644 index 00000000000..8cf8e86100f --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -0,0 +1,254 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; +use rustc_ast_pretty::pprust; +use rustc_attr_data_structures::RustcVersion; +use rustc_feature::{Features, GatedCfg, find_gated_cfg}; +use rustc_session::Session; +use rustc_session::config::ExpectedValues; +use rustc_session::lint::BuiltinLintDiag; +use rustc_session::lint::builtin::UNEXPECTED_CFGS; +use rustc_session::parse::feature_err; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, kw, sym}; + +use crate::util::UnsupportedLiteralReason; +use crate::{fluent_generated, parse_version, session_diagnostics}; + +#[derive(Clone, Debug)] +pub struct Condition { + pub name: Symbol, + pub name_span: Span, + pub value: Option, + pub value_span: Option, + pub span: Span, +} + +/// Tests if a cfg-pattern matches the cfg set +pub fn cfg_matches( + cfg: &ast::MetaItemInner, + sess: &Session, + lint_node_id: NodeId, + features: Option<&Features>, +) -> bool { + eval_condition(cfg, sess, features, &mut |cfg| { + try_gate_cfg(cfg.name, cfg.span, sess, features); + match sess.psess.check_config.expecteds.get(&cfg.name) { + Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { + sess.psess.buffer_lint( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + BuiltinLintDiag::UnexpectedCfgValue( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), + ); + } + None if sess.psess.check_config.exhaustive_names => { + sess.psess.buffer_lint( + UNEXPECTED_CFGS, + cfg.span, + lint_node_id, + BuiltinLintDiag::UnexpectedCfgName( + (cfg.name, cfg.name_span), + cfg.value.map(|v| (v, cfg.value_span.unwrap())), + ), + ); + } + _ => { /* not unexpected */ } + } + sess.psess.config.contains(&(cfg.name, cfg.value)) + }) +} + +fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { + let gate = find_gated_cfg(|sym| sym == name); + if let (Some(feats), Some(gated_cfg)) = (features, gate) { + gate_cfg(gated_cfg, span, sess, feats); + } +} + +#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable +fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { + let (cfg, feature, has_feature) = gated_cfg; + if !has_feature(features) && !cfg_span.allows_unstable(*feature) { + let explain = format!("`cfg({cfg})` is experimental and subject to change"); + feature_err(sess, *feature, cfg_span, explain).emit(); + } +} + +/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to +/// evaluate individual items. +pub fn eval_condition( + cfg: &ast::MetaItemInner, + sess: &Session, + features: Option<&Features>, + eval: &mut impl FnMut(Condition) -> bool, +) -> bool { + let dcx = sess.dcx(); + + let cfg = match cfg { + ast::MetaItemInner::MetaItem(meta_item) => meta_item, + ast::MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { + if let Some(features) = features { + // we can't use `try_gate_cfg` as symbols don't differentiate between `r#true` + // and `true`, and we want to keep the former working without feature gate + gate_cfg( + &( + if *b { kw::True } else { kw::False }, + sym::cfg_boolean_literals, + |features: &Features| features.cfg_boolean_literals(), + ), + cfg.span(), + sess, + features, + ); + } + return *b; + } + _ => { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: cfg.span(), + reason: UnsupportedLiteralReason::CfgBoolean, + is_bytestr: false, + start_point_span: sess.source_map().start_point(cfg.span()), + }); + return false; + } + }; + + match &cfg.kind { + ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => { + try_gate_cfg(sym::version, cfg.span, sess, features); + let (min_version, span) = match &mis[..] { + [MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => { + (sym, span) + } + [ + MetaItemInner::Lit(MetaItemLit { span, .. }) + | MetaItemInner::MetaItem(MetaItem { span, .. }), + ] => { + dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); + return false; + } + [..] => { + dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { + span: cfg.span, + }); + return false; + } + }; + let Some(min_version) = parse_version(*min_version) else { + dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); + return false; + }; + + // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details + if sess.psess.assume_incomplete_release { + RustcVersion::CURRENT > min_version + } else { + RustcVersion::CURRENT >= min_version + } + } + ast::MetaItemKind::List(mis) => { + for mi in mis.iter() { + if mi.meta_item_or_bool().is_none() { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: mi.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(mi.span()), + }); + return false; + } + } + + // The unwraps below may look dangerous, but we've already asserted + // that they won't fail with the loop above. + match cfg.name_or_empty() { + sym::any => mis + .iter() + // We don't use any() here, because we want to evaluate all cfg condition + // as eval_condition can (and does) extra checks + .fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)), + sym::all => mis + .iter() + // We don't use all() here, because we want to evaluate all cfg condition + // as eval_condition can (and does) extra checks + .fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)), + sym::not => { + let [mi] = mis.as_slice() else { + dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); + return false; + }; + + !eval_condition(mi, sess, features, eval) + } + sym::target => { + if let Some(features) = features + && !features.cfg_target_compact() + { + feature_err( + sess, + sym::cfg_target_compact, + cfg.span, + fluent_generated::attr_parsing_unstable_cfg_target_compact, + ) + .emit(); + } + + mis.iter().fold(true, |res, mi| { + let Some(mut mi) = mi.meta_item().cloned() else { + dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { + span: mi.span(), + }); + return false; + }; + + if let [seg, ..] = &mut mi.path.segments[..] { + seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); + } + + res & eval_condition( + &ast::MetaItemInner::MetaItem(mi), + sess, + features, + eval, + ) + }) + } + _ => { + dcx.emit_err(session_diagnostics::InvalidPredicate { + span: cfg.span, + predicate: pprust::path_to_string(&cfg.path), + }); + false + } + } + } + ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { + dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); + true + } + MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { + dcx.emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::CfgString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); + true + } + ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => { + let ident = cfg.ident().expect("multi-segment cfg predicate"); + eval(Condition { + name: ident.name, + name_span: ident.span, + value: cfg.value_str(), + value_span: cfg.name_value_literal_span(), + span: cfg.span, + }) + } + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/confusables.rs b/compiler/rustc_attr_parsing/src/attributes/confusables.rs new file mode 100644 index 00000000000..672fcf05eda --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/confusables.rs @@ -0,0 +1,21 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::MetaItemInner; +use rustc_ast::attr::AttributeExt; +use rustc_span::symbol::Symbol; + +/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names. +pub fn parse_confusables(attr: &impl AttributeExt) -> Option> { + let metas = attr.meta_item_list()?; + + let mut candidates = Vec::new(); + + for meta in metas { + let MetaItemInner::Lit(meta_lit) = meta else { + return None; + }; + candidates.push(meta_lit.symbol); + } + + Some(candidates) +} diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs new file mode 100644 index 00000000000..2f9872cc311 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -0,0 +1,149 @@ +//! Parsing and validation of builtin attributes + +use rustc_ast::attr::AttributeExt; +use rustc_ast::{MetaItem, MetaItemInner}; +use rustc_ast_pretty::pprust; +use rustc_attr_data_structures::{DeprecatedSince, Deprecation}; +use rustc_feature::Features; +use rustc_session::Session; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, sym}; + +use super::util::UnsupportedLiteralReason; +use crate::{parse_version, session_diagnostics}; + +/// Finds the deprecation attribute. `None` if none exists. +pub fn find_deprecation( + sess: &Session, + features: &Features, + attrs: &[impl AttributeExt], +) -> Option<(Deprecation, Span)> { + let mut depr: Option<(Deprecation, Span)> = None; + let is_rustc = features.staged_api(); + + 'outer: for attr in attrs { + if !attr.has_name(sym::deprecated) { + continue; + } + + let mut since = None; + let mut note = None; + let mut suggestion = None; + + if attr.is_doc_comment() { + continue; + } else if attr.is_word() { + } else if let Some(value) = attr.value_str() { + note = Some(value) + } else if let Some(list) = attr.meta_item_list() { + let get = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); + return false; + } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + if let Some(lit) = meta.name_value_literal() { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedString, + is_bytestr: lit.kind.is_bytestr(), + start_point_span: sess.source_map().start_point(lit.span), + }); + } else { + sess.dcx() + .emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + } + false + } + }; + + for meta in &list { + match meta { + MetaItemInner::MetaItem(mi) => match mi.name_or_empty() { + sym::since => { + if !get(mi, &mut since) { + continue 'outer; + } + } + sym::note => { + if !get(mi, &mut note) { + continue 'outer; + } + } + sym::suggestion => { + if !features.deprecated_suggestion() { + sess.dcx().emit_err( + session_diagnostics::DeprecatedItemSuggestion { + span: mi.span, + is_nightly: sess.is_nightly_build(), + details: (), + }, + ); + } + + if !get(mi, &mut suggestion) { + continue 'outer; + } + } + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: if features.deprecated_suggestion() { + &["since", "note", "suggestion"] + } else { + &["since", "note"] + }, + }); + continue 'outer; + } + }, + MetaItemInner::Lit(lit) => { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: lit.span, + reason: UnsupportedLiteralReason::DeprecatedKvPair, + is_bytestr: false, + start_point_span: sess.source_map().start_point(lit.span), + }); + continue 'outer; + } + } + } + } else { + continue; + } + + let since = if let Some(since) = since { + if since.as_str() == "TBD" { + DeprecatedSince::Future + } else if !is_rustc { + DeprecatedSince::NonStandard(since) + } else if let Some(version) = parse_version(since) { + DeprecatedSince::RustcVersion(version) + } else { + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); + DeprecatedSince::Err + } + } else if is_rustc { + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); + DeprecatedSince::Err + } else { + DeprecatedSince::Unspecified + }; + + if is_rustc && note.is_none() { + sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() }); + continue; + } + + depr = Some((Deprecation { since, note, suggestion }, attr.span())); + } + + depr +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs new file mode 100644 index 00000000000..a78e0b54b64 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -0,0 +1,17 @@ +mod allow_unstable; +mod cfg; +mod confusables; +mod deprecation; +mod repr; +mod stability; +mod transparency; + +pub mod util; + +pub use allow_unstable::*; +pub use cfg::*; +pub use confusables::*; +pub use deprecation::*; +pub use repr::*; +pub use stability::*; +pub use transparency::*; diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs new file mode 100644 index 00000000000..008edfe6366 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -0,0 +1,215 @@ +//! Parsing and validation of builtin attributes + +use rustc_abi::Align; +use rustc_ast::attr::AttributeExt; +use rustc_ast::{self as ast, MetaItemKind}; +use rustc_attr_data_structures::IntType; +use rustc_attr_data_structures::ReprAttr::*; +use rustc_session::Session; +use rustc_span::symbol::{Symbol, sym}; + +use crate::ReprAttr; +use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; + +/// Parse #[repr(...)] forms. +/// +/// Valid repr contents: any of the primitive integral type names (see +/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use +/// the same discriminant size that the corresponding C enum would or C +/// structure layout, `packed` to remove padding, and `transparent` to delegate representation +/// concerns to the only non-ZST field. +pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec { + if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() } +} + +pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec { + assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); + let mut acc = Vec::new(); + let dcx = sess.dcx(); + + if let Some(items) = attr.meta_item_list() { + for item in items { + let mut recognised = false; + if item.is_word() { + let hint = match item.name_or_empty() { + sym::Rust => Some(ReprRust), + sym::C => Some(ReprC), + sym::packed => Some(ReprPacked(Align::ONE)), + sym::simd => Some(ReprSimd), + sym::transparent => Some(ReprTransparent), + sym::align => { + sess.dcx().emit_err(session_diagnostics::InvalidReprAlignNeedArg { + span: item.span(), + }); + recognised = true; + None + } + name => int_type_of_word(name).map(ReprInt), + }; + + if let Some(h) = hint { + recognised = true; + acc.push(h); + } + } else if let Some((name, value)) = item.singleton_lit_list() { + let mut literal_error = None; + let mut err_span = item.span(); + if name == sym::align { + recognised = true; + match parse_alignment(&value.kind) { + Ok(literal) => acc.push(ReprAlign(literal)), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } + }; + } else if name == sym::packed { + recognised = true; + match parse_alignment(&value.kind) { + Ok(literal) => acc.push(ReprPacked(literal)), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } + }; + } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) + || int_type_of_word(name).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { + span: item.span(), + name: name.to_ident_string(), + }); + } + if let Some(literal_error) = literal_error { + sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric { + span: err_span, + repr_arg: name.to_ident_string(), + error_part: literal_error, + }); + } + } else if let Some(meta_item) = item.meta_item() { + match &meta_item.kind { + MetaItemKind::NameValue(value) => { + if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { + let name = meta_item.name_or_empty().to_ident_string(); + recognised = true; + sess.dcx().emit_err(session_diagnostics::IncorrectReprFormatGeneric { + span: item.span(), + repr_arg: &name, + cause: IncorrectReprFormatGenericCause::from_lit_kind( + item.span(), + &value.kind, + &name, + ), + }); + } else if matches!( + meta_item.name_or_empty(), + sym::Rust | sym::C | sym::simd | sym::transparent + ) || int_type_of_word(meta_item.name_or_empty()).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoValue { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); + } + } + MetaItemKind::List(nested_items) => { + if meta_item.has_name(sym::align) { + recognised = true; + if let [nested_item] = nested_items.as_slice() { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatExpectInteger { + span: nested_item.span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatAlignOneArg { + span: meta_item.span, + }, + ); + } + } else if meta_item.has_name(sym::packed) { + recognised = true; + if let [nested_item] = nested_items.as_slice() { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedExpectInteger { + span: nested_item.span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { + span: meta_item.span, + }, + ); + } + } else if matches!( + meta_item.name_or_empty(), + sym::Rust | sym::C | sym::simd | sym::transparent + ) || int_type_of_word(meta_item.name_or_empty()).is_some() + { + recognised = true; + sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); + } + } + _ => (), + } + } + if !recognised { + // Not a word we recognize. This will be caught and reported by + // the `check_mod_attrs` pass, but this pass doesn't always run + // (e.g. if we only pretty-print the source), so we have to gate + // the `span_delayed_bug` call as follows: + if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) { + dcx.span_delayed_bug(item.span(), "unrecognized representation hint"); + } + } + } + } + acc +} + +fn int_type_of_word(s: Symbol) -> Option { + use rustc_attr_data_structures::IntType::*; + + match s { + sym::i8 => Some(SignedInt(ast::IntTy::I8)), + sym::u8 => Some(UnsignedInt(ast::UintTy::U8)), + sym::i16 => Some(SignedInt(ast::IntTy::I16)), + sym::u16 => Some(UnsignedInt(ast::UintTy::U16)), + sym::i32 => Some(SignedInt(ast::IntTy::I32)), + sym::u32 => Some(UnsignedInt(ast::UintTy::U32)), + sym::i64 => Some(SignedInt(ast::IntTy::I64)), + sym::u64 => Some(UnsignedInt(ast::UintTy::U64)), + sym::i128 => Some(SignedInt(ast::IntTy::I128)), + sym::u128 => Some(UnsignedInt(ast::UintTy::U128)), + sym::isize => Some(SignedInt(ast::IntTy::Isize)), + sym::usize => Some(UnsignedInt(ast::UintTy::Usize)), + _ => None, + } +} + +pub fn parse_alignment(node: &ast::LitKind) -> Result { + if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { + // `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first + if literal.get().is_power_of_two() { + // Only possible error is larger than 2^29 + literal + .get() + .try_into() + .ok() + .and_then(|v| Align::from_bytes(v).ok()) + .ok_or("larger than 2^29") + } else { + Err("not a power of two") + } + } else { + Err("not an unsuffixed integer") + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs new file mode 100644 index 00000000000..0d5bd105f05 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -0,0 +1,385 @@ +//! Parsing and validation of builtin attributes + +use std::num::NonZero; + +use rustc_ast::MetaItem; +use rustc_ast::attr::AttributeExt; +use rustc_ast_pretty::pprust; +use rustc_attr_data_structures::{ + ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason, + VERSION_PLACEHOLDER, +}; +use rustc_errors::ErrorGuaranteed; +use rustc_session::Session; +use rustc_span::Span; +use rustc_span::symbol::{Symbol, sym}; + +use crate::attributes::util::UnsupportedLiteralReason; +use crate::{parse_version, session_diagnostics}; + +/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. +pub fn find_stability( + sess: &Session, + attrs: &[impl AttributeExt], + item_sp: Span, +) -> Option<(Stability, Span)> { + let mut stab: Option<(Stability, Span)> = None; + let mut allowed_through_unstable_modules = false; + + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, + sym::unstable => { + if stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span())); + } + } + sym::stable => { + if stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span())); + } + } + _ => {} + } + } + + if allowed_through_unstable_modules { + match &mut stab { + Some(( + Stability { + level: StabilityLevel::Stable { allowed_through_unstable_modules, .. }, + .. + }, + _, + )) => *allowed_through_unstable_modules = true, + _ => { + sess.dcx() + .emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); + } + } + } + + stab +} + +/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. +pub fn find_const_stability( + sess: &Session, + attrs: &[impl AttributeExt], + item_sp: Span, +) -> Option<(ConstStability, Span)> { + let mut const_stab: Option<(ConstStability, Span)> = None; + let mut promotable = false; + let mut const_stable_indirect = false; + + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_promotable => promotable = true, + sym::rustc_const_stable_indirect => const_stable_indirect = true, + sym::rustc_const_unstable => { + if const_stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + const_stab = Some(( + ConstStability { + level, + feature, + const_stable_indirect: false, + promotable: false, + }, + attr.span(), + )); + } + } + sym::rustc_const_stable => { + if const_stab.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels { + span: attr.span(), + }); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + const_stab = Some(( + ConstStability { + level, + feature, + const_stable_indirect: false, + promotable: false, + }, + attr.span(), + )); + } + } + _ => {} + } + } + + // Merge promotable and const_stable_indirect into stability info + if promotable { + match &mut const_stab { + Some((stab, _)) => stab.promotable = promotable, + _ => { + _ = sess + .dcx() + .emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }) + } + } + } + if const_stable_indirect { + match &mut const_stab { + Some((stab, _)) => { + if stab.is_const_unstable() { + stab.const_stable_indirect = true; + } else { + _ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing { + span: item_sp, + }) + } + } + _ => { + // This function has no const stability attribute, but has `const_stable_indirect`. + // We ignore that; unmarked functions are subject to recursive const stability + // checks by default so we do carry out the user's intent. + } + } + } + + const_stab +} + +/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate +/// without the `staged_api` feature. +pub fn unmarked_crate_const_stab( + _sess: &Session, + attrs: &[impl AttributeExt], + regular_stab: Stability, +) -> ConstStability { + assert!(regular_stab.level.is_unstable()); + // The only attribute that matters here is `rustc_const_stable_indirect`. + // We enforce recursive const stability rules for those functions. + let const_stable_indirect = + attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect); + ConstStability { + feature: regular_stab.feature, + const_stable_indirect, + promotable: false, + level: regular_stab.level, + } +} + +/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. +/// Returns `None` if no stability attributes are found. +pub fn find_body_stability( + sess: &Session, + attrs: &[impl AttributeExt], +) -> Option<(DefaultBodyStability, Span)> { + let mut body_stab: Option<(DefaultBodyStability, Span)> = None; + + for attr in attrs { + if attr.has_name(sym::rustc_default_body_unstable) { + if body_stab.is_some() { + sess.dcx() + .emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() }); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + body_stab = Some((DefaultBodyStability { level, feature }, attr.span())); + } + } + } + + body_stab +} + +fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option) -> Option<()> { + if item.is_some() { + sess.dcx().emit_err(session_diagnostics::MultipleItem { + span: meta.span, + item: pprust::path_to_string(&meta.path), + }); + None + } else if let Some(v) = meta.value_str() { + *item = Some(v); + Some(()) + } else { + sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + None + } +} + +/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and +/// its stability information. +fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; + + let mut feature = None; + let mut since = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); + return None; + }; + + match mi.name_or_empty() { + sym::feature => insert_or_error(sess, mi, &mut feature)?, + sym::since => insert_or_error(sess, mi, &mut since)?, + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "since"], + }); + return None; + } + } + } + + let feature = match feature { + Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), + Some(_bad_feature) => { + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) + } + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), + }; + + let since = if let Some(since) = since { + if since.as_str() == VERSION_PLACEHOLDER { + StableSince::Current + } else if let Some(version) = parse_version(since) { + StableSince::Version(version) + } else { + sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() }); + StableSince::Err + } + } else { + sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() }); + StableSince::Err + }; + + match feature { + Ok(feature) => { + let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; + Some((feature, level)) + } + Err(ErrorGuaranteed { .. }) => None, + } +} + +/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` +/// attribute, and return the feature name and its stability information. +fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> { + let metas = attr.meta_item_list()?; + + let mut feature = None; + let mut reason = None; + let mut issue = None; + let mut issue_num = None; + let mut is_soft = false; + let mut implied_by = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral { + span: meta.span(), + reason: UnsupportedLiteralReason::Generic, + is_bytestr: false, + start_point_span: sess.source_map().start_point(meta.span()), + }); + return None; + }; + + match mi.name_or_empty() { + sym::feature => insert_or_error(sess, mi, &mut feature)?, + sym::reason => insert_or_error(sess, mi, &mut reason)?, + sym::issue => { + insert_or_error(sess, mi, &mut issue)?; + + // These unwraps are safe because `insert_or_error` ensures the meta item + // is a name/value pair string literal. + issue_num = match issue.unwrap().as_str() { + "none" => None, + issue => match issue.parse::>() { + Ok(num) => Some(num), + Err(err) => { + sess.dcx().emit_err( + session_diagnostics::InvalidIssueString { + span: mi.span, + cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( + mi.name_value_literal_span().unwrap(), + err.kind(), + ), + }, + ); + return None; + } + }, + }; + } + sym::soft => { + if !mi.is_word() { + sess.dcx().emit_err(session_diagnostics::SoftNoArgs { span: mi.span }); + } + is_soft = true; + } + sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?, + _ => { + sess.dcx().emit_err(session_diagnostics::UnknownMetaItem { + span: meta.span(), + item: pprust::path_to_string(&mi.path), + expected: &["feature", "reason", "issue", "soft", "implied_by"], + }); + return None; + } + } + } + + let feature = match feature { + Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature), + Some(_bad_feature) => { + Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() })) + } + None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })), + }; + + let issue = issue.ok_or_else(|| { + sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() }) + }); + + match (feature, issue) { + (Ok(feature), Ok(_)) => { + let level = StabilityLevel::Unstable { + reason: UnstableReason::from_opt_reason(reason), + issue: issue_num, + is_soft, + implied_by, + }; + Some((feature, level)) + } + (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None, + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs new file mode 100644 index 00000000000..f4065a77048 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs @@ -0,0 +1,36 @@ +use rustc_ast::attr::AttributeExt; +use rustc_attr_data_structures::TransparencyError; +use rustc_span::hygiene::Transparency; +use rustc_span::sym; + +pub fn find_transparency( + attrs: &[impl AttributeExt], + macro_rules: bool, +) -> (Transparency, Option) { + let mut transparency = None; + let mut error = None; + for attr in attrs { + if attr.has_name(sym::rustc_macro_transparency) { + if let Some((_, old_span)) = transparency { + error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span())); + break; + } else if let Some(value) = attr.value_str() { + transparency = Some(( + match value { + sym::transparent => Transparency::Transparent, + sym::semitransparent => Transparency::SemiTransparent, + sym::opaque => Transparency::Opaque, + _ => { + error = + Some(TransparencyError::UnknownTransparency(value, attr.span())); + continue; + } + }, + attr.span(), + )); + } + } + } + let fallback = if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque }; + (transparency.map_or(fallback, |t| t.0), error) +} diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs new file mode 100644 index 00000000000..c59d2fec1dc --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -0,0 +1,36 @@ +use rustc_ast::attr::{AttributeExt, first_attr_value_str_by_name}; +use rustc_attr_data_structures::RustcVersion; +use rustc_feature::is_builtin_attr_name; +use rustc_span::symbol::{Symbol, sym}; + +pub(crate) enum UnsupportedLiteralReason { + Generic, + CfgString, + CfgBoolean, + DeprecatedString, + DeprecatedKvPair, +} + +pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { + attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) +} + +pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { + first_attr_value_str_by_name(attrs, sym::crate_name) +} + +/// Parse a rustc version number written inside string literal in an attribute, +/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are +/// not accepted in this position, unlike when parsing CFG_RELEASE. +pub fn parse_version(s: Symbol) -> Option { + let mut components = s.as_str().split('-'); + let d = components.next()?; + if components.next().is_some() { + return None; + } + let mut digits = d.splitn(3, '.'); + let major = digits.next()?.parse().ok()?; + let minor = digits.next()?.parse().ok()?; + let patch = digits.next().unwrap_or("0").parse().ok()?; + Some(RustcVersion { major, minor, patch }) +} diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs new file mode 100644 index 00000000000..a1264a6875f --- /dev/null +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -0,0 +1,22 @@ +//! Functions and types dealing with attributes and meta items. +//! +//! FIXME(Centril): For now being, much of the logic is still in `rustc_ast::attr`. +//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` +//! to this crate. + +// tidy-alphabetical-start +#![allow(internal_features)] +#![doc(rust_logo)] +#![feature(let_chains)] +#![feature(rustdoc_internals)] +#![warn(unreachable_pub)] +// tidy-alphabetical-end + +mod attributes; +mod session_diagnostics; + +pub use attributes::*; +pub use rustc_attr_data_structures::*; +pub use util::{find_crate_name, is_builtin_attr, parse_version}; + +rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs new file mode 100644 index 00000000000..b1d8ec49774 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -0,0 +1,419 @@ +use std::num::IntErrorKind; + +use rustc_ast as ast; +use rustc_errors::codes::*; +use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; +use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_span::{Span, Symbol}; + +use crate::attributes::util::UnsupportedLiteralReason; +use crate::fluent_generated as fluent; + +#[derive(Diagnostic)] +#[diag(attr_parsing_expected_one_cfg_pattern, code = E0536)] +pub(crate) struct ExpectedOneCfgPattern { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_predicate, code = E0537)] +pub(crate) struct InvalidPredicate { + #[primary_span] + pub span: Span, + + pub predicate: String, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_multiple_item, code = E0538)] +pub(crate) struct MultipleItem { + #[primary_span] + pub span: Span, + + pub item: String, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_meta_item, code = E0539)] +pub(crate) struct IncorrectMetaItem { + #[primary_span] + pub span: Span, +} + +/// Error code: E0541 +pub(crate) struct UnknownMetaItem<'a> { + pub span: Span, + pub item: String, + pub expected: &'a [&'a str], +} + +// Manual implementation to be able to format `expected` items correctly. +impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { + let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); + Diag::new(dcx, level, fluent::attr_parsing_unknown_meta_item) + .with_span(self.span) + .with_code(E0541) + .with_arg("item", self.item) + .with_arg("expected", expected.join(", ")) + .with_span_label(self.span, fluent::attr_parsing_label) + } +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_missing_since, code = E0542)] +pub(crate) struct MissingSince { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_missing_note, code = E0543)] +pub(crate) struct MissingNote { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_multiple_stability_levels, code = E0544)] +pub(crate) struct MultipleStabilityLevels { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_issue_string, code = E0545)] +pub(crate) struct InvalidIssueString { + #[primary_span] + pub span: Span, + + #[subdiagnostic] + pub cause: Option, +} + +// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be +// translatable. +#[derive(Subdiagnostic)] +pub(crate) enum InvalidIssueStringCause { + #[label(attr_parsing_must_not_be_zero)] + MustNotBeZero { + #[primary_span] + span: Span, + }, + + #[label(attr_parsing_empty)] + Empty { + #[primary_span] + span: Span, + }, + + #[label(attr_parsing_invalid_digit)] + InvalidDigit { + #[primary_span] + span: Span, + }, + + #[label(attr_parsing_pos_overflow)] + PosOverflow { + #[primary_span] + span: Span, + }, + + #[label(attr_parsing_neg_overflow)] + NegOverflow { + #[primary_span] + span: Span, + }, +} + +impl InvalidIssueStringCause { + pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option { + match kind { + IntErrorKind::Empty => Some(Self::Empty { span }), + IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }), + IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }), + IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }), + IntErrorKind::Zero => Some(Self::MustNotBeZero { span }), + _ => None, + } + } +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_missing_feature, code = E0546)] +pub(crate) struct MissingFeature { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_non_ident_feature, code = E0546)] +pub(crate) struct NonIdentFeature { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_missing_issue, code = E0547)] +pub(crate) struct MissingIssue { + #[primary_span] + pub span: Span, +} + +// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? +// It is more similar to `IncorrectReprFormatGeneric`. +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)] +pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { + #[primary_span] + pub span: Span, +} +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_repr_format_packed_expect_integer, code = E0552)] +pub(crate) struct IncorrectReprFormatPackedExpectInteger { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_repr_hint_no_paren, code = E0552)] +pub(crate) struct InvalidReprHintNoParen { + #[primary_span] + pub span: Span, + + pub name: String, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_repr_hint_no_value, code = E0552)] +pub(crate) struct InvalidReprHintNoValue { + #[primary_span] + pub span: Span, + + pub name: String, +} + +/// Error code: E0565 +pub(crate) struct UnsupportedLiteral { + pub span: Span, + pub reason: UnsupportedLiteralReason, + pub is_bytestr: bool, + pub start_point_span: Span, +} + +impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { + let mut diag = Diag::new(dcx, level, match self.reason { + UnsupportedLiteralReason::Generic => fluent::attr_parsing_unsupported_literal_generic, + UnsupportedLiteralReason::CfgString => { + fluent::attr_parsing_unsupported_literal_cfg_string + } + UnsupportedLiteralReason::CfgBoolean => { + fluent::attr_parsing_unsupported_literal_cfg_boolean + } + UnsupportedLiteralReason::DeprecatedString => { + fluent::attr_parsing_unsupported_literal_deprecated_string + } + UnsupportedLiteralReason::DeprecatedKvPair => { + fluent::attr_parsing_unsupported_literal_deprecated_kv_pair + } + }); + diag.span(self.span); + diag.code(E0565); + if self.is_bytestr { + diag.span_suggestion( + self.start_point_span, + fluent::attr_parsing_unsupported_literal_suggestion, + "", + Applicability::MaybeIncorrect, + ); + } + diag + } +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)] +pub(crate) struct InvalidReprAlignNeedArg { + #[primary_span] + #[suggestion(code = "align(...)", applicability = "has-placeholders")] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_repr_generic, code = E0589)] +pub(crate) struct InvalidReprGeneric<'a> { + #[primary_span] + pub span: Span, + + pub repr_arg: String, + pub error_part: &'a str, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_repr_format_align_one_arg, code = E0693)] +pub(crate) struct IncorrectReprFormatAlignOneArg { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_repr_format_expect_literal_integer, code = E0693)] +pub(crate) struct IncorrectReprFormatExpectInteger { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)] +pub(crate) struct IncorrectReprFormatGeneric<'a> { + #[primary_span] + pub span: Span, + + pub repr_arg: &'a str, + + #[subdiagnostic] + pub cause: Option>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum IncorrectReprFormatGenericCause<'a> { + #[suggestion( + attr_parsing_suggestion, + code = "{name}({int})", + applicability = "machine-applicable" + )] + Int { + #[primary_span] + span: Span, + + #[skip_arg] + name: &'a str, + + #[skip_arg] + int: u128, + }, + + #[suggestion( + attr_parsing_suggestion, + code = "{name}({symbol})", + applicability = "machine-applicable" + )] + Symbol { + #[primary_span] + span: Span, + + #[skip_arg] + name: &'a str, + + #[skip_arg] + symbol: Symbol, + }, +} + +impl<'a> IncorrectReprFormatGenericCause<'a> { + pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { + match kind { + ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { + Some(Self::Int { span, name, int: int.get() }) + } + ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }), + _ => None, + } + } +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_rustc_promotable_pairing, code = E0717)] +pub(crate) struct RustcPromotablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_rustc_const_stable_indirect_pairing)] +pub(crate) struct RustcConstStableIndirectPairing { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_rustc_allowed_unstable_pairing, code = E0789)] +pub(crate) struct RustcAllowedUnstablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_cfg_predicate_identifier)] +pub(crate) struct CfgPredicateIdentifier { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_deprecated_item_suggestion)] +pub(crate) struct DeprecatedItemSuggestion { + #[primary_span] + pub span: Span, + + #[help] + pub is_nightly: bool, + + #[note] + pub details: (), +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_expected_single_version_literal)] +pub(crate) struct ExpectedSingleVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_expected_version_literal)] +pub(crate) struct ExpectedVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_expects_feature_list)] +pub(crate) struct ExpectsFeatureList { + #[primary_span] + pub span: Span, + + pub name: String, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_expects_features)] +pub(crate) struct ExpectsFeatures { + #[primary_span] + pub span: Span, + + pub name: String, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_since)] +pub(crate) struct InvalidSince { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_soft_no_args)] +pub(crate) struct SoftNoArgs { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_unknown_version_literal)] +pub(crate) struct UnknownVersionLiteral { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index ef48486f6f1..b50cb35b8e9 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -14,7 +14,7 @@ doctest = false # tidy-alphabetical-start rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 15993dbf5ec..6e90f1682e3 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -7,7 +7,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_errors::PResult; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_span::Span; -use {rustc_ast as ast, rustc_attr as attr}; +use {rustc_ast as ast, rustc_attr_parsing as attr}; use crate::errors; diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 3bd8f899a4a..b91d6ced123 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -6,7 +6,7 @@ use rustc_ast::{ self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem, TraitBoundModifiers, VariantData, WherePredicate, }; -use rustc_attr as attr; +use rustc_attr_parsing as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_macros::Diagnostic; diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 846d8784dea..1c5ff6c9ef2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -185,7 +185,7 @@ use rustc_ast::{ self as ast, AnonConst, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics, Mutability, PatKind, VariantData, }; -use rustc_attr as attr; +use rustc_attr_parsing as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, Span}; diff --git a/compiler/rustc_codegen_gcc/src/attributes.rs b/compiler/rustc_codegen_gcc/src/attributes.rs index d20e13e15b9..028a5ab5f71 100644 --- a/compiler/rustc_codegen_gcc/src/attributes.rs +++ b/compiler/rustc_codegen_gcc/src/attributes.rs @@ -2,8 +2,8 @@ use gccjit::FnAttribute; use gccjit::Function; #[cfg(feature = "master")] -use rustc_attr::InlineAttr; -use rustc_attr::InstructionSetAttr; +use rustc_attr_parsing::InlineAttr; +use rustc_attr_parsing::InstructionSetAttr; #[cfg(feature = "master")] use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty; diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index bb0f2fa5b01..f2efa981f97 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -35,7 +35,7 @@ extern crate tracing; extern crate rustc_abi; extern crate rustc_apfloat; extern crate rustc_ast; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 03a871297c4..689986d642d 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -16,7 +16,7 @@ object = { version = "0.36.3", default-features = false, features = ["std", "rea rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 5552a241060..f8454fd9960 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,6 +1,6 @@ //! Set and unset common attributes on LLVM values. -use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index ec77f32caf4..aa9a0f34f55 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -106,7 +106,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t // This is a monomorphization of a generic function. if !(cx.tcx.sess.opts.share_generics() || tcx.codegen_fn_attrs(instance_def_id).inline - == rustc_attr::InlineAttr::Never) + == rustc_attr_parsing::InlineAttr::Never) { // When not sharing generics, all instances are in the same // crate and have hidden visibility. diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index f5c155667ba..628543443b3 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -17,7 +17,7 @@ rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index cfd40a575b1..dee6dd7b262 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2982,7 +2982,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None), + Some(ref cfg) => rustc_attr_parsing::cfg_matches(cfg, sess, CRATE_NODE_ID, None), None => true, } } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 788a8a13b3e..60ab2919352 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -311,7 +311,8 @@ fn exported_symbols_provider_local( } if !tcx.sess.opts.share_generics() { - if tcx.codegen_fn_attrs(mono_item.def_id()).inline == rustc_attr::InlineAttr::Never + if tcx.codegen_fn_attrs(mono_item.def_id()).inline + == rustc_attr_parsing::InlineAttr::Never { // this is OK, we explicitly allow sharing inline(never) across crates even // without share-generics. diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 828f82ddde3..dab035d3339 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -30,7 +30,7 @@ use rustc_trait_selection::infer::at::ToTrace; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; -use {rustc_ast as ast, rustc_attr as attr}; +use {rustc_ast as ast, rustc_attr_parsing as attr}; use crate::assert_module_sources::CguReuse; use crate::back::link::are_upstream_rust_objects_already_included; diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index c88b625060e..b243f904aee 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,6 +1,6 @@ use rustc_ast::attr::list_contains_name; use rustc_ast::{MetaItemInner, attr}; -use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; @@ -426,7 +426,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let [item] = items.as_slice() && let Some((sym::align, literal)) = item.singleton_lit_list() { - rustc_attr::parse_alignment(&literal.kind) + rustc_attr_parsing::parse_alignment(&literal.kind) .map_err(|msg| { struct_span_code_err!( tcx.dcx(), diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index c08758a9796..cac3cc587cb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -1,4 +1,4 @@ -use rustc_attr::InstructionSetAttr; +use rustc_attr_parsing::InstructionSetAttr; use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility}; use rustc_middle::mir::{Body, InlineAsmOperand}; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf}; diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a84f5c74d1e..c31e8aa7d31 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -1,4 +1,4 @@ -use rustc_attr::InstructionSetAttr; +use rustc_attr_parsing::InstructionSetAttr; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::Applicability; diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 41136019a88..7717cd2c696 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -9,7 +9,7 @@ either = "1" rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 16610ebfca2..f4257ad9671 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -6,7 +6,7 @@ use std::mem; use std::num::NonZero; use std::ops::Deref; -use rustc_attr::{ConstStability, StabilityLevel}; +use rustc_attr_parsing::{ConstStability, StabilityLevel}; use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 80d3c6448aa..ab68691f1b9 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::{self, PolyFnSig, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::Symbol; -use {rustc_attr as attr, rustc_hir as hir}; +use {rustc_attr_parsing as attr, rustc_hir as hir}; pub use self::qualifs::Qualif; diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 81f15ebcbf8..2f0fe64b096 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -9,7 +9,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b80736f41ad..9728f848ce8 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -112,7 +112,7 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ crate::DEFAULT_LOCALE_RESOURCE, rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, - rustc_attr::DEFAULT_LOCALE_RESOURCE, + rustc_attr_parsing::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index ce014364b0d..eb93972387d 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -12,7 +12,7 @@ doctest = false rustc_ast = { path = "../rustc_ast" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 9f2765718b5..82d4847e27a 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -10,7 +10,7 @@ use rustc_ast::token::Nonterminal; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind}; -use rustc_attr::{self as attr, Deprecation, Stability}; +use rustc_attr_parsing::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult}; @@ -848,7 +848,7 @@ impl SyntaxExtension { is_local: bool, ) -> SyntaxExtension { let allow_internal_unstable = - rustc_attr::allow_internal_unstable(sess, attrs).collect::>(); + rustc_attr_parsing::allow_internal_unstable(sess, attrs).collect::>(); let allow_internal_unsafe = ast::attr::contains_name(attrs, sym::allow_internal_unsafe); let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 12298d43b89..8e500f538a7 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -8,7 +8,7 @@ use rustc_ast::tokenstream::{ use rustc_ast::{ self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId, }; -use rustc_attr as attr; +use rustc_attr_parsing as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeSafety, EnabledLangFeature, EnabledLibFeature, Features, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 690e080fbfc..575108a548f 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1913,7 +1913,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { self.cx.current_expansion.lint_node_id, BuiltinLintDiag::UnusedDocComment(attr.span), ); - } else if rustc_attr::is_builtin_attr(attr) { + } else if rustc_attr_parsing::is_builtin_attr(attr) { let attr_name = attr.ident().unwrap().name; // `#[cfg]` and `#[cfg_attr]` are special - they are // eagerly evaluated. diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index c666078fa3b..ae8e24007bd 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -10,7 +10,7 @@ use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId}; use rustc_ast_pretty::pprust; -use rustc_attr::{self as attr, TransparencyError}; +use rustc_attr_parsing::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_feature::Features; diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 581ef2272d1..196d7d99e93 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -13,7 +13,7 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8ff94fa566d..5548a6a6ef7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -31,7 +31,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_type_ir::fold::TypeFoldable; use tracing::{debug, instrument}; use ty::TypingMode; -use {rustc_attr as attr, rustc_hir as hir}; +use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 8ddbb4b3397..1f5acaa58a9 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -9,7 +9,7 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6b1a288510a..caddfc12540 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -8,7 +8,7 @@ use std::borrow::Cow; use hir::Expr; use rustc_ast::ast::Mutability; -use rustc_attr::parse_confusables; +use rustc_attr_parsing::parse_confusables; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::unord::UnordSet; diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 7a2ba07ce87..dcb9c5d22d6 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -11,7 +11,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 2af25bfd3aa..54fbb743b93 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -453,7 +453,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu .opts .crate_name .clone() - .or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string())); + .or_else(|| rustc_attr_parsing::find_crate_name(attrs).map(|n| n.to_string())); match sess.io.output_file { None => { diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index ec5f0f06c59..cc5a9029633 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 7d1c8139518..e315307cd45 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -8,7 +8,7 @@ use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{Ident, sym}; use rustc_span::{BytePos, Span}; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; use crate::lints::{ NonCamelCaseType, NonCamelCaseTypeSub, NonSnakeCaseDiag, NonSnakeCaseDiagSub, diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index dca42fea57d..83942918e3b 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -3,7 +3,7 @@ use rustc_abi::{Integer, Size}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::{bug, ty}; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; use crate::LateContext; use crate::context::LintContext; diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 12519be9870..0b9fdbbd3da 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -11,7 +11,7 @@ libloading = "0.8.0" odht = { version = "0.3.1", features = ["nightly"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 8bd2281981b..fe3bdb3a7b9 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use rustc_abi::ExternAbi; use rustc_ast::CRATE_NODE_ID; -use rustc_attr as attr; +use rustc_attr_parsing as attr; use rustc_data_structures::fx::FxHashSet; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 3077312ccf9..f8c743d4f27 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -1,7 +1,7 @@ use std::any::Any; use std::mem; -use rustc_attr::Deprecation; +use rustc_attr_parsing::Deprecation; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index fa843a10adf..f1872807aef 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -40,7 +40,7 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span}; use rustc_target::spec::{PanicStrategy, TargetTuple}; use table::TableBuilder; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; use crate::creader::CrateMetadataRef; diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 3bda3a4aa63..e64500f812a 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -17,7 +17,7 @@ rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 44428471a5f..509063c40d7 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,5 +1,5 @@ use rustc_abi::Align; -use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::symbol::Symbol; use rustc_target::spec::SanitizerSet; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index eda53ce2e9f..ece561c7493 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -4,7 +4,7 @@ use std::num::NonZero; use rustc_ast::NodeId; -use rustc_attr::{ +use rustc_attr_parsing::{ self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability, }; use rustc_data_structures::unord::UnordMap; diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 266dc7ad2b3..dcb680c283c 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -1,7 +1,7 @@ use std::fmt; use std::hash::Hash; -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 013847f0b2d..9afcf9466b6 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -239,9 +239,9 @@ trivial! { bool, Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>, Option, - Option, - Option, - Option, + Option, + Option, + Option, Option, Option, Option, @@ -264,10 +264,10 @@ trivial! { Result, rustc_abi::ReprOptions, rustc_ast::expand::allocator::AllocatorKind, - rustc_attr::ConstStability, - rustc_attr::DefaultBodyStability, - rustc_attr::Deprecation, - rustc_attr::Stability, + rustc_attr_parsing::ConstStability, + rustc_attr_parsing::DefaultBodyStability, + rustc_attr_parsing::Deprecation, + rustc_attr_parsing::Stability, rustc_data_structures::svh::Svh, rustc_errors::ErrorGuaranteed, rustc_hir::Constness, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 906a47713f4..9475e629683 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -44,7 +44,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::PanicStrategy; -use {rustc_abi as abi, rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_abi as abi, rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0ba187bf105..49b5588e261 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -202,7 +202,7 @@ impl<'tcx> Instance<'tcx> { if !tcx.sess.opts.share_generics() // However, if the def_id is marked inline(never), then it's fine to just reuse the // upstream monomorphization. - && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr::InlineAttr::Never + && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_parsing::InlineAttr::Never { return None; } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cf8b6b5901a..061b4e806b2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -52,7 +52,7 @@ pub use rustc_type_ir::relate::VarianceDiagInfo; pub use rustc_type_ir::*; use tracing::{debug, instrument}; pub use vtable::*; -use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; +use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; pub use self::closure::{ BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo, diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 348f25c8f90..59f2555be95 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -80,10 +80,10 @@ trivially_parameterized_over_tcx! { rustc_ast::Attribute, rustc_ast::DelimArgs, rustc_ast::expand::StrippedCfgItem, - rustc_attr::ConstStability, - rustc_attr::DefaultBodyStability, - rustc_attr::Deprecation, - rustc_attr::Stability, + rustc_attr_parsing::ConstStability, + rustc_attr_parsing::DefaultBodyStability, + rustc_attr_parsing::Deprecation, + rustc_attr_parsing::Stability, rustc_hir::Constness, rustc_hir::Defaultness, rustc_hir::Safety, diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 4b648d21084..2f233f787f0 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -10,7 +10,7 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_const_eval = { path = "../rustc_const_eval" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 589be81558c..e1f1dd83f0d 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -1,4 +1,4 @@ -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::visit::Visitor; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 79c38b50459..f0acbaf56b6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -4,7 +4,7 @@ use std::iter; use std::ops::{Range, RangeFrom}; use rustc_abi::{ExternAbi, FieldIdx}; -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_index::Idx; diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index e18441ea7fc..9bdaeb015cd 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index dabce72650a..33e1065f051 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -833,7 +833,8 @@ fn mono_item_visibility<'tcx>( return if is_generic && (always_export_generics || (can_export_generics - && tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never)) + && tcx.codegen_fn_attrs(def_id).inline + == rustc_attr_parsing::InlineAttr::Never)) { // If it is an upstream monomorphization and we export generics, we must make // it available to downstream crates. @@ -847,7 +848,7 @@ fn mono_item_visibility<'tcx>( if is_generic { if always_export_generics || (can_export_generics - && tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never) + && tcx.codegen_fn_attrs(def_id).inline == rustc_attr_parsing::InlineAttr::Never) { if tcx.is_unreachable_local_definition(def_id) { // This instance cannot be used from another crate. diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index ed5991459ac..497eb373c45 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index ec9075bbdee..07f7a1c8f2a 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -4,7 +4,7 @@ //! but are not declared in one single location (unlike lang features), which means we need to //! collect them instead. -use rustc_attr::VERSION_PLACEHOLDER; +use rustc_attr_parsing::VERSION_PLACEHOLDER; use rustc_hir::Attribute; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 72705b43d6f..96614a7a128 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -4,7 +4,7 @@ use std::mem::replace; use std::num::NonZero; -use rustc_attr::{ +use rustc_attr_parsing::{ self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER, }; diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index f998e0ff154..eb48155919f 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start rustc_ast = { path = "../rustc_ast" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3057f13e3a7..6357efa5bae 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -41,7 +41,7 @@ use rustc_span::Span; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{Ident, kw, sym}; use tracing::debug; -use {rustc_attr as attr, rustc_hir as hir}; +use {rustc_attr_parsing as attr, rustc_hir as hir}; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index b71853b871d..309227176d4 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -10,7 +10,7 @@ pulldown-cmark = { version = "0.11", features = ["html"], default-features = fal rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e18c7edec30..f82fd6a6f5f 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -12,7 +12,7 @@ use rustc_ast::{ self as ast, AssocItem, AssocItemKind, Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StmtKind, }; -use rustc_attr as attr; +use rustc_attr_parsing as attr; use rustc_data_structures::sync::Lrc; use rustc_expand::base::ResolverExpand; use rustc_expand::expand::AstFragment; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 891bc494d0c..43e260aa264 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -8,7 +8,7 @@ use rustc_ast::attr::AttributeExt; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr}; use rustc_ast_pretty::pprust; -use rustc_attr::StabilityLevel; +use rustc_attr_parsing::StabilityLevel; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, StashKey}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 0b4470b2b0f..dcf86d1a408 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -29,9 +29,6 @@ pub mod output; pub use getopts; -mod version; -pub use version::RustcVersion; - rustc_fluent_macro::fluent_messages! { "../messages.ftl" } /// Requirements for a `StableHashingContext` to be used in this crate. diff --git a/compiler/rustc_session/src/version.rs b/compiler/rustc_session/src/version.rs deleted file mode 100644 index 1696eaf902b..00000000000 --- a/compiler/rustc_session/src/version.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::borrow::Cow; -use std::fmt::{self, Display}; - -use rustc_errors::IntoDiagArg; -use rustc_macros::{Decodable, Encodable, HashStable_Generic, current_rustc_version}; - -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable_Generic)] -pub struct RustcVersion { - pub major: u16, - pub minor: u16, - pub patch: u16, -} - -impl RustcVersion { - pub const CURRENT: Self = current_rustc_version!(); -} - -impl Display for RustcVersion { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) - } -} - -impl IntoDiagArg for RustcVersion { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - rustc_errors::DiagArgValue::Str(Cow::Owned(self.to_string())) - } -} diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index e29ed9a4b56..b13a753c4ed 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -9,7 +9,7 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } -rustc_attr = { path = "../rustc_attr" } +rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index dac4a03bf75..d54b8598254 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -16,7 +16,7 @@ use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::Span; use rustc_span::symbol::{Symbol, kw, sym}; use tracing::{debug, info}; -use {rustc_attr as attr, rustc_hir as hir}; +use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::{ObligationCauseCode, PredicateObligation}; use crate::error_reporting::TypeErrCtxt; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d4dc35b6c9c..0918a90d04b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -6,7 +6,7 @@ use std::{fmt, iter}; use arrayvec::ArrayVec; use rustc_abi::{ExternAbi, VariantIdx}; -use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; +use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7d40f662ed0..136002b8e15 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -15,7 +15,7 @@ use std::iter::{self, once}; use itertools::Itertools; use rustc_abi::ExternAbi; -use rustc_attr::{ConstStability, StabilityLevel, StableSince}; +use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e013829e5e0..eb9f39128bc 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -44,14 +44,15 @@ use std::path::PathBuf; use std::{fs, str}; use rinja::Template; -use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince}; +use rustc_attr_parsing::{ + ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, +}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::Mutability; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::RustcVersion; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName}; use serde::ser::SerializeMap; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index be39984c3da..12f68f60426 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -6,7 +6,7 @@ use rustc_abi::ExternAbi; use rustc_ast::ast; -use rustc_attr::DeprecatedSince; +use rustc_attr_parsing::DeprecatedSince; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; @@ -215,8 +215,8 @@ where } } -pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation { - let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation; +pub(crate) fn from_deprecation(deprecation: rustc_attr_parsing::Deprecation) -> Deprecation { + let rustc_attr_parsing::Deprecation { since, note, suggestion: _ } = deprecation; let since = match since { DeprecatedSince::RustcVersion(version) => Some(version.to_string()), DeprecatedSince::Future => Some("TBD".to_owned()), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5d82b8e309a..91e104f49fb 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -36,7 +36,7 @@ extern crate pulldown_cmark; extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index a81b130a218..d924be2edce 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -6,7 +6,7 @@ //! [`core::error`] module is marked as stable since 1.81.0, so we want to show //! [`core::error::Error`] as stable since 1.81.0 as well. -use rustc_attr::{Stability, StabilityLevel}; +use rustc_attr_parsing::{Stability, StabilityLevel}; use rustc_hir::def_id::CRATE_DEF_ID; use crate::clean::{Crate, Item, ItemId, ItemKind}; diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs index ebd35fd2b27..95c85f250e9 100644 --- a/src/tools/clippy/clippy_lints/src/approx_const.rs +++ b/src/tools/clippy/clippy_lints/src/approx_const.rs @@ -2,9 +2,10 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv}; use rustc_ast::ast::{FloatTy, LitFloatType, LitKind}; +use rustc_attr_parsing::RustcVersion; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::symbol; use std::f64::consts as f64; diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index 6eef0d42a55..f68a7a89b39 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -9,7 +9,8 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp}; use rustc_lint::{LateContext, LateLintPass, Level}; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_attr_parsing::RustcVersion; +use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index f3467adacc5..6cee7cfaca2 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -2,12 +2,12 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_in_test; use clippy_utils::msrvs::Msrv; -use rustc_attr::{StabilityLevel, StableSince}; +use rustc_attr_parsing::{StabilityLevel, StableSince, RustcVersion}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::{Expr, ExprKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyCtxt; -use rustc_session::{RustcVersion, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::def_id::DefId; use rustc_span::{ExpnKind, Span}; diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index e80cca6e7db..3e8315588cc 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -35,7 +35,7 @@ extern crate rustc_abi; extern crate rustc_arena; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs index 2941b9c3960..82ff13a5aff 100644 --- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs +++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs @@ -2,7 +2,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; use clippy_utils::msrvs::Msrv; -use rustc_attr::{StabilityLevel, StableSince}; +use rustc_attr_parsing::{StabilityLevel, StableSince}; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index af38e066559..496343d82c8 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -222,7 +222,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<' return; } - if rustc_attr::parse_version(value).is_none() { + if rustc_attr_parsing::parse_version(value).is_none() { span_lint_and_help( cx, INVALID_CLIPPY_VERSION_ATTRIBUTE, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 96139a08c3d..02bbddb413a 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -31,7 +31,7 @@ // (Currently there is no way to opt into sysroot crates without `extern crate`.) extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_const_eval; extern crate rustc_data_structures; // The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate. diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 55986acea3d..1e6368fab36 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -1,6 +1,6 @@ use rustc_ast::attr::AttributeExt; -use rustc_attr::parse_version; -use rustc_session::{RustcVersion, Session}; +use rustc_attr_parsing::{parse_version, RustcVersion}; +use rustc_session::Session; use rustc_span::{Symbol, sym}; use serde::Deserialize; use smallvec::{SmallVec, smallvec}; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index df3f10d6179..104ae154e36 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -5,7 +5,7 @@ use crate::msrvs::{self, Msrv}; use hir::LangItem; -use rustc_attr::StableSince; +use rustc_attr_parsing::{RustcVersion, StableSince}; use rustc_const_eval::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -381,14 +381,14 @@ fn check_terminator<'tcx>( fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { tcx.is_const_fn(def_id) && tcx.lookup_const_stability(def_id).is_none_or(|const_stab| { - if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level { + if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level { // Checking MSRV is manually necessary because `rustc` has no such concept. This entire // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`. // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. let const_stab_rust_version = match since { StableSince::Version(version) => version, - StableSince::Current => rustc_session::RustcVersion::CURRENT, + StableSince::Current => RustcVersion::CURRENT, StableSince::Err => return false, }; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 85c896563da..e02d51afcef 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -58,7 +58,7 @@ extern crate tracing; extern crate rustc_abi; extern crate rustc_apfloat; extern crate rustc_ast; -extern crate rustc_attr; +extern crate rustc_attr_parsing; extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ac26feb345c..ad8a7ea1668 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -11,7 +11,7 @@ use std::{fmt, process}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[allow(unused)] use rustc_data_structures::static_assert_size; -- cgit 1.4.1-3-g733a5 From cb487cc2fa3c5ebfddd22d6721cf1669943c1774 Mon Sep 17 00:00:00 2001 From: ltdk Date: Mon, 23 Sep 2024 19:40:22 -0400 Subject: Stabilize #[coverage] attribute --- compiler/rustc_feature/src/accepted.rs | 3 + compiler/rustc_feature/src/builtin_attrs.rs | 3 +- compiler/rustc_feature/src/unstable.rs | 3 - library/core/src/cmp.rs | 2 +- library/core/src/lib.rs | 2 +- library/core/src/macros/mod.rs | 6 +- .../src/language-features/coverage-attribute.md | 30 ------- .../crates/hir-expand/src/inert_attr_macro.rs | 2 +- tests/coverage/async.cov-map | 100 ++++++++++----------- tests/coverage/async.coverage | 1 - tests/coverage/async.rs | 1 - tests/coverage/async2.cov-map | 24 ++--- tests/coverage/async2.coverage | 1 - tests/coverage/async2.rs | 1 - tests/coverage/async_block.cov-map | 8 +- tests/coverage/async_block.coverage | 1 - tests/coverage/async_block.rs | 1 - tests/coverage/attr/impl.cov-map | 12 +-- tests/coverage/attr/impl.coverage | 1 - tests/coverage/attr/impl.rs | 1 - tests/coverage/attr/module.cov-map | 12 +-- tests/coverage/attr/module.coverage | 1 - tests/coverage/attr/module.rs | 1 - tests/coverage/attr/nested.coverage | 2 +- tests/coverage/attr/nested.rs | 2 +- tests/coverage/attr/off-on-sandwich.cov-map | 12 +-- tests/coverage/attr/off-on-sandwich.coverage | 1 - tests/coverage/attr/off-on-sandwich.rs | 1 - tests/coverage/auxiliary/executor.rs | 1 - tests/coverage/await_ready.cov-map | 8 +- tests/coverage/await_ready.coverage | 1 - tests/coverage/await_ready.rs | 1 - tests/coverage/bad_counter_ids.cov-map | 32 +++---- tests/coverage/bad_counter_ids.coverage | 1 - tests/coverage/bad_counter_ids.rs | 1 - tests/coverage/branch/generics.cov-map | 12 +-- tests/coverage/branch/generics.coverage | 1 - tests/coverage/branch/generics.rs | 1 - tests/coverage/branch/guard.cov-map | 4 +- tests/coverage/branch/guard.coverage | 1 - tests/coverage/branch/guard.rs | 1 - tests/coverage/branch/if-let.coverage | 2 +- tests/coverage/branch/if-let.rs | 2 +- tests/coverage/branch/if.cov-map | 16 ++-- tests/coverage/branch/if.coverage | 1 - tests/coverage/branch/if.rs | 1 - tests/coverage/branch/lazy-boolean.cov-map | 16 ++-- tests/coverage/branch/lazy-boolean.coverage | 1 - tests/coverage/branch/lazy-boolean.rs | 1 - tests/coverage/branch/let-else.cov-map | 4 +- tests/coverage/branch/let-else.coverage | 1 - tests/coverage/branch/let-else.rs | 1 - tests/coverage/branch/match-arms.cov-map | 12 +-- tests/coverage/branch/match-arms.coverage | 1 - tests/coverage/branch/match-arms.rs | 1 - tests/coverage/branch/match-trivial.cov-map | 8 +- tests/coverage/branch/match-trivial.coverage | 1 - tests/coverage/branch/match-trivial.rs | 1 - tests/coverage/branch/no-mir-spans.cov-map | 16 ++-- tests/coverage/branch/no-mir-spans.coverage | 1 - tests/coverage/branch/no-mir-spans.rs | 1 - tests/coverage/branch/while.cov-map | 16 ++-- tests/coverage/branch/while.coverage | 1 - tests/coverage/branch/while.rs | 1 - tests/coverage/closure_macro_async.cov-map | 16 ++-- tests/coverage/closure_macro_async.coverage | 1 - tests/coverage/closure_macro_async.rs | 1 - tests/coverage/closure_unit_return.cov-map | 16 ++-- tests/coverage/closure_unit_return.coverage | 1 - tests/coverage/closure_unit_return.rs | 1 - tests/coverage/condition/conditions.cov-map | 28 +++--- tests/coverage/condition/conditions.coverage | 1 - tests/coverage/condition/conditions.rs | 1 - tests/coverage/coverage_attr_closure.coverage | 2 +- tests/coverage/coverage_attr_closure.rs | 2 +- tests/coverage/fn_sig_into_try.cov-map | 16 ++-- tests/coverage/fn_sig_into_try.coverage | 1 - tests/coverage/fn_sig_into_try.rs | 1 - tests/coverage/if_not.cov-map | 4 +- tests/coverage/if_not.coverage | 1 - tests/coverage/if_not.rs | 1 - tests/coverage/let_else_loop.cov-map | 12 +-- tests/coverage/let_else_loop.coverage | 1 - tests/coverage/let_else_loop.rs | 1 - tests/coverage/macro_in_closure.cov-map | 8 +- tests/coverage/macro_in_closure.coverage | 1 - tests/coverage/macro_in_closure.rs | 1 - tests/coverage/mcdc/condition-limit.cov-map | 4 +- tests/coverage/mcdc/condition-limit.coverage | 1 - tests/coverage/mcdc/condition-limit.rs | 1 - tests/coverage/mcdc/if.cov-map | 28 +++--- tests/coverage/mcdc/if.coverage | 1 - tests/coverage/mcdc/if.rs | 1 - tests/coverage/mcdc/inlined_expressions.cov-map | 4 +- tests/coverage/mcdc/inlined_expressions.coverage | 1 - tests/coverage/mcdc/inlined_expressions.rs | 1 - tests/coverage/mcdc/nested_if.cov-map | 16 ++-- tests/coverage/mcdc/nested_if.coverage | 1 - tests/coverage/mcdc/nested_if.rs | 1 - tests/coverage/mcdc/non_control_flow.cov-map | 28 +++--- tests/coverage/mcdc/non_control_flow.coverage | 1 - tests/coverage/mcdc/non_control_flow.rs | 1 - tests/coverage/no_cov_crate.cov-map | 28 +++--- tests/coverage/no_cov_crate.coverage | 1 - tests/coverage/no_cov_crate.rs | 1 - tests/coverage/no_spans.cov-map | 8 +- tests/coverage/no_spans.coverage | 1 - tests/coverage/no_spans.rs | 1 - tests/coverage/unreachable.cov-map | 12 +-- tests/coverage/unreachable.coverage | 1 - tests/coverage/unreachable.rs | 1 - .../branch_match_arms.main.InstrumentCoverage.diff | 14 +-- tests/mir-opt/coverage/branch_match_arms.rs | 1 - tests/ui/coverage-attr/bad-attr-ice.feat.stderr | 15 ---- tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr | 26 ------ tests/ui/coverage-attr/bad-attr-ice.rs | 6 -- tests/ui/coverage-attr/bad-attr-ice.stderr | 15 ++++ tests/ui/coverage-attr/bad-syntax.rs | 1 - tests/ui/coverage-attr/bad-syntax.stderr | 26 +++--- tests/ui/coverage-attr/name-value.rs | 1 - tests/ui/coverage-attr/name-value.stderr | 38 ++++---- tests/ui/coverage-attr/no-coverage.rs | 1 - tests/ui/coverage-attr/no-coverage.stderr | 22 ++--- tests/ui/coverage-attr/subword.rs | 1 - tests/ui/coverage-attr/subword.stderr | 8 +- tests/ui/coverage-attr/word-only.rs | 1 - tests/ui/coverage-attr/word-only.stderr | 38 ++++---- .../feature-gate-coverage-attribute.rs | 14 --- .../feature-gate-coverage-attribute.stderr | 22 ----- tests/ui/feature-gates/feature-gate-no-coverage.rs | 14 +++ .../feature-gates/feature-gate-no-coverage.stderr | 11 +++ 131 files changed, 400 insertions(+), 543 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/coverage-attribute.md delete mode 100644 tests/ui/coverage-attr/bad-attr-ice.feat.stderr delete mode 100644 tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr create mode 100644 tests/ui/coverage-attr/bad-attr-ice.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-coverage-attribute.rs delete mode 100644 tests/ui/feature-gates/feature-gate-coverage-attribute.stderr create mode 100644 tests/ui/feature-gates/feature-gate-no-coverage.rs create mode 100644 tests/ui/feature-gates/feature-gate-no-coverage.stderr (limited to 'src/tools') diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index c5913ed27cf..26ae541d08b 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -157,6 +157,9 @@ declare_features! ( (accepted, const_refs_to_static, "1.83.0", Some(119618)), /// Allows implementing `Copy` for closures where possible (RFC 2132). (accepted, copy_closures, "1.26.0", Some(44490)), + /// Allows function attribute `#[coverage(on/off)]`, to control coverage + /// instrumentation of that function. + (accepted, coverage_attribute, "CURRENT_RUSTC_VERSION", Some(84605)), /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477)), /// Allows users to provide classes for fenced code block using `class:classname`. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 3bf485c2eb6..bf221158d57 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -480,10 +480,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(List: "address, kcfi, memory, thread"), DuplicatesOk, EncodeCrossCrate::No, experimental!(no_sanitize) ), - gated!( + ungated!( coverage, Normal, template!(OneOf: &[sym::off, sym::on]), ErrorPreceding, EncodeCrossCrate::No, - coverage_attribute, experimental!(coverage) ), ungated!( diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 76b9bee4b00..e07ddae06d5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -448,9 +448,6 @@ declare_features! ( (unstable, coroutine_clone, "1.65.0", Some(95360)), /// Allows defining coroutines. (unstable, coroutines, "1.21.0", Some(43122)), - /// Allows function attribute `#[coverage(on/off)]`, to control coverage - /// instrumentation of that function. - (unstable, coverage_attribute, "1.74.0", Some(84605)), /// Allows non-builtin attributes in inner attribute position. (unstable, custom_inner_attributes, "1.30.0", Some(54726)), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 5a3b9365cd2..66a6578fc72 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -348,7 +348,7 @@ pub trait Eq: PartialEq { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)] -#[allow_internal_unstable(coverage_attribute)] +#[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))] pub macro Eq($item:item) { /* compiler built-in */ } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d45cb01910f..922866f95dc 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -107,12 +107,12 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(coverage_attribute))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(const_eval_select)] #![feature(const_typed_swap)] #![feature(core_intrinsics)] -#![feature(coverage_attribute)] #![feature(do_not_recommend)] #![feature(internal_impls_macro)] #![feature(ip)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ab674b58902..bff7ad98df3 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1673,7 +1673,8 @@ pub(crate) mod builtin { /// /// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute #[stable(feature = "rust1", since = "1.0.0")] - #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)] + #[allow_internal_unstable(test, rustc_attrs)] + #[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))] #[rustc_builtin_macro] pub macro test($item:item) { /* compiler built-in */ @@ -1686,7 +1687,8 @@ pub(crate) mod builtin { soft, reason = "`bench` is a part of custom test frameworks which are unstable" )] - #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)] + #[allow_internal_unstable(test, rustc_attrs)] + #[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))] #[rustc_builtin_macro] pub macro bench($item:item) { /* compiler built-in */ diff --git a/src/doc/unstable-book/src/language-features/coverage-attribute.md b/src/doc/unstable-book/src/language-features/coverage-attribute.md deleted file mode 100644 index 0a9bd07de07..00000000000 --- a/src/doc/unstable-book/src/language-features/coverage-attribute.md +++ /dev/null @@ -1,30 +0,0 @@ -# `coverage_attribute` - -The tracking issue for this feature is: [#84605] - -[#84605]: https://github.com/rust-lang/rust/issues/84605 - ---- - -The `coverage` attribute can be used to selectively disable coverage -instrumentation in an annotated function. This might be useful to: - -- Avoid instrumentation overhead in a performance critical function -- Avoid generating coverage for a function that is not meant to be executed, - but still target 100% coverage for the rest of the program. - -## Example - -```rust -#![feature(coverage_attribute)] - -// `foo()` will get coverage instrumentation (by default) -fn foo() { - // ... -} - -#[coverage(off)] -fn bar() { - // ... -} -``` diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 9a7a1a01a09..2bba410de02 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -237,7 +237,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(List: "address, kcfi, memory, thread"), DuplicatesOk, experimental!(no_sanitize) ), - gated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing, coverage_attribute, experimental!(coverage)), + ungated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing), ungated!( doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index d3eed6c4f2a..9c6f4bd385f 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -1,20 +1,20 @@ Function name: async::c -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::c::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0b, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 0a, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 11, 25) to (start + 1, 14) +- Code(Counter(0)) at (prev + 10, 25) to (start + 1, 14) - Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) @@ -22,93 +22,93 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: async::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 20) Highest counter ID seen: c0 Function name: async::d::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 12, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 18, 20) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 14, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 1) to (start + 0, 20) +- Code(Zero) at (prev + 20, 1) to (start + 0, 20) Highest counter ID seen: (none) Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 14, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 21, 20) to (start + 0, 25) +- Code(Zero) at (prev + 20, 20) to (start + 0, 25) Highest counter ID seen: (none) Function name: async::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 20) Highest counter ID seen: c0 Function name: async::f::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 22, 20) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 1) to (start + 0, 30) +- Code(Zero) at (prev + 24, 1) to (start + 0, 30) Highest counter ID seen: (none) Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 1e, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 1e, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 30) to (start + 0, 45) +- Code(Zero) at (prev + 24, 30) to (start + 0, 45) Highest counter ID seen: (none) Function name: async::g -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 23) Highest counter ID seen: c0 Function name: async::g::{closure#0} (unused) -Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1b, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (59): 0x[01, 01, 00, 0b, 00, 1a, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 11 -- Code(Zero) at (prev + 27, 23) to (start + 1, 12) +- Code(Zero) at (prev + 26, 23) to (start + 1, 12) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 23) - Code(Zero) at (prev + 0, 27) to (start + 0, 28) @@ -122,21 +122,21 @@ Number of file 0 mappings: 11 Highest counter ID seen: (none) Function name: async::h -Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 01, 00, 16] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 01, 00, 16] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 35, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 22) Highest counter ID seen: c0 Function name: async::h::{closure#0} (unused) -Raw bytes (39): 0x[01, 01, 00, 07, 00, 23, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (39): 0x[01, 01, 00, 07, 00, 22, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 7 -- Code(Zero) at (prev + 35, 22) to (start + 3, 12) +- Code(Zero) at (prev + 34, 22) to (start + 3, 12) - Code(Zero) at (prev + 4, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 25) - Code(Zero) at (prev + 0, 26) to (start + 0, 27) @@ -146,23 +146,23 @@ Number of file 0 mappings: 7 Highest counter ID seen: (none) Function name: async::i -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 00, 13] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 01, 00, 13] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 43, 1) to (start + 0, 19) Highest counter ID seen: c0 Function name: async::i::{closure#0} -Raw bytes (63): 0x[01, 01, 02, 07, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 11, 01, 09, 00, 0a, 19, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 11, 00, 24, 00, 26, 15, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (63): 0x[01, 01, 02, 07, 15, 0d, 11, 0b, 01, 2b, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 11, 01, 09, 00, 0a, 19, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 11, 00, 24, 00, 26, 15, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5) - expression 1 operands: lhs = Counter(3), rhs = Counter(4) Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 44, 19) to (start + 4, 12) +- Code(Counter(0)) at (prev + 43, 19) to (start + 4, 12) - Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24) - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33) @@ -177,14 +177,14 @@ Number of file 0 mappings: 11 Highest counter ID seen: c7 Function name: async::j -Raw bytes (58): 0x[01, 01, 02, 07, 0d, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 02, 07, 0d, 05, 09, 0a, 01, 36, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 55, 1) to (start + 0, 13) +- Code(Counter(0)) at (prev + 54, 1) to (start + 0, 13) - Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12) - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) @@ -198,13 +198,13 @@ Number of file 0 mappings: 10 Highest counter ID seen: c4 Function name: async::j::c -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 38, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 57, 5) to (start + 1, 18) +- Code(Counter(0)) at (prev + 56, 5) to (start + 1, 18) - Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 14) = (c0 - c1) @@ -212,30 +212,30 @@ Number of file 0 mappings: 4 Highest counter ID seen: c1 Function name: async::j::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 3f, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 63, 5) to (start + 0, 23) Highest counter ID seen: c0 Function name: async::j::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 41, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 40, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 65, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 64, 5) to (start + 0, 23) Highest counter ID seen: c0 Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 00, 49, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 48, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 -- Code(Zero) at (prev + 73, 1) to (start + 1, 12) +- Code(Zero) at (prev + 72, 1) to (start + 1, 12) - Code(Zero) at (prev + 2, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) @@ -243,14 +243,14 @@ Number of file 0 mappings: 5 Highest counter ID seen: (none) Function name: async::l -Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 51, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] +Raw bytes (33): 0x[01, 01, 02, 01, 07, 05, 09, 05, 01, 50, 01, 01, 0c, 02, 02, 0e, 00, 10, 09, 01, 0e, 00, 10, 05, 01, 0e, 00, 10, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 81, 1) to (start + 1, 12) +- Code(Counter(0)) at (prev + 80, 1) to (start + 1, 12) - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) = (c0 - (c1 + c2)) - Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16) @@ -259,29 +259,29 @@ Number of file 0 mappings: 5 Highest counter ID seen: c2 Function name: async::m -Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 58, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 89, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 88, 1) to (start + 0, 25) Highest counter ID seen: c0 Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 59, 19, 00, 22] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 58, 19, 00, 22] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 89, 25) to (start + 0, 34) +- Code(Zero) at (prev + 88, 25) to (start + 0, 34) Highest counter ID seen: (none) Function name: async::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 08, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 5a, 01, 08, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 91, 1) to (start + 8, 2) +- Code(Counter(0)) at (prev + 90, 1) to (start + 8, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage index aee76b05fb7..cee0e1a0a85 100644 --- a/tests/coverage/async.coverage +++ b/tests/coverage/async.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |#![feature(custom_inner_attributes)] // for #![rustfmt::skip] LL| |#![allow(unused_assignments, dead_code)] LL| |#![rustfmt::skip] diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs index da0a1c0b6f0..801c98c52df 100644 --- a/tests/coverage/async.rs +++ b/tests/coverage/async.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] #![feature(custom_inner_attributes)] // for #![rustfmt::skip] #![allow(unused_assignments, dead_code)] #![rustfmt::skip] diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map index 7660f917b65..926124fdc76 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -1,58 +1,58 @@ Function name: async2::async_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 23) Highest counter ID seen: c0 Function name: async2::async_func::{closure#0} -Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 0e, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 15, 23) to (start + 3, 9) +- Code(Counter(0)) at (prev + 14, 23) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: async2::async_func_just_println -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 36) Highest counter ID seen: c0 Function name: async2::async_func_just_println::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 24, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 24, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 36) to (start + 2, 2) +- Code(Counter(0)) at (prev + 22, 36) to (start + 2, 2) Highest counter ID seen: c0 Function name: async2::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 07, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 07, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 1) to (start + 7, 2) +- Code(Counter(0)) at (prev + 26, 1) to (start + 7, 2) Highest counter ID seen: c0 Function name: async2::non_async_func -Raw bytes (24): 0x[01, 01, 00, 04, 01, 07, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 06, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 9) +- Code(Counter(0)) at (prev + 6, 1) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage index fa56072924b..0e91fa975f5 100644 --- a/tests/coverage/async2.coverage +++ b/tests/coverage/async2.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2018 LL| | LL| |//@ aux-build: executor.rs diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs index 9bd4821518a..64e85f1b6bd 100644 --- a/tests/coverage/async2.rs +++ b/tests/coverage/async2.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2018 //@ aux-build: executor.rs diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map index 14ed4850d4a..e9e7e9cd2c3 100644 --- a/tests/coverage/async_block.cov-map +++ b/tests/coverage/async_block.cov-map @@ -1,11 +1,11 @@ Function name: async_block::main -Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 07, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 06, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 11) +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 11) - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) - Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19) = (c0 + c1) @@ -15,13 +15,13 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: async_block::main::{closure#0} -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 08, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 9, 28) to (start + 1, 23) +- Code(Counter(0)) at (prev + 8, 28) to (start + 1, 23) - Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14) - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14) = (c0 - c1) diff --git a/tests/coverage/async_block.coverage b/tests/coverage/async_block.coverage index 9e3294492cd..7ccc83499e6 100644 --- a/tests/coverage/async_block.coverage +++ b/tests/coverage/async_block.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |//@ aux-build: executor.rs diff --git a/tests/coverage/async_block.rs b/tests/coverage/async_block.rs index d1e37ab7505..05a105224bb 100644 --- a/tests/coverage/async_block.rs +++ b/tests/coverage/async_block.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ aux-build: executor.rs diff --git a/tests/coverage/attr/impl.cov-map b/tests/coverage/attr/impl.cov-map index 4d068c290f4..afb91af6829 100644 --- a/tests/coverage/attr/impl.cov-map +++ b/tests/coverage/attr/impl.cov-map @@ -1,27 +1,27 @@ Function name: ::off_on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 05, 00, 13] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0d, 05, 00, 13] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 14, 5) to (start + 0, 19) +- Code(Zero) at (prev + 13, 5) to (start + 0, 19) Highest counter ID seen: (none) Function name: ::on_inherit (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 22, 5) to (start + 0, 23) +- Code(Zero) at (prev + 21, 5) to (start + 0, 23) Highest counter ID seen: (none) Function name: ::on_on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 12] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 05, 00, 12] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 5) to (start + 0, 18) +- Code(Zero) at (prev + 24, 5) to (start + 0, 18) Highest counter ID seen: (none) diff --git a/tests/coverage/attr/impl.coverage b/tests/coverage/attr/impl.coverage index 560429fb5fe..205b9e830a5 100644 --- a/tests/coverage/attr/impl.coverage +++ b/tests/coverage/attr/impl.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Checks that `#[coverage(..)]` can be applied to impl and impl-trait blocks, diff --git a/tests/coverage/attr/impl.rs b/tests/coverage/attr/impl.rs index d4d784a3502..8c1f991926d 100644 --- a/tests/coverage/attr/impl.rs +++ b/tests/coverage/attr/impl.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Checks that `#[coverage(..)]` can be applied to impl and impl-trait blocks, diff --git a/tests/coverage/attr/module.cov-map b/tests/coverage/attr/module.cov-map index b318ac85a6c..3efc745dba3 100644 --- a/tests/coverage/attr/module.cov-map +++ b/tests/coverage/attr/module.cov-map @@ -1,27 +1,27 @@ Function name: module::off::on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0c, 05, 00, 0f] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 00, 0f] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 12, 5) to (start + 0, 15) +- Code(Zero) at (prev + 11, 5) to (start + 0, 15) Highest counter ID seen: (none) Function name: module::on::inherit (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 14, 05, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 05, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 20, 5) to (start + 0, 20) +- Code(Zero) at (prev + 19, 5) to (start + 0, 20) Highest counter ID seen: (none) Function name: module::on::on (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 0f] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 05, 00, 0f] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 23, 5) to (start + 0, 15) +- Code(Zero) at (prev + 22, 5) to (start + 0, 15) Highest counter ID seen: (none) diff --git a/tests/coverage/attr/module.coverage b/tests/coverage/attr/module.coverage index c1b9f0e35c0..acad0312069 100644 --- a/tests/coverage/attr/module.coverage +++ b/tests/coverage/attr/module.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Checks that `#[coverage(..)]` can be applied to modules, and is inherited diff --git a/tests/coverage/attr/module.rs b/tests/coverage/attr/module.rs index 4bfb1e7729b..ed530d53e47 100644 --- a/tests/coverage/attr/module.rs +++ b/tests/coverage/attr/module.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Checks that `#[coverage(..)]` can be applied to modules, and is inherited diff --git a/tests/coverage/attr/nested.coverage b/tests/coverage/attr/nested.coverage index 2d64fe698ea..1e2525eb860 100644 --- a/tests/coverage/attr/nested.coverage +++ b/tests/coverage/attr/nested.coverage @@ -1,4 +1,4 @@ - LL| |#![feature(coverage_attribute, stmt_expr_attributes)] + LL| |#![feature(stmt_expr_attributes)] LL| |//@ edition: 2021 LL| | LL| |// Demonstrates the interaction between #[coverage(off)] and various kinds of diff --git a/tests/coverage/attr/nested.rs b/tests/coverage/attr/nested.rs index 8213e29b6fc..019f07428c1 100644 --- a/tests/coverage/attr/nested.rs +++ b/tests/coverage/attr/nested.rs @@ -1,4 +1,4 @@ -#![feature(coverage_attribute, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] //@ edition: 2021 // Demonstrates the interaction between #[coverage(off)] and various kinds of diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map index ae5c9bd19a2..d7972d0cc9e 100644 --- a/tests/coverage/attr/off-on-sandwich.cov-map +++ b/tests/coverage/attr/off-on-sandwich.cov-map @@ -1,30 +1,30 @@ Function name: off_on_sandwich::dense_a::dense_b -Raw bytes (14): 0x[01, 01, 00, 02, 01, 0f, 05, 02, 12, 01, 07, 05, 00, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0e, 05, 02, 12, 01, 07, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 15, 5) to (start + 2, 18) +- Code(Counter(0)) at (prev + 14, 5) to (start + 2, 18) - Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c -Raw bytes (14): 0x[01, 01, 00, 02, 01, 21, 09, 02, 17, 01, 0b, 09, 00, 0a] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 20, 09, 02, 17, 01, 0b, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 33, 9) to (start + 2, 23) +- Code(Counter(0)) at (prev + 32, 9) to (start + 2, 23) - Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10) Highest counter ID seen: c0 Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d -Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 0d, 02, 1b, 01, 07, 0d, 00, 0e] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 23, 0d, 02, 1b, 01, 07, 0d, 00, 0e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 36, 13) to (start + 2, 27) +- Code(Counter(0)) at (prev + 35, 13) to (start + 2, 27) - Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14) Highest counter ID seen: c0 diff --git a/tests/coverage/attr/off-on-sandwich.coverage b/tests/coverage/attr/off-on-sandwich.coverage index 675697906ee..f23c248c0eb 100644 --- a/tests/coverage/attr/off-on-sandwich.coverage +++ b/tests/coverage/attr/off-on-sandwich.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]` diff --git a/tests/coverage/attr/off-on-sandwich.rs b/tests/coverage/attr/off-on-sandwich.rs index 261634e0029..4272365d87d 100644 --- a/tests/coverage/attr/off-on-sandwich.rs +++ b/tests/coverage/attr/off-on-sandwich.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]` diff --git a/tests/coverage/auxiliary/executor.rs b/tests/coverage/auxiliary/executor.rs index c282414fb8e..ed1fe032ef4 100644 --- a/tests/coverage/auxiliary/executor.rs +++ b/tests/coverage/auxiliary/executor.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 use core::future::Future; diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map index bc1af4e42e8..ea16b36b616 100644 --- a/tests/coverage/await_ready.cov-map +++ b/tests/coverage/await_ready.cov-map @@ -1,19 +1,19 @@ Function name: await_ready::await_ready -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0e, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 30) +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 30) Highest counter ID seen: c0 Function name: await_ready::await_ready::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 0e, 1e, 03, 0f, 05, 04, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0d, 1e, 03, 0f, 05, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 14, 30) to (start + 3, 15) +- Code(Counter(0)) at (prev + 13, 30) to (start + 3, 15) - Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/await_ready.coverage b/tests/coverage/await_ready.coverage index 1150d807e76..40107a92e41 100644 --- a/tests/coverage/await_ready.coverage +++ b/tests/coverage/await_ready.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |#![coverage(off)] LL| |//@ edition: 2021 LL| | diff --git a/tests/coverage/await_ready.rs b/tests/coverage/await_ready.rs index 9eaa31dedda..8fbdf7b8004 100644 --- a/tests/coverage/await_ready.rs +++ b/tests/coverage/await_ready.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] #![coverage(off)] //@ edition: 2021 diff --git a/tests/coverage/bad_counter_ids.cov-map b/tests/coverage/bad_counter_ids.cov-map index 2b5399f33bb..ae9db139e3d 100644 --- a/tests/coverage/bad_counter_ids.cov-map +++ b/tests/coverage/bad_counter_ids.cov-map @@ -1,88 +1,88 @@ Function name: bad_counter_ids::eq_bad -Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 01, 02, 1f, 00, 03, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 23, 01, 02, 1f, 00, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 31) +- Code(Counter(0)) at (prev + 35, 1) to (start + 2, 31) - Code(Zero) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::eq_bad_message -Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 29, 01, 02, 0f, 02, 02, 20, 00, 2b, 00, 01, 01, 00, 02] +Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 28, 01, 02, 0f, 02, 02, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15) +- Code(Counter(0)) at (prev + 40, 1) to (start + 2, 15) - Code(Expression(0, Sub)) at (prev + 2, 32) to (start + 0, 43) = (c0 - Zero) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::eq_good -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 02, 1f, 05, 03, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0f, 01, 02, 1f, 05, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 2, 31) +- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 31) - Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: bad_counter_ids::eq_good_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 05, 01, 01, 00, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 14, 01, 02, 0f, 00, 02, 20, 00, 2b, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15) +- Code(Counter(0)) at (prev + 20, 1) to (start + 2, 15) - Code(Zero) at (prev + 2, 32) to (start + 0, 43) - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: bad_counter_ids::ne_bad -Raw bytes (14): 0x[01, 01, 00, 02, 01, 2e, 01, 02, 1f, 00, 03, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 2d, 01, 02, 1f, 00, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 46, 1) to (start + 2, 31) +- Code(Counter(0)) at (prev + 45, 1) to (start + 2, 31) - Code(Zero) at (prev + 3, 1) to (start + 0, 2) Highest counter ID seen: c0 Function name: bad_counter_ids::ne_bad_message -Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 05, 02, 20, 00, 2b, 00, 01, 01, 00, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 32, 01, 02, 0f, 05, 02, 20, 00, 2b, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15) +- Code(Counter(0)) at (prev + 50, 1) to (start + 2, 15) - Code(Counter(1)) at (prev + 2, 32) to (start + 0, 43) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: bad_counter_ids::ne_good -Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 1a, 01, 02, 1f, 02, 03, 01, 00, 02] +Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 19, 01, 02, 1f, 02, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 31) +- Code(Counter(0)) at (prev + 25, 1) to (start + 2, 31) - Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2) = (c0 - Zero) Highest counter ID seen: c0 Function name: bad_counter_ids::ne_good_message -Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 02, 01, 01, 00, 02] +Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 1e, 01, 02, 0f, 00, 02, 20, 00, 2b, 02, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15) +- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 15) - Code(Zero) at (prev + 2, 32) to (start + 0, 43) - Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2) = (c0 - Zero) diff --git a/tests/coverage/bad_counter_ids.coverage b/tests/coverage/bad_counter_ids.coverage index f6c69913cdd..eede634923d 100644 --- a/tests/coverage/bad_counter_ids.coverage +++ b/tests/coverage/bad_counter_ids.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Copt-level=0 -Zmir-opt-level=3 LL| | diff --git a/tests/coverage/bad_counter_ids.rs b/tests/coverage/bad_counter_ids.rs index ef31d682e4f..8fa0d83bf20 100644 --- a/tests/coverage/bad_counter_ids.rs +++ b/tests/coverage/bad_counter_ids.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Copt-level=0 -Zmir-opt-level=3 diff --git a/tests/coverage/branch/generics.cov-map b/tests/coverage/branch/generics.cov-map index 656890634ff..9ff8e29f9e7 100644 --- a/tests/coverage/branch/generics.cov-map +++ b/tests/coverage/branch/generics.cov-map @@ -1,11 +1,11 @@ Function name: generics::print_size::<()> -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 36) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) true = c1 false = (c0 - c1) @@ -16,13 +16,13 @@ Number of file 0 mappings: 5 Highest counter ID seen: c1 Function name: generics::print_size:: -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 36) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) true = c1 false = (c0 - c1) @@ -33,13 +33,13 @@ Number of file 0 mappings: 5 Highest counter ID seen: c1 Function name: generics::print_size:: -Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 05, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Code(Counter(0)) at (prev + 5, 1) to (start + 1, 36) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) true = c1 false = (c0 - c1) diff --git a/tests/coverage/branch/generics.coverage b/tests/coverage/branch/generics.coverage index 85f73d45f65..849ddfa7a72 100644 --- a/tests/coverage/branch/generics.coverage +++ b/tests/coverage/branch/generics.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/generics.rs b/tests/coverage/branch/generics.rs index d870ace7006..24bfdaaa687 100644 --- a/tests/coverage/branch/generics.rs +++ b/tests/coverage/branch/generics.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map index 7ca499bd847..9e02240f1a2 100644 --- a/tests/coverage/branch/guard.cov-map +++ b/tests/coverage/branch/guard.cov-map @@ -1,5 +1,5 @@ Function name: guard::branch_match_guard -Raw bytes (89): 0x[01, 01, 08, 05, 0d, 05, 17, 0d, 11, 1f, 17, 05, 09, 0d, 11, 1f, 15, 05, 09, 0d, 01, 0c, 01, 01, 10, 02, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 06, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 0e, 03, 0e, 02, 0a, 1b, 04, 01, 00, 02] +Raw bytes (89): 0x[01, 01, 08, 05, 0d, 05, 17, 0d, 11, 1f, 17, 05, 09, 0d, 11, 1f, 15, 05, 09, 0d, 01, 0b, 01, 01, 10, 02, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 06, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 0e, 03, 0e, 02, 0a, 1b, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 @@ -12,7 +12,7 @@ Number of expressions: 8 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(5) - expression 7 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 16) - Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12) = (c1 - c3) - Code(Counter(5)) at (prev + 1, 20) to (start + 2, 10) diff --git a/tests/coverage/branch/guard.coverage b/tests/coverage/branch/guard.coverage index f89b965b5d0..3376209d373 100644 --- a/tests/coverage/branch/guard.coverage +++ b/tests/coverage/branch/guard.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/guard.rs b/tests/coverage/branch/guard.rs index fa049e6206d..78b79a62946 100644 --- a/tests/coverage/branch/guard.rs +++ b/tests/coverage/branch/guard.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/if-let.coverage b/tests/coverage/branch/if-let.coverage index 9a3f0113f75..368597f1daa 100644 --- a/tests/coverage/branch/if-let.coverage +++ b/tests/coverage/branch/if-let.coverage @@ -1,4 +1,4 @@ - LL| |#![feature(coverage_attribute, let_chains)] + LL| |#![feature(let_chains)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/if-let.rs b/tests/coverage/branch/if-let.rs index 13db00a82b1..1ac506964b1 100644 --- a/tests/coverage/branch/if-let.rs +++ b/tests/coverage/branch/if-let.rs @@ -1,4 +1,4 @@ -#![feature(coverage_attribute, let_chains)] +#![feature(let_chains)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map index 3d9a1d2e1ab..bd507c5a324 100644 --- a/tests/coverage/branch/if.cov-map +++ b/tests/coverage/branch/if.cov-map @@ -1,5 +1,5 @@ Function name: if::branch_and -Raw bytes (54): 0x[01, 01, 03, 05, 09, 09, 0d, 05, 0d, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 0d, 06, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 05, 03, 01, 00, 02] +Raw bytes (54): 0x[01, 01, 03, 05, 09, 09, 0d, 05, 0d, 08, 01, 2a, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 0d, 06, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 05, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -7,7 +7,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(2), rhs = Counter(3) - expression 2 operands: lhs = Counter(1), rhs = Counter(3) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 42, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c2 @@ -23,7 +23,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c3 Function name: if::branch_not -Raw bytes (116): 0x[01, 01, 07, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 05, 15, 05, 15, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 05, 00, 06, 05, 01, 08, 00, 0a, 20, 0a, 0d, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 0d, 02, 05, 00, 06, 05, 01, 08, 00, 0b, 20, 11, 12, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 05, 01, 08, 00, 0c, 20, 1a, 15, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 15, 02, 05, 00, 06, 05, 01, 01, 00, 02] +Raw bytes (116): 0x[01, 01, 07, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 05, 15, 05, 15, 12, 01, 0b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 05, 00, 06, 05, 01, 08, 00, 0a, 20, 0a, 0d, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 0d, 02, 05, 00, 06, 05, 01, 08, 00, 0b, 20, 11, 12, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 05, 01, 08, 00, 0c, 20, 1a, 15, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 15, 02, 05, 00, 06, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 7 @@ -35,7 +35,7 @@ Number of expressions: 7 - expression 5 operands: lhs = Counter(1), rhs = Counter(5) - expression 6 operands: lhs = Counter(1), rhs = Counter(5) Number of file 0 mappings: 18 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c2 @@ -68,7 +68,7 @@ Number of file 0 mappings: 18 Highest counter ID seen: c5 Function name: if::branch_not_as -Raw bytes (90): 0x[01, 01, 05, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 05, 00, 06, 05, 01, 08, 00, 15, 20, 0d, 0a, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 05, 01, 08, 00, 16, 20, 12, 11, 00, 08, 00, 16, 12, 00, 17, 02, 06, 11, 02, 05, 00, 06, 05, 01, 01, 00, 02] +Raw bytes (90): 0x[01, 01, 05, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 0e, 01, 1c, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 05, 00, 06, 05, 01, 08, 00, 15, 20, 0d, 0a, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 05, 01, 08, 00, 16, 20, 12, 11, 00, 08, 00, 16, 12, 00, 17, 02, 06, 11, 02, 05, 00, 06, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 5 @@ -78,7 +78,7 @@ Number of expressions: 5 - expression 3 operands: lhs = Counter(1), rhs = Counter(4) - expression 4 operands: lhs = Counter(1), rhs = Counter(4) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 28, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 8) to (start + 0, 20) - Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 0, 8) to (start + 0, 20) true = (c1 - c2) @@ -104,7 +104,7 @@ Number of file 0 mappings: 14 Highest counter ID seen: c4 Function name: if::branch_or -Raw bytes (60): 0x[01, 01, 06, 05, 09, 05, 17, 09, 0d, 09, 0d, 05, 17, 09, 0d, 08, 01, 35, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 0d, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 05, 03, 01, 00, 02] +Raw bytes (60): 0x[01, 01, 06, 05, 09, 05, 17, 09, 0d, 09, 0d, 05, 17, 09, 0d, 08, 01, 34, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 0d, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 05, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 6 @@ -115,7 +115,7 @@ Number of expressions: 6 - expression 4 operands: lhs = Counter(1), rhs = Expression(5, Add) - expression 5 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 52, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) true = c2 diff --git a/tests/coverage/branch/if.coverage b/tests/coverage/branch/if.coverage index 3d107188ca6..fd0a3d87a8d 100644 --- a/tests/coverage/branch/if.coverage +++ b/tests/coverage/branch/if.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/if.rs b/tests/coverage/branch/if.rs index 151eede75bb..9e06ffc1aa5 100644 --- a/tests/coverage/branch/if.rs +++ b/tests/coverage/branch/if.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map index 94522734bcd..70819505485 100644 --- a/tests/coverage/branch/lazy-boolean.cov-map +++ b/tests/coverage/branch/lazy-boolean.cov-map @@ -1,11 +1,11 @@ Function name: lazy_boolean::branch_and -Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 13, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 05, 01, 05, 01, 02] +Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 12, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 05, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 18, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -16,13 +16,13 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: lazy_boolean::branch_or -Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 1b, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 05, 01, 05, 01, 02] +Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 1a, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 05, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 26, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -34,7 +34,7 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: lazy_boolean::chain -Raw bytes (141): 0x[01, 01, 0f, 05, 09, 09, 0d, 0d, 11, 05, 15, 05, 15, 05, 3b, 15, 19, 05, 3b, 15, 19, 05, 37, 3b, 1d, 15, 19, 05, 37, 3b, 1d, 15, 19, 13, 01, 24, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 02, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 06, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 0a, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 15, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 19, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 1d, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 05, 01, 05, 01, 02] +Raw bytes (141): 0x[01, 01, 0f, 05, 09, 09, 0d, 0d, 11, 05, 15, 05, 15, 05, 3b, 15, 19, 05, 3b, 15, 19, 05, 37, 3b, 1d, 15, 19, 05, 37, 3b, 1d, 15, 19, 13, 01, 23, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 02, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 06, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 0a, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 15, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 19, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 1d, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 05, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 15 @@ -54,7 +54,7 @@ Number of expressions: 15 - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7) - expression 14 operands: lhs = Counter(5), rhs = Counter(6) Number of file 0 mappings: 19 -- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 35, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10) - Code(Counter(1)) at (prev + 0, 13) to (start + 0, 18) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18) @@ -91,7 +91,7 @@ Number of file 0 mappings: 19 Highest counter ID seen: c7 Function name: lazy_boolean::nested_mixed -Raw bytes (137): 0x[01, 01, 0d, 05, 09, 05, 1f, 09, 0d, 09, 0d, 1f, 11, 09, 0d, 1f, 11, 09, 0d, 05, 15, 15, 19, 05, 19, 05, 33, 19, 1d, 13, 01, 31, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 0d, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 11, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 15, 22, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 1d, 2e, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 05, 01, 05, 01, 02] +Raw bytes (137): 0x[01, 01, 0d, 05, 09, 05, 1f, 09, 0d, 09, 0d, 1f, 11, 09, 0d, 1f, 11, 09, 0d, 05, 15, 15, 19, 05, 19, 05, 33, 19, 1d, 13, 01, 30, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 0d, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 11, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 15, 22, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 1d, 2e, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 05, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 13 @@ -109,7 +109,7 @@ Number of expressions: 13 - expression 11 operands: lhs = Counter(1), rhs = Expression(12, Add) - expression 12 operands: lhs = Counter(6), rhs = Counter(7) Number of file 0 mappings: 19 -- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10) - Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) - Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19) diff --git a/tests/coverage/branch/lazy-boolean.coverage b/tests/coverage/branch/lazy-boolean.coverage index f6aba1da46e..6e5dfbd19f3 100644 --- a/tests/coverage/branch/lazy-boolean.coverage +++ b/tests/coverage/branch/lazy-boolean.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/lazy-boolean.rs b/tests/coverage/branch/lazy-boolean.rs index 3c73fc1a87d..68267bf56ed 100644 --- a/tests/coverage/branch/lazy-boolean.rs +++ b/tests/coverage/branch/lazy-boolean.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map index e6bf7ed6a92..466de5d5de3 100644 --- a/tests/coverage/branch/let-else.cov-map +++ b/tests/coverage/branch/let-else.cov-map @@ -1,11 +1,11 @@ Function name: let_else::let_else -Raw bytes (43): 0x[01, 01, 01, 05, 09, 07, 01, 0c, 01, 01, 10, 20, 02, 09, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 05, 01, 01, 00, 02] +Raw bytes (43): 0x[01, 01, 01, 05, 09, 07, 01, 0b, 01, 01, 10, 20, 02, 09, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 16) - Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 3, 9) to (start + 0, 16) true = (c1 - c2) false = c2 diff --git a/tests/coverage/branch/let-else.coverage b/tests/coverage/branch/let-else.coverage index 22ad8f2b0e1..f0549205590 100644 --- a/tests/coverage/branch/let-else.coverage +++ b/tests/coverage/branch/let-else.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/let-else.rs b/tests/coverage/branch/let-else.rs index af0665d8241..0d23d956541 100644 --- a/tests/coverage/branch/let-else.rs +++ b/tests/coverage/branch/let-else.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map index 53d0a4edbd0..5d9f94923bc 100644 --- a/tests/coverage/branch/match-arms.cov-map +++ b/tests/coverage/branch/match-arms.cov-map @@ -1,5 +1,5 @@ Function name: match_arms::guards -Raw bytes (98): 0x[01, 01, 0d, 11, 19, 27, 19, 2b, 00, 2f, 11, 33, 0d, 05, 09, 1f, 25, 23, 21, 27, 1d, 2b, 00, 2f, 11, 33, 0d, 05, 09, 0c, 01, 30, 01, 01, 10, 11, 03, 0b, 00, 10, 1d, 01, 11, 00, 29, 20, 1d, 05, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 09, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 0d, 00, 17, 00, 1b, 19, 01, 11, 00, 29, 20, 19, 02, 00, 17, 00, 1b, 06, 01, 0e, 00, 18, 1b, 03, 05, 01, 02] +Raw bytes (98): 0x[01, 01, 0d, 11, 19, 27, 19, 2b, 00, 2f, 11, 33, 0d, 05, 09, 1f, 25, 23, 21, 27, 1d, 2b, 00, 2f, 11, 33, 0d, 05, 09, 0c, 01, 2f, 01, 01, 10, 11, 03, 0b, 00, 10, 1d, 01, 11, 00, 29, 20, 1d, 05, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 09, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 0d, 00, 17, 00, 1b, 19, 01, 11, 00, 29, 20, 19, 02, 00, 17, 00, 1b, 06, 01, 0e, 00, 18, 1b, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 13 @@ -17,7 +17,7 @@ Number of expressions: 13 - expression 11 operands: lhs = Expression(12, Add), rhs = Counter(3) - expression 12 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 12 -- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 47, 1) to (start + 1, 16) - Code(Counter(4)) at (prev + 3, 11) to (start + 0, 16) - Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41) - Branch { true: Counter(7), false: Counter(1) } at (prev + 0, 23) to (start + 0, 27) @@ -42,7 +42,7 @@ Number of file 0 mappings: 12 Highest counter ID seen: c9 Function name: match_arms::match_arms -Raw bytes (45): 0x[01, 01, 03, 05, 07, 0b, 11, 09, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 11, 01, 11, 00, 21, 02, 01, 11, 00, 21, 05, 03, 05, 01, 02] +Raw bytes (45): 0x[01, 01, 03, 05, 07, 0b, 11, 09, 0d, 07, 01, 17, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 11, 01, 11, 00, 21, 02, 01, 11, 00, 21, 05, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -50,7 +50,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) - expression 2 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 23, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16) - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33) - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33) @@ -61,7 +61,7 @@ Number of file 0 mappings: 7 Highest counter ID seen: c4 Function name: match_arms::or_patterns -Raw bytes (57): 0x[01, 01, 04, 09, 0d, 05, 0b, 03, 11, 05, 03, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 11, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 05, 03, 05, 01, 02] +Raw bytes (57): 0x[01, 01, 04, 09, 0d, 05, 0b, 03, 11, 05, 03, 09, 01, 24, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 11, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 05, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -70,7 +70,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(4) - expression 3 operands: lhs = Counter(1), rhs = Expression(0, Add) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16) - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) - Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31) diff --git a/tests/coverage/branch/match-arms.coverage b/tests/coverage/branch/match-arms.coverage index ea8a6f97ab1..bc797d55a53 100644 --- a/tests/coverage/branch/match-arms.coverage +++ b/tests/coverage/branch/match-arms.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/match-arms.rs b/tests/coverage/branch/match-arms.rs index 63151f59ffe..6292a9c2050 100644 --- a/tests/coverage/branch/match-arms.rs +++ b/tests/coverage/branch/match-arms.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map index 6af8ce46f5f..0a1d8cef050 100644 --- a/tests/coverage/branch/match-trivial.cov-map +++ b/tests/coverage/branch/match-trivial.cov-map @@ -1,19 +1,19 @@ Function name: match_trivial::_uninhabited (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 10] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 10] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 22, 1) to (start + 1, 16) +- Code(Zero) at (prev + 21, 1) to (start + 1, 16) Highest counter ID seen: (none) Function name: match_trivial::trivial -Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 05, 03, 0b, 05, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 1d, 01, 01, 10, 05, 03, 0b, 05, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 11) to (start + 5, 2) Highest counter ID seen: c1 diff --git a/tests/coverage/branch/match-trivial.coverage b/tests/coverage/branch/match-trivial.coverage index 4ffb172e1b6..bd6be9ea3b5 100644 --- a/tests/coverage/branch/match-trivial.coverage +++ b/tests/coverage/branch/match-trivial.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/match-trivial.rs b/tests/coverage/branch/match-trivial.rs index db8887a26b7..62680916d5c 100644 --- a/tests/coverage/branch/match-trivial.rs +++ b/tests/coverage/branch/match-trivial.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map index 6003efc36ca..15ead0726e1 100644 --- a/tests/coverage/branch/no-mir-spans.cov-map +++ b/tests/coverage/branch/no-mir-spans.cov-map @@ -1,35 +1,35 @@ Function name: no_mir_spans::while_cond -Raw bytes (16): 0x[01, 01, 00, 02, 01, 10, 01, 00, 11, 20, 05, 09, 04, 0b, 00, 10] +Raw bytes (16): 0x[01, 01, 00, 02, 01, 0f, 01, 00, 11, 20, 05, 09, 04, 0b, 00, 10] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 17) +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 17) - Branch { true: Counter(1), false: Counter(2) } at (prev + 4, 11) to (start + 0, 16) true = c1 false = c2 Highest counter ID seen: c2 Function name: no_mir_spans::while_cond_not -Raw bytes (16): 0x[01, 01, 00, 02, 01, 19, 01, 00, 15, 20, 09, 05, 04, 0b, 00, 14] +Raw bytes (16): 0x[01, 01, 00, 02, 01, 18, 01, 00, 15, 20, 09, 05, 04, 0b, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 25, 1) to (start + 0, 21) +- Code(Counter(0)) at (prev + 24, 1) to (start + 0, 21) - Branch { true: Counter(2), false: Counter(1) } at (prev + 4, 11) to (start + 0, 20) true = c2 false = c1 Highest counter ID seen: c2 Function name: no_mir_spans::while_op_and -Raw bytes (25): 0x[01, 01, 01, 05, 09, 03, 01, 22, 01, 00, 13, 20, 05, 0d, 05, 0b, 00, 10, 20, 02, 09, 00, 14, 00, 19] +Raw bytes (25): 0x[01, 01, 01, 05, 09, 03, 01, 21, 01, 00, 13, 20, 05, 0d, 05, 0b, 00, 10, 20, 02, 09, 00, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 19) - Branch { true: Counter(1), false: Counter(3) } at (prev + 5, 11) to (start + 0, 16) true = c1 false = c3 @@ -39,13 +39,13 @@ Number of file 0 mappings: 3 Highest counter ID seen: c3 Function name: no_mir_spans::while_op_or -Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 2d, 01, 00, 12, 20, 05, 09, 05, 0b, 00, 10, 20, 0d, 02, 00, 14, 00, 19] +Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 2c, 01, 00, 12, 20, 05, 09, 05, 0b, 00, 10, 20, 0d, 02, 00, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 45, 1) to (start + 0, 18) +- Code(Counter(0)) at (prev + 44, 1) to (start + 0, 18) - Branch { true: Counter(1), false: Counter(2) } at (prev + 5, 11) to (start + 0, 16) true = c1 false = c2 diff --git a/tests/coverage/branch/no-mir-spans.coverage b/tests/coverage/branch/no-mir-spans.coverage index 2cae98ed3ff..be5a1ef3442 100644 --- a/tests/coverage/branch/no-mir-spans.coverage +++ b/tests/coverage/branch/no-mir-spans.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch,no-mir-spans LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/no-mir-spans.rs b/tests/coverage/branch/no-mir-spans.rs index acb268f2d45..47b4d1eff58 100644 --- a/tests/coverage/branch/no-mir-spans.rs +++ b/tests/coverage/branch/no-mir-spans.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch,no-mir-spans //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map index 5eb08a42803..f2956efade1 100644 --- a/tests/coverage/branch/while.cov-map +++ b/tests/coverage/branch/while.cov-map @@ -1,11 +1,11 @@ Function name: while::while_cond -Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 0c, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 10, 20, 09, 05, 00, 0b, 00, 10, 09, 00, 11, 02, 06, 05, 03, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 0b, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 10, 20, 09, 05, 00, 0b, 00, 10, 09, 00, 11, 02, 06, 05, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18) - Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 16) = (c1 + c2) @@ -17,13 +17,13 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: while::while_cond_not -Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 15, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 14, 20, 09, 05, 00, 0b, 00, 14, 09, 00, 15, 02, 06, 05, 03, 01, 00, 02] +Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 14, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 14, 20, 09, 05, 00, 0b, 00, 14, 09, 00, 15, 02, 06, 05, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 20, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18) - Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 20) = (c1 + c2) @@ -35,7 +35,7 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: while::while_op_and -Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 05, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 0e, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 05, 04, 01, 00, 02] +Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 05, 0d, 08, 01, 1d, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 0e, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 05, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -44,7 +44,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 3 operands: lhs = Counter(1), rhs = Counter(3) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16) = (c1 + c2) @@ -61,7 +61,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c3 Function name: while::while_op_or -Raw bytes (58): 0x[01, 01, 05, 07, 0d, 05, 09, 05, 0d, 05, 0d, 09, 0d, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 0f, 00, 0b, 00, 10, 0f, 00, 14, 00, 19, 20, 0d, 05, 00, 14, 00, 19, 13, 00, 1a, 03, 06, 05, 04, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 05, 07, 0d, 05, 09, 05, 0d, 05, 0d, 09, 0d, 08, 01, 28, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 0f, 00, 0b, 00, 10, 0f, 00, 14, 00, 19, 20, 0d, 05, 00, 14, 00, 19, 13, 00, 1a, 03, 06, 05, 04, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 5 @@ -71,7 +71,7 @@ Number of expressions: 5 - expression 3 operands: lhs = Counter(1), rhs = Counter(3) - expression 4 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 40, 1) to (start + 1, 16) - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16) = ((c1 + c2) + c3) diff --git a/tests/coverage/branch/while.coverage b/tests/coverage/branch/while.coverage index 8d9a6c3bc68..b16c8d7defd 100644 --- a/tests/coverage/branch/while.coverage +++ b/tests/coverage/branch/while.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=branch LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/branch/while.rs b/tests/coverage/branch/while.rs index 507815fbecb..e7180c43a5e 100644 --- a/tests/coverage/branch/while.rs +++ b/tests/coverage/branch/while.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=branch //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 1bd1460a147..6a36ce2e5fe 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -1,29 +1,29 @@ Function name: closure_macro_async::load_configuration_files -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 20, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 32, 1) to (start + 2, 2) Highest counter ID seen: c0 Function name: closure_macro_async::test -Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 00, 2b] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 37, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 43) Highest counter ID seen: c0 Function name: closure_macro_async::test::{closure#0} -Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 25, 2b, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 24, 2b, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 37, 43) to (start + 1, 33) +- Code(Counter(0)) at (prev + 36, 43) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(0)) at (prev + 0, 18) to (start + 0, 84) @@ -34,7 +34,7 @@ Number of file 0 mappings: 6 Highest counter ID seen: c1 Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 14, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] +Raw bytes (35): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 05, 01, 13, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 06, 00, 17, 00, 1e, 01, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -42,7 +42,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 20, 28) to (start + 3, 33) +- Code(Counter(0)) at (prev + 19, 28) to (start + 3, 33) - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) - Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22) = (c0 - c1) diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage index 1e1ffec9f76..efa40489bcf 100644 --- a/tests/coverage/closure_macro_async.coverage +++ b/tests/coverage/closure_macro_async.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2018 LL| | LL| |//@ aux-build: executor.rs diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs index 5dbb438424d..1f67f2623a1 100644 --- a/tests/coverage/closure_macro_async.rs +++ b/tests/coverage/closure_macro_async.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2018 //@ aux-build: executor.rs diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map index 9a66e0b0e77..0d108b3dcc7 100644 --- a/tests/coverage/closure_unit_return.cov-map +++ b/tests/coverage/closure_unit_return.cov-map @@ -1,38 +1,38 @@ Function name: closure_unit_return::explicit_unit -Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 06, 01, 01, 10, 01, 05, 05, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 16) - Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2) Highest counter ID seen: c0 Function name: closure_unit_return::explicit_unit::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 16, 02, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 8, 22) to (start + 2, 6) +- Code(Zero) at (prev + 7, 22) to (start + 2, 6) Highest counter ID seen: (none) Function name: closure_unit_return::implicit_unit -Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0f, 01, 01, 10, 01, 05, 05, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16) +- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 16) - Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2) Highest counter ID seen: c0 Function name: closure_unit_return::implicit_unit::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 16, 02, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 17, 22) to (start + 2, 6) +- Code(Zero) at (prev + 16, 22) to (start + 2, 6) Highest counter ID seen: (none) diff --git a/tests/coverage/closure_unit_return.coverage b/tests/coverage/closure_unit_return.coverage index 5e57e0db160..131fab993f0 100644 --- a/tests/coverage/closure_unit_return.coverage +++ b/tests/coverage/closure_unit_return.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Regression test for an inconsistency between functions that return the value diff --git a/tests/coverage/closure_unit_return.rs b/tests/coverage/closure_unit_return.rs index d4f139dd363..74334f32f6e 100644 --- a/tests/coverage/closure_unit_return.rs +++ b/tests/coverage/closure_unit_return.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Regression test for an inconsistency between functions that return the value diff --git a/tests/coverage/condition/conditions.cov-map b/tests/coverage/condition/conditions.cov-map index 417637f2d2e..d437c91b2b0 100644 --- a/tests/coverage/condition/conditions.cov-map +++ b/tests/coverage/condition/conditions.cov-map @@ -1,5 +1,5 @@ Function name: conditions::assign_3_and_or -Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1c, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (65): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 1b, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 5 @@ -9,7 +9,7 @@ Number of expressions: 5 - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) - expression 4 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 47) +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 47) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -28,7 +28,7 @@ Number of file 0 mappings: 9 Highest counter ID seen: c3 Function name: conditions::assign_3_or_and -Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 17, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (63): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 09, 01, 16, 01, 00, 2f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 09, 00, 17, 00, 18, 20, 0d, 0e, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -37,7 +37,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 47) +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 47) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -56,14 +56,14 @@ Number of file 0 mappings: 9 Highest counter ID seen: c3 Function name: conditions::assign_and -Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0d, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (47): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 0c, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33) +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -77,7 +77,7 @@ Number of file 0 mappings: 7 Highest counter ID seen: c2 Function name: conditions::assign_or -Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 12, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (49): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 07, 01, 11, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 20, 09, 06, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -85,7 +85,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14) @@ -100,23 +100,23 @@ Number of file 0 mappings: 7 Highest counter ID seen: c2 Function name: conditions::foo -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 20, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 32, 1) to (start + 2, 2) Highest counter ID seen: c0 Function name: conditions::func_call -Raw bytes (37): 0x[01, 01, 02, 01, 05, 05, 09, 05, 01, 25, 01, 01, 0a, 20, 05, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] +Raw bytes (37): 0x[01, 01, 02, 01, 05, 05, 09, 05, 01, 24, 01, 01, 0a, 20, 05, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 0f, 20, 09, 06, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 10) +- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 10) - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 9) to (start + 0, 10) true = c1 false = (c0 - c1) @@ -128,11 +128,11 @@ Number of file 0 mappings: 5 Highest counter ID seen: c2 Function name: conditions::simple_assign -Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 03, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2) +- Code(Counter(0)) at (prev + 7, 1) to (start + 3, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/condition/conditions.coverage b/tests/coverage/condition/conditions.coverage index 3215b391d62..117e9aabb5b 100644 --- a/tests/coverage/condition/conditions.coverage +++ b/tests/coverage/condition/conditions.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ compile-flags: -Zcoverage-options=condition LL| |//@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/condition/conditions.rs b/tests/coverage/condition/conditions.rs index 3d658dc93e0..63fa962ce5f 100644 --- a/tests/coverage/condition/conditions.rs +++ b/tests/coverage/condition/conditions.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ compile-flags: -Zcoverage-options=condition //@ llvm-cov-flags: --show-branches=count diff --git a/tests/coverage/coverage_attr_closure.coverage b/tests/coverage/coverage_attr_closure.coverage index 7bdb96bdab8..31898786afc 100644 --- a/tests/coverage/coverage_attr_closure.coverage +++ b/tests/coverage/coverage_attr_closure.coverage @@ -1,4 +1,4 @@ - LL| |#![feature(coverage_attribute, stmt_expr_attributes)] + LL| |#![feature(stmt_expr_attributes)] LL| |#![allow(dead_code)] LL| |//@ edition: 2021 LL| | diff --git a/tests/coverage/coverage_attr_closure.rs b/tests/coverage/coverage_attr_closure.rs index 4341a868ab8..c66ccb7f5a5 100644 --- a/tests/coverage/coverage_attr_closure.rs +++ b/tests/coverage/coverage_attr_closure.rs @@ -1,4 +1,4 @@ -#![feature(coverage_attribute, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] #![allow(dead_code)] //@ edition: 2021 diff --git a/tests/coverage/fn_sig_into_try.cov-map b/tests/coverage/fn_sig_into_try.cov-map index 374811dba9e..cd8726fe1c3 100644 --- a/tests/coverage/fn_sig_into_try.cov-map +++ b/tests/coverage/fn_sig_into_try.cov-map @@ -1,20 +1,20 @@ Function name: fn_sig_into_try::a -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 05, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 01, 05, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 10, 1) to (start + 5, 2) +- Code(Counter(0)) at (prev + 9, 1) to (start + 5, 2) Highest counter ID seen: c0 Function name: fn_sig_into_try::b -Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 11, 01, 03, 0f, 00, 03, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 10, 01, 03, 0f, 00, 03, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 17, 1) to (start + 3, 15) +- Code(Counter(0)) at (prev + 16, 1) to (start + 3, 15) - Code(Zero) at (prev + 3, 15) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12) = (c0 - Zero) @@ -22,13 +22,13 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: fn_sig_into_try::c -Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 18, 01, 03, 17, 00, 03, 17, 00, 18, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 17, 01, 03, 17, 00, 03, 17, 00, 18, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 24, 1) to (start + 3, 23) +- Code(Counter(0)) at (prev + 23, 1) to (start + 3, 23) - Code(Zero) at (prev + 3, 23) to (start + 0, 24) - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12) = (c0 - Zero) @@ -36,13 +36,13 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: fn_sig_into_try::d -Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 1f, 01, 04, 0f, 00, 04, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 1e, 01, 04, 0f, 00, 04, 0f, 00, 10, 02, 01, 05, 00, 0c, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Zero Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 31, 1) to (start + 4, 15) +- Code(Counter(0)) at (prev + 30, 1) to (start + 4, 15) - Code(Zero) at (prev + 4, 15) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 12) = (c0 - Zero) diff --git a/tests/coverage/fn_sig_into_try.coverage b/tests/coverage/fn_sig_into_try.coverage index cabe747ce5a..05b8edf15a4 100644 --- a/tests/coverage/fn_sig_into_try.coverage +++ b/tests/coverage/fn_sig_into_try.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Regression test for inconsistent handling of function signature spans that diff --git a/tests/coverage/fn_sig_into_try.rs b/tests/coverage/fn_sig_into_try.rs index cda5e716edf..fd3e0c3f7c6 100644 --- a/tests/coverage/fn_sig_into_try.rs +++ b/tests/coverage/fn_sig_into_try.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Regression test for inconsistent handling of function signature spans that diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map index f47139ce5a4..6f366796722 100644 --- a/tests/coverage/if_not.cov-map +++ b/tests/coverage/if_not.cov-map @@ -1,5 +1,5 @@ Function name: if_not::if_not -Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 04, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -7,7 +7,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(0), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(3) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 13) +- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 13) - Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 2, 6) = (c0 - c1) - Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6) diff --git a/tests/coverage/if_not.coverage b/tests/coverage/if_not.coverage index 678ccf9f2f8..c96627d88ae 100644 --- a/tests/coverage/if_not.coverage +++ b/tests/coverage/if_not.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |#[rustfmt::skip] diff --git a/tests/coverage/if_not.rs b/tests/coverage/if_not.rs index 69283ef2527..d1c2b5fc982 100644 --- a/tests/coverage/if_not.rs +++ b/tests/coverage/if_not.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 #[rustfmt::skip] diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map index 7789114c239..5a3ccff87c3 100644 --- a/tests/coverage/let_else_loop.cov-map +++ b/tests/coverage/let_else_loop.cov-map @@ -1,32 +1,32 @@ Function name: let_else_loop::_if (unused) -Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 15, 01, 01, 0c, 00, 01, 0f, 00, 16, 00, 00, 20, 00, 27] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 -- Code(Zero) at (prev + 22, 1) to (start + 1, 12) +- Code(Zero) at (prev + 21, 1) to (start + 1, 12) - Code(Zero) at (prev + 1, 15) to (start + 0, 22) - Code(Zero) at (prev + 0, 32) to (start + 0, 39) Highest counter ID seen: (none) Function name: let_else_loop::_loop_either_way (unused) -Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c] +Raw bytes (19): 0x[01, 01, 00, 03, 00, 0e, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 -- Code(Zero) at (prev + 15, 1) to (start + 1, 20) +- Code(Zero) at (prev + 14, 1) to (start + 1, 20) - Code(Zero) at (prev + 1, 28) to (start + 0, 35) - Code(Zero) at (prev + 1, 5) to (start + 0, 12) Highest counter ID seen: (none) Function name: let_else_loop::loopy -Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02] +Raw bytes (19): 0x[01, 01, 00, 03, 01, 08, 01, 01, 14, 09, 01, 1c, 00, 23, 05, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20) +- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 20) - Code(Counter(2)) at (prev + 1, 28) to (start + 0, 35) - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c2 diff --git a/tests/coverage/let_else_loop.coverage b/tests/coverage/let_else_loop.coverage index bd13f6e5650..b42e1e144ae 100644 --- a/tests/coverage/let_else_loop.coverage +++ b/tests/coverage/let_else_loop.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// Regression test for . diff --git a/tests/coverage/let_else_loop.rs b/tests/coverage/let_else_loop.rs index 8217c0d072a..83571287859 100644 --- a/tests/coverage/let_else_loop.rs +++ b/tests/coverage/let_else_loop.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Regression test for . diff --git a/tests/coverage/macro_in_closure.cov-map b/tests/coverage/macro_in_closure.cov-map index 9614154a366..38ce58d9ea5 100644 --- a/tests/coverage/macro_in_closure.cov-map +++ b/tests/coverage/macro_in_closure.cov-map @@ -1,18 +1,18 @@ Function name: macro_in_closure::NO_BLOCK::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 1c, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 1c, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 28) to (start + 0, 45) +- Code(Counter(0)) at (prev + 6, 28) to (start + 0, 45) Highest counter ID seen: c0 Function name: macro_in_closure::WITH_BLOCK::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 1e, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 1e, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 9, 30) to (start + 2, 2) +- Code(Counter(0)) at (prev + 8, 30) to (start + 2, 2) Highest counter ID seen: c0 diff --git a/tests/coverage/macro_in_closure.coverage b/tests/coverage/macro_in_closure.coverage index a23ad2c37ec..c829c512cb8 100644 --- a/tests/coverage/macro_in_closure.coverage +++ b/tests/coverage/macro_in_closure.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// If a closure body consists entirely of a single bang-macro invocation, the diff --git a/tests/coverage/macro_in_closure.rs b/tests/coverage/macro_in_closure.rs index 3d62b54073f..251fbf04ee3 100644 --- a/tests/coverage/macro_in_closure.rs +++ b/tests/coverage/macro_in_closure.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // If a closure body consists entirely of a single bang-macro invocation, the diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map index 8ff5d6360f6..befe8866a59 100644 --- a/tests/coverage/mcdc/condition-limit.cov-map +++ b/tests/coverage/mcdc/condition-limit.cov-map @@ -1,5 +1,5 @@ Function name: condition_limit::accept_7_conditions -Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] +Raw bytes (147): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 12, 01, 06, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 @@ -12,7 +12,7 @@ Number of expressions: 8 - expression 6 operands: lhs = Counter(6), rhs = Counter(7) - expression 7 operands: lhs = Counter(0), rhs = Counter(7) Number of file 0 mappings: 18 -- Code(Counter(0)) at (prev + 7, 1) to (start + 2, 9) +- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 9) - MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 2, 8) to (start + 0, 39) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 diff --git a/tests/coverage/mcdc/condition-limit.coverage b/tests/coverage/mcdc/condition-limit.coverage index d11b8a17710..1a990f27ac2 100644 --- a/tests/coverage/mcdc/condition-limit.coverage +++ b/tests/coverage/mcdc/condition-limit.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 19 LL| |//@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/condition-limit.rs b/tests/coverage/mcdc/condition-limit.rs index 2e8f1619379..520a9f44e08 100644 --- a/tests/coverage/mcdc/condition-limit.rs +++ b/tests/coverage/mcdc/condition-limit.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 19 //@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map index 771351f649f..1b038f48429 100644 --- a/tests/coverage/mcdc/if.cov-map +++ b/tests/coverage/mcdc/if.cov-map @@ -1,5 +1,5 @@ Function name: if::mcdc_check_a -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 0e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -7,7 +7,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -23,7 +23,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_b -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 17, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 16, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -31,7 +31,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 23, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -47,7 +47,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_both -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1f, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 1e, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -55,7 +55,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 31, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -71,7 +71,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_neither -Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 07, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (62): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 06, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -79,7 +79,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Counter(0), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -95,7 +95,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: if::mcdc_check_not_tree_decision -Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 31, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (85): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0a, 01, 30, 01, 03, 0a, 28, 05, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 7 @@ -107,7 +107,7 @@ Number of expressions: 7 - expression 5 operands: lhs = Counter(1), rhs = Counter(2) - expression 6 operands: lhs = Counter(0), rhs = Counter(3) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 49, 1) to (start + 3, 10) +- Code(Counter(0)) at (prev + 48, 1) to (start + 3, 10) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10) true = c1 @@ -129,7 +129,7 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: if::mcdc_check_tree_decision -Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 27, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0a, 01, 26, 01, 03, 09, 28, 04, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 @@ -142,7 +142,7 @@ Number of expressions: 8 - expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add) - expression 7 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 39, 1) to (start + 3, 9) +- Code(Counter(0)) at (prev + 38, 1) to (start + 3, 9) - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -164,7 +164,7 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: if::mcdc_nested_if -Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (120): 0x[01, 01, 0b, 01, 05, 01, 2b, 05, 09, 05, 09, 2b, 0d, 05, 09, 0d, 11, 2b, 11, 05, 09, 01, 2b, 05, 09, 0e, 01, 3a, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 26, 02, 00, 00, 00, 0d, 00, 0e, 2b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 0d, 12, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 1a, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 1e, 02, 09, 00, 0a, 26, 01, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 11 @@ -180,7 +180,7 @@ Number of expressions: 11 - expression 9 operands: lhs = Counter(0), rhs = Expression(10, Add) - expression 10 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 59, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 58, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9) true = c1 diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage index b000c7d5d2f..cee74de3c5f 100644 --- a/tests/coverage/mcdc/if.coverage +++ b/tests/coverage/mcdc/if.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 19 LL| |//@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs index a2abb2edf11..895b736d066 100644 --- a/tests/coverage/mcdc/if.rs +++ b/tests/coverage/mcdc/if.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 19 //@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map index 6a112b66e88..7d78e572a3b 100644 --- a/tests/coverage/mcdc/inlined_expressions.cov-map +++ b/tests/coverage/mcdc/inlined_expressions.cov-map @@ -1,12 +1,12 @@ Function name: inlined_expressions::inlined_instance -Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 08, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 07, 01, 01, 06, 28, 03, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6) +- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 6) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6) true = c1 diff --git a/tests/coverage/mcdc/inlined_expressions.coverage b/tests/coverage/mcdc/inlined_expressions.coverage index 57c655a2054..12bf55d6460 100644 --- a/tests/coverage/mcdc/inlined_expressions.coverage +++ b/tests/coverage/mcdc/inlined_expressions.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 19 LL| |//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs index 651e2fe8438..dbab0b8a662 100644 --- a/tests/coverage/mcdc/inlined_expressions.rs +++ b/tests/coverage/mcdc/inlined_expressions.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 19 //@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map index 72c7d68840d..59564404481 100644 --- a/tests/coverage/mcdc/nested_if.cov-map +++ b/tests/coverage/mcdc/nested_if.cov-map @@ -1,5 +1,5 @@ Function name: nested_if::doubly_nested_if_in_condition -Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 09, 05, 09, 05, 13, 09, 19, 19, 1d, 05, 1f, 09, 1d, 09, 0d, 2b, 05, 01, 15, 33, 05, 37, 15, 01, 11, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 21, 02, 00, 00, 00, 15, 00, 36, 0a, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 19, 0e, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1d, 16, 02, 00, 00, 00, 1d, 00, 1e, 1d, 00, 21, 00, 25, 1a, 00, 2f, 00, 34, 23, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 26, 02, 0c, 02, 06, 2e, 03, 01, 00, 02] +Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 09, 05, 09, 05, 13, 09, 19, 19, 1d, 05, 1f, 09, 1d, 09, 0d, 2b, 05, 01, 15, 33, 05, 37, 15, 01, 11, 14, 01, 0e, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 21, 02, 00, 00, 00, 15, 00, 36, 0a, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 19, 0e, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1d, 16, 02, 00, 00, 00, 1d, 00, 1e, 1d, 00, 21, 00, 25, 1a, 00, 2f, 00, 34, 23, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 26, 02, 0c, 02, 06, 2e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 14 @@ -18,7 +18,7 @@ Number of expressions: 14 - expression 12 operands: lhs = Expression(13, Add), rhs = Counter(5) - expression 13 operands: lhs = Counter(0), rhs = Counter(4) Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -58,7 +58,7 @@ Number of file 0 mappings: 20 Highest counter ID seen: c8 Function name: nested_if::nested_if_in_condition -Raw bytes (124): 0x[01, 01, 0d, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 05, 1f, 09, 0d, 27, 05, 01, 15, 2f, 05, 33, 15, 01, 11, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 1a, 02, 00, 00, 00, 15, 00, 16, 1f, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 22, 02, 0c, 02, 06, 2a, 03, 01, 00, 02] +Raw bytes (124): 0x[01, 01, 0d, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 05, 1f, 09, 0d, 27, 05, 01, 15, 2f, 05, 33, 15, 01, 11, 0e, 01, 06, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 1a, 02, 00, 00, 00, 15, 00, 16, 1f, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 22, 02, 0c, 02, 06, 2a, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 13 @@ -76,7 +76,7 @@ Number of expressions: 13 - expression 11 operands: lhs = Expression(12, Add), rhs = Counter(5) - expression 12 operands: lhs = Counter(0), rhs = Counter(4) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -106,7 +106,7 @@ Number of file 0 mappings: 14 Highest counter ID seen: c5 Function name: nested_if::nested_in_then_block_in_condition -Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 09, 05, 09, 05, 33, 09, 0d, 09, 0d, 33, 11, 09, 0d, 11, 15, 33, 15, 09, 0d, 05, 33, 09, 0d, 3b, 05, 01, 1d, 43, 05, 47, 1d, 01, 19, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 1d, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 2e, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1a, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 22, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 26, 00, 33, 00, 38, 2e, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 36, 02, 0c, 02, 06, 3e, 03, 01, 00, 02] +Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 09, 05, 09, 05, 33, 09, 0d, 09, 0d, 33, 11, 09, 0d, 11, 15, 33, 15, 09, 0d, 05, 33, 09, 0d, 3b, 05, 01, 1d, 43, 05, 47, 1d, 01, 19, 14, 01, 21, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 1d, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 2e, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1a, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 22, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 26, 00, 33, 00, 38, 2e, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 36, 02, 0c, 02, 06, 3e, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 18 @@ -129,7 +129,7 @@ Number of expressions: 18 - expression 16 operands: lhs = Expression(17, Add), rhs = Counter(7) - expression 17 operands: lhs = Counter(0), rhs = Counter(6) Number of file 0 mappings: 20 -- Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9) +- Code(Counter(0)) at (prev + 33, 1) to (start + 1, 9) - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 @@ -170,7 +170,7 @@ Number of file 0 mappings: 20 Highest counter ID seen: c7 Function name: nested_if::nested_single_condition_decision -Raw bytes (89): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 13, 05, 01, 11, 1b, 05, 1f, 11, 01, 0d, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 11, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0a, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 0e, 02, 0c, 02, 06, 16, 03, 01, 00, 02] +Raw bytes (89): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 13, 05, 01, 11, 1b, 05, 1f, 11, 01, 0d, 0b, 01, 16, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 11, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0a, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 0e, 02, 0c, 02, 06, 16, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 8 @@ -183,7 +183,7 @@ Number of expressions: 8 - expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4) - expression 7 operands: lhs = Counter(0), rhs = Counter(3) Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9) +- Code(Counter(0)) at (prev + 22, 1) to (start + 4, 9) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) true = c1 diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage index ca0cb54d581..4c872708a6e 100644 --- a/tests/coverage/mcdc/nested_if.coverage +++ b/tests/coverage/mcdc/nested_if.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 19 LL| |//@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs index 83f188ea47e..3356a768a69 100644 --- a/tests/coverage/mcdc/nested_if.rs +++ b/tests/coverage/mcdc/nested_if.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 19 //@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map index c282d53c5ac..ee128d997c0 100644 --- a/tests/coverage/mcdc/non_control_flow.cov-map +++ b/tests/coverage/mcdc/non_control_flow.cov-map @@ -1,5 +1,5 @@ Function name: non_control_flow::assign_3 -Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 16, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (79): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0a, 01, 15, 01, 00, 28, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -8,7 +8,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Counter(1), rhs = Counter(2) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40) +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 40) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) @@ -28,7 +28,7 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: non_control_flow::assign_3_bis -Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1b, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] +Raw bytes (81): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0a, 01, 1a, 01, 00, 2c, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 5 @@ -38,7 +38,7 @@ Number of expressions: 5 - expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) - expression 4 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44) +- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 44) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) @@ -58,14 +58,14 @@ Number of file 0 mappings: 10 Highest counter ID seen: c3 Function name: non_control_flow::assign_and -Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0c, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 0b, 01, 00, 21, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33) +- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 33) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) @@ -80,7 +80,7 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: non_control_flow::assign_or -Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 11, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] +Raw bytes (62): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 08, 01, 10, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 @@ -88,7 +88,7 @@ Number of expressions: 3 - expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) - expression 2 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32) +- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 32) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) @@ -104,23 +104,23 @@ Number of file 0 mappings: 8 Highest counter ID seen: c2 Function name: non_control_flow::foo -Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 37, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 36, 1) to (start + 2, 2) Highest counter ID seen: c0 Function name: non_control_flow::func_call -Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 29, 01, 01, 0a, 28, 03, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] +Raw bytes (50): 0x[01, 01, 02, 01, 05, 05, 09, 06, 01, 28, 01, 01, 0a, 28, 03, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10) +- Code(Counter(0)) at (prev + 40, 1) to (start + 1, 10) - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15) - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10) true = c1 @@ -133,7 +133,7 @@ Number of file 0 mappings: 6 Highest counter ID seen: c2 Function name: non_control_flow::right_comb_tree -Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 20, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02] +Raw bytes (111): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 0e, 01, 1f, 01, 00, 41, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 5 @@ -143,7 +143,7 @@ Number of expressions: 5 - expression 3 operands: lhs = Counter(3), rhs = Counter(4) - expression 4 operands: lhs = Counter(4), rhs = Counter(5) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65) +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 65) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) - MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42) diff --git a/tests/coverage/mcdc/non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage index cead419fbdf..204c46dc7b5 100644 --- a/tests/coverage/mcdc/non_control_flow.coverage +++ b/tests/coverage/mcdc/non_control_flow.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 19 LL| |//@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs index 6cfce6fae93..a836d8b55c0 100644 --- a/tests/coverage/mcdc/non_control_flow.rs +++ b/tests/coverage/mcdc/non_control_flow.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 //@ min-llvm-version: 19 //@ compile-flags: -Zcoverage-options=mcdc diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map index 28d0d9ff8ab..dd01774b9c4 100644 --- a/tests/coverage/no_cov_crate.cov-map +++ b/tests/coverage/no_cov_crate.cov-map @@ -1,67 +1,67 @@ Function name: no_cov_crate::add_coverage_1 -Raw bytes (9): 0x[01, 01, 00, 01, 01, 14, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 20, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2) Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_2 -Raw bytes (9): 0x[01, 01, 00, 01, 01, 18, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 23, 1) to (start + 2, 2) Highest counter ID seen: c0 Function name: no_cov_crate::add_coverage_not_called (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 1c, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 29, 1) to (start + 2, 2) +- Code(Zero) at (prev + 28, 1) to (start + 2, 2) Highest counter ID seen: (none) Function name: no_cov_crate::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 4d, 01, 0b, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 4c, 01, 0b, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 77, 1) to (start + 11, 2) +- Code(Counter(0)) at (prev + 76, 1) to (start + 11, 2) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer -Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 05, 02, 23, 01, 0c, 05, 00, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 30, 05, 02, 23, 01, 0c, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 49, 5) to (start + 2, 35) +- Code(Counter(0)) at (prev + 48, 5) to (start + 2, 35) - Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered -Raw bytes (14): 0x[01, 01, 00, 02, 01, 3f, 05, 02, 17, 01, 0b, 05, 00, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 3e, 05, 02, 17, 01, 0b, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 63, 5) to (start + 2, 23) +- Code(Counter(0)) at (prev + 62, 5) to (start + 2, 23) - Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6) Highest counter ID seen: c0 Function name: no_cov_crate::nested_fns::outer_both_covered::inner -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 42, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 67, 9) to (start + 1, 23) +- Code(Counter(0)) at (prev + 66, 9) to (start + 1, 23) - Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14) - Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14) = (c0 - c1) diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage index 6a43e52652e..b08e5604454 100644 --- a/tests/coverage/no_cov_crate.coverage +++ b/tests/coverage/no_cov_crate.coverage @@ -1,5 +1,4 @@ LL| |// Enables `coverage(off)` on the entire crate - LL| |#![feature(coverage_attribute)] LL| | LL| |#[coverage(off)] LL| |fn do_not_add_coverage_1() { diff --git a/tests/coverage/no_cov_crate.rs b/tests/coverage/no_cov_crate.rs index e12e4bc55e3..1b4b384b167 100644 --- a/tests/coverage/no_cov_crate.rs +++ b/tests/coverage/no_cov_crate.rs @@ -1,5 +1,4 @@ // Enables `coverage(off)` on the entire crate -#![feature(coverage_attribute)] #[coverage(off)] fn do_not_add_coverage_1() { diff --git a/tests/coverage/no_spans.cov-map b/tests/coverage/no_spans.cov-map index 7f43b68fa90..c6178fc41cf 100644 --- a/tests/coverage/no_spans.cov-map +++ b/tests/coverage/no_spans.cov-map @@ -1,18 +1,18 @@ Function name: no_spans::affected_function -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 1c, 00, 1d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29) +- Code(Counter(0)) at (prev + 25, 28) to (start + 0, 29) Highest counter ID seen: c0 Function name: no_spans::affected_function::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 0c, 00, 0e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14) +- Code(Counter(0)) at (prev + 26, 12) to (start + 0, 14) Highest counter ID seen: c0 diff --git a/tests/coverage/no_spans.coverage b/tests/coverage/no_spans.coverage index 19e8c2fe5b6..c722210e35f 100644 --- a/tests/coverage/no_spans.coverage +++ b/tests/coverage/no_spans.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// If the span extractor can't find any relevant spans for a function, the diff --git a/tests/coverage/no_spans.rs b/tests/coverage/no_spans.rs index e5312406f8a..db28bfd0590 100644 --- a/tests/coverage/no_spans.rs +++ b/tests/coverage/no_spans.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // If the span extractor can't find any relevant spans for a function, the diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map index d4a5936a784..97961bc7414 100644 --- a/tests/coverage/unreachable.cov-map +++ b/tests/coverage/unreachable.cov-map @@ -1,27 +1,27 @@ Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 27, 00, 47] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 27, 00, 47] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 39) to (start + 0, 71) +- Code(Zero) at (prev + 14, 39) to (start + 0, 71) Highest counter ID seen: (none) Function name: unreachable::unreachable_function (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 01, 01, 25] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 10, 01, 01, 25] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 17, 1) to (start + 1, 37) +- Code(Zero) at (prev + 16, 1) to (start + 1, 37) Highest counter ID seen: (none) Function name: unreachable::unreachable_intrinsic (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 2c] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 01, 2c] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 22, 1) to (start + 1, 44) +- Code(Zero) at (prev + 21, 1) to (start + 1, 44) Highest counter ID seen: (none) diff --git a/tests/coverage/unreachable.coverage b/tests/coverage/unreachable.coverage index fdb6d3616d9..6f9f45dce1e 100644 --- a/tests/coverage/unreachable.coverage +++ b/tests/coverage/unreachable.coverage @@ -1,5 +1,4 @@ LL| |#![feature(core_intrinsics)] - LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 LL| | LL| |// diff --git a/tests/coverage/unreachable.rs b/tests/coverage/unreachable.rs index 0e05c1d11be..d6082f85a36 100644 --- a/tests/coverage/unreachable.rs +++ b/tests/coverage/unreachable.rs @@ -1,5 +1,4 @@ #![feature(core_intrinsics)] -#![feature(coverage_attribute)] //@ edition: 2021 // diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index 8dd23e4d6a3..f0d128ec02e 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -26,16 +26,16 @@ debug a => _9; } -+ coverage body span: $DIR/branch_match_arms.rs:14:11: 21:2 (#0) ++ coverage body span: $DIR/branch_match_arms.rs:13:11: 20:2 (#0) + coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Add, rhs: Counter(2) }; + coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Add, rhs: Counter(3) }; + coverage ExpressionId(2) => Expression { lhs: Counter(0), op: Subtract, rhs: Expression(1) }; -+ coverage Code(Counter(0)) => 14:1 - 15:21; -+ coverage Code(Counter(1)) => 16:17 - 16:33; -+ coverage Code(Counter(2)) => 17:17 - 17:33; -+ coverage Code(Counter(3)) => 18:17 - 18:33; -+ coverage Code(Expression(2)) => 19:17 - 19:33; -+ coverage Code(Counter(0)) => 21:1 - 21:2; ++ coverage Code(Counter(0)) => 13:1 - 14:21; ++ coverage Code(Counter(1)) => 15:17 - 15:33; ++ coverage Code(Counter(2)) => 16:17 - 16:33; ++ coverage Code(Counter(3)) => 17:17 - 17:33; ++ coverage Code(Expression(2)) => 18:17 - 18:33; ++ coverage Code(Counter(0)) => 20:1 - 20:2; + bb0: { + Coverage::CounterIncrement(0); diff --git a/tests/mir-opt/coverage/branch_match_arms.rs b/tests/mir-opt/coverage/branch_match_arms.rs index 18764b38d6e..84ffddcb289 100644 --- a/tests/mir-opt/coverage/branch_match_arms.rs +++ b/tests/mir-opt/coverage/branch_match_arms.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ test-mir-pass: InstrumentCoverage //@ compile-flags: -Cinstrument-coverage -Zno-profiler-runtime -Zcoverage-options=branch // skip-filecheck diff --git a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr deleted file mode 100644 index 9e3cd41c277..00000000000 --- a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: malformed `coverage` attribute input - --> $DIR/bad-attr-ice.rs:10:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL | #[coverage(off)] - | -LL | #[coverage(on)] - | - -error: aborting due to 1 previous error - diff --git a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr deleted file mode 100644 index d73636e158b..00000000000 --- a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: malformed `coverage` attribute input - --> $DIR/bad-attr-ice.rs:10:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL | #[coverage(off)] - | -LL | #[coverage(on)] - | - -error[E0658]: the `#[coverage]` attribute is an experimental feature - --> $DIR/bad-attr-ice.rs:10:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ - | - = note: see issue #84605 for more information - = help: add `#![feature(coverage_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/coverage-attr/bad-attr-ice.rs b/tests/ui/coverage-attr/bad-attr-ice.rs index 55c86d260d4..eaf9ec255dc 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.rs +++ b/tests/ui/coverage-attr/bad-attr-ice.rs @@ -1,5 +1,3 @@ -#![cfg_attr(feat, feature(coverage_attribute))] -//@ revisions: feat nofeat //@ compile-flags: -Cinstrument-coverage //@ needs-profiler-runtime @@ -9,8 +7,4 @@ #[coverage] //~^ ERROR malformed `coverage` attribute input -//[nofeat]~| the `#[coverage]` attribute is an experimental feature fn main() {} - -// FIXME(#130766): When the `#[coverage(..)]` attribute is stabilized, -// get rid of the revisions and just make this a normal test. diff --git a/tests/ui/coverage-attr/bad-attr-ice.stderr b/tests/ui/coverage-attr/bad-attr-ice.stderr new file mode 100644 index 00000000000..e48436ccdfe --- /dev/null +++ b/tests/ui/coverage-attr/bad-attr-ice.stderr @@ -0,0 +1,15 @@ +error: malformed `coverage` attribute input + --> $DIR/bad-attr-ice.rs:8:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/coverage-attr/bad-syntax.rs b/tests/ui/coverage-attr/bad-syntax.rs index c8c92de8c38..fa2b25ceccd 100644 --- a/tests/ui/coverage-attr/bad-syntax.rs +++ b/tests/ui/coverage-attr/bad-syntax.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Tests the error messages produced (or not produced) by various unusual diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index 2bcf54860eb..e1833b57a72 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -1,5 +1,5 @@ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:15:1 + --> $DIR/bad-syntax.rs:14:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:18:1 + --> $DIR/bad-syntax.rs:17:1 | LL | #[coverage = true] | ^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:21:1 + --> $DIR/bad-syntax.rs:20:1 | LL | #[coverage()] | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:24:1 + --> $DIR/bad-syntax.rs:23:1 | LL | #[coverage(off, off)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:27:1 + --> $DIR/bad-syntax.rs:26:1 | LL | #[coverage(off, on)] | ^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:30:1 + --> $DIR/bad-syntax.rs:29:1 | LL | #[coverage(bogus)] | ^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:33:1 + --> $DIR/bad-syntax.rs:32:1 | LL | #[coverage(bogus, off)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:36:1 + --> $DIR/bad-syntax.rs:35:1 | LL | #[coverage(off, bogus)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: expected identifier, found `,` - --> $DIR/bad-syntax.rs:42:12 + --> $DIR/bad-syntax.rs:41:12 | LL | #[coverage(,off)] | ^ expected identifier @@ -115,25 +115,25 @@ LL + #[coverage(off)] | error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:7:1 + --> $DIR/bad-syntax.rs:6:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/bad-syntax.rs:8:1 + --> $DIR/bad-syntax.rs:7:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:11:1 + --> $DIR/bad-syntax.rs:10:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/bad-syntax.rs:12:1 + --> $DIR/bad-syntax.rs:11:1 | LL | #[coverage(on)] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs index 24a0feb0710..4d09b3796a7 100644 --- a/tests/ui/coverage-attr/name-value.rs +++ b/tests/ui/coverage-attr/name-value.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Demonstrates the diagnostics produced when using the syntax diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr index 38101764d6f..48581df52f7 100644 --- a/tests/ui/coverage-attr/name-value.stderr +++ b/tests/ui/coverage-attr/name-value.stderr @@ -1,5 +1,5 @@ error: malformed `coverage` attribute input - --> $DIR/name-value.rs:11:1 + --> $DIR/name-value.rs:10:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:16:5 + --> $DIR/name-value.rs:15:5 | LL | #![coverage = "off"] | ^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #![coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:20:1 + --> $DIR/name-value.rs:19:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:28:5 + --> $DIR/name-value.rs:27:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:25:1 + --> $DIR/name-value.rs:24:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:38:5 + --> $DIR/name-value.rs:37:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:43:5 + --> $DIR/name-value.rs:42:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:34:1 + --> $DIR/name-value.rs:33:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:52:5 + --> $DIR/name-value.rs:51:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:57:5 + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:49:1 + --> $DIR/name-value.rs:48:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:63:1 + --> $DIR/name-value.rs:62:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | #[coverage(on)] | error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:20:1 + --> $DIR/name-value.rs:19:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -164,7 +164,7 @@ LL | struct MyStruct; | ---------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:34:1 + --> $DIR/name-value.rs:33:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | | } | |_- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:38:5 + --> $DIR/name-value.rs:37:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -186,7 +186,7 @@ LL | const X: u32; | ------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:43:5 + --> $DIR/name-value.rs:42:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -195,7 +195,7 @@ LL | type T; | ------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:28:5 + --> $DIR/name-value.rs:27:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL | const X: u32 = 7; | ----------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:52:5 + --> $DIR/name-value.rs:51:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ @@ -213,7 +213,7 @@ LL | const X: u32 = 8; | ----------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/name-value.rs:57:5 + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/coverage-attr/no-coverage.rs b/tests/ui/coverage-attr/no-coverage.rs index 9545b0b55cf..634eceee0f6 100644 --- a/tests/ui/coverage-attr/no-coverage.rs +++ b/tests/ui/coverage-attr/no-coverage.rs @@ -1,5 +1,4 @@ #![feature(extern_types)] -#![feature(coverage_attribute)] #![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] #![coverage(off)] diff --git a/tests/ui/coverage-attr/no-coverage.stderr b/tests/ui/coverage-attr/no-coverage.stderr index 3897d295940..6f117c68f88 100644 --- a/tests/ui/coverage-attr/no-coverage.stderr +++ b/tests/ui/coverage-attr/no-coverage.stderr @@ -1,5 +1,5 @@ error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:7:1 + --> $DIR/no-coverage.rs:6:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | | } | |_- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:39:5 + --> $DIR/no-coverage.rs:38:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | let _ = (); | ----------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:43:9 + --> $DIR/no-coverage.rs:42:9 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | () => (), | -------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:47:5 + --> $DIR/no-coverage.rs:46:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | return (); | --------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:9:5 + --> $DIR/no-coverage.rs:8:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | const X: u32; | ------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:12:5 + --> $DIR/no-coverage.rs:11:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | type T; | ------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:22:5 + --> $DIR/no-coverage.rs:21:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | type T = Self; | -------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:25:5 + --> $DIR/no-coverage.rs:24:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | type U = impl Trait; | -------------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:30:5 + --> $DIR/no-coverage.rs:29:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | static X: u32; | -------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/no-coverage.rs:33:5 + --> $DIR/no-coverage.rs:32:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | type T; | ------- not a function or closure error: unconstrained opaque type - --> $DIR/no-coverage.rs:26:14 + --> $DIR/no-coverage.rs:25:14 | LL | type U = impl Trait; | ^^^^^^^^^^ diff --git a/tests/ui/coverage-attr/subword.rs b/tests/ui/coverage-attr/subword.rs index 16582240b69..00c8dea3d37 100644 --- a/tests/ui/coverage-attr/subword.rs +++ b/tests/ui/coverage-attr/subword.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare diff --git a/tests/ui/coverage-attr/subword.stderr b/tests/ui/coverage-attr/subword.stderr index 3a106898f8b..60e58c015d8 100644 --- a/tests/ui/coverage-attr/subword.stderr +++ b/tests/ui/coverage-attr/subword.stderr @@ -1,5 +1,5 @@ error: malformed `coverage` attribute input - --> $DIR/subword.rs:7:1 + --> $DIR/subword.rs:6:1 | LL | #[coverage(yes(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/subword.rs:10:1 + --> $DIR/subword.rs:9:1 | LL | #[coverage(no(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/subword.rs:13:1 + --> $DIR/subword.rs:12:1 | LL | #[coverage(yes = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | #[coverage(on)] | ~~~~~~~~~~~~~~~ error: malformed `coverage` attribute input - --> $DIR/subword.rs:16:1 + --> $DIR/subword.rs:15:1 | LL | #[coverage(no = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs index ea12e7b19ee..6d9503593f0 100644 --- a/tests/ui/coverage-attr/word-only.rs +++ b/tests/ui/coverage-attr/word-only.rs @@ -1,4 +1,3 @@ -#![feature(coverage_attribute)] //@ edition: 2021 // Demonstrates the diagnostics produced when using the syntax `#[coverage]`, diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index 154ea61f3a3..de025cad96f 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -1,5 +1,5 @@ error: malformed `coverage` attribute input - --> $DIR/word-only.rs:11:1 + --> $DIR/word-only.rs:10:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:16:5 + --> $DIR/word-only.rs:15:5 | LL | #![coverage] | ^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #![coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:20:1 + --> $DIR/word-only.rs:19:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:28:5 + --> $DIR/word-only.rs:27:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:25:1 + --> $DIR/word-only.rs:24:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:38:5 + --> $DIR/word-only.rs:37:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:43:5 + --> $DIR/word-only.rs:42:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:34:1 + --> $DIR/word-only.rs:33:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:52:5 + --> $DIR/word-only.rs:51:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:57:5 + --> $DIR/word-only.rs:56:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:49:1 + --> $DIR/word-only.rs:48:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/word-only.rs:63:1 + --> $DIR/word-only.rs:62:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | #[coverage(on)] | error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:20:1 + --> $DIR/word-only.rs:19:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -164,7 +164,7 @@ LL | struct MyStruct; | ---------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:34:1 + --> $DIR/word-only.rs:33:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | | } | |_- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:38:5 + --> $DIR/word-only.rs:37:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -186,7 +186,7 @@ LL | const X: u32; | ------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:43:5 + --> $DIR/word-only.rs:42:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -195,7 +195,7 @@ LL | type T; | ------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:28:5 + --> $DIR/word-only.rs:27:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL | const X: u32 = 7; | ----------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:52:5 + --> $DIR/word-only.rs:51:5 | LL | #[coverage] | ^^^^^^^^^^^ @@ -213,7 +213,7 @@ LL | const X: u32 = 8; | ----------------- not a function or closure error[E0788]: attribute should be applied to a function definition or closure - --> $DIR/word-only.rs:57:5 + --> $DIR/word-only.rs:56:5 | LL | #[coverage] | ^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs deleted file mode 100644 index 0a463755f13..00000000000 --- a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![crate_type = "lib"] -#![feature(no_coverage)] //~ ERROR feature has been removed [E0557] - -#[derive(PartialEq, Eq)] // ensure deriving `Eq` does not enable `feature(coverage)` -struct Foo { - a: u8, - b: u32, -} - -#[coverage(off)] //~ ERROR the `#[coverage]` attribute is an experimental feature -fn requires_feature_coverage() -> bool { - let bar = Foo { a: 0, b: 0 }; - bar == Foo { a: 0, b: 0 } -} diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr deleted file mode 100644 index 00e0f0afbde..00000000000 --- a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0557]: feature has been removed - --> $DIR/feature-gate-coverage-attribute.rs:2:12 - | -LL | #![feature(no_coverage)] - | ^^^^^^^^^^^ feature has been removed - | - = note: renamed to `coverage_attribute` - -error[E0658]: the `#[coverage]` attribute is an experimental feature - --> $DIR/feature-gate-coverage-attribute.rs:10:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #84605 for more information - = help: add `#![feature(coverage_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0557, E0658. -For more information about an error, try `rustc --explain E0557`. diff --git a/tests/ui/feature-gates/feature-gate-no-coverage.rs b/tests/ui/feature-gates/feature-gate-no-coverage.rs new file mode 100644 index 00000000000..9c28b293854 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-no-coverage.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] +#![feature(no_coverage)] //~ ERROR feature has been removed [E0557] + +#[derive(PartialEq, Eq)] // ensure deriving `Eq` does not enable `feature(coverage)` +struct Foo { + a: u8, + b: u32, +} + +#[coverage(off)] +fn requires_feature_coverage() -> bool { + let bar = Foo { a: 0, b: 0 }; + bar == Foo { a: 0, b: 0 } +} diff --git a/tests/ui/feature-gates/feature-gate-no-coverage.stderr b/tests/ui/feature-gates/feature-gate-no-coverage.stderr new file mode 100644 index 00000000000..fa378bbd9dc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-no-coverage.stderr @@ -0,0 +1,11 @@ +error[E0557]: feature has been removed + --> $DIR/feature-gate-no-coverage.rs:2:12 + | +LL | #![feature(no_coverage)] + | ^^^^^^^^^^^ feature has been removed + | + = note: renamed to `coverage_attribute` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0557`. -- cgit 1.4.1-3-g733a5 From fadcbef1a4034e9eb593ba362e59da4ea5be49be Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 17 Dec 2024 21:53:33 -0500 Subject: Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/cargo b/src/tools/cargo index 769f622e12d..99dff6d77db 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 769f622e12db0001431d8ae36d1093fb8727c5d9 +Subproject commit 99dff6d77db779716dda9ca3b29c26addd02c1be -- cgit 1.4.1-3-g733a5