diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb449197f78bd..8747d77b46648 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: run_type: ${{ steps.jobs.outputs.run_type }} steps: - name: Checkout the source code - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Test citool # Only test citool on the auto branch, to reduce latency of the calculate matrix job # on PR/try builds. @@ -117,7 +117,7 @@ jobs: run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 2 @@ -254,7 +254,7 @@ jobs: df -h - name: upload artifacts to github - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: # name is set in previous step name: ${{ env.DOC_ARTIFACT_NAME }} @@ -315,7 +315,7 @@ jobs: environment: ${{ (github.repository == 'rust-lang/rust' && 'bors') || '' }} steps: - name: checkout the source code - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 2 # Publish the toolstate if an auto build succeeds (just before push to the default branch) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 9512e74601784..be0db12b52f3a 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -51,7 +51,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: checkout the source code - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: submodules: recursive - name: install the bootstrap toolchain @@ -66,7 +66,7 @@ jobs: run: ./src/tools/update-lockfile.sh - name: upload Cargo.lock artifact for use in PR - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: Cargo-lock path: | @@ -75,7 +75,7 @@ jobs: src/tools/rustbook/Cargo.lock retention-days: 1 - name: upload cargo-update log artifact for use in PR - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: cargo-updates path: cargo_update.log @@ -91,14 +91,14 @@ jobs: pull-requests: write steps: - name: checkout the source code - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: download Cargo.lock from update job - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: Cargo-lock - name: download cargo-update log from update job - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: cargo-updates diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml index ddb3b2ce0dd58..60deb90542607 100644 --- a/.github/workflows/ghcr.yml +++ b/.github/workflows/ghcr.yml @@ -29,7 +29,7 @@ jobs: # Needed to write to the ghcr.io registry packages: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: persist-credentials: false diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index c3d9217a645be..cbe92f1b52d9a 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -15,7 +15,7 @@ jobs: permissions: pull-requests: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: # Make sure that we have enough commits to find the parent merge commit. # Since all merges should be through merge commits, fetching two commits diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2bee8949c384e..57c18c74c23f7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1514,28 +1514,30 @@ impl EarlyLintPass for DoubleNegations { } } -declare_lint_pass!( - /// Does nothing as a lint pass, but registers some `Lint`s - /// which are used by other parts of the compiler. - SoftLints => [ - WHILE_TRUE, - NON_SHORTHAND_FIELD_PATTERNS, - UNSAFE_CODE, - MISSING_DOCS, - MISSING_COPY_IMPLEMENTATIONS, - MISSING_DEBUG_IMPLEMENTATIONS, - ANONYMOUS_PARAMETERS, - UNUSED_DOC_COMMENTS, - NO_MANGLE_CONST_ITEMS, - NO_MANGLE_GENERIC_ITEMS, - MUTABLE_TRANSMUTES, - UNSTABLE_FEATURES, - UNREACHABLE_PUB, - TYPE_ALIAS_BOUNDS, - TRIVIAL_BOUNDS, - DOUBLE_NEGATIONS - ] -); +pub mod soft { + use super::*; + + pub fn lint_vec() -> crate::LintVec { + vec![ + WHILE_TRUE, + NON_SHORTHAND_FIELD_PATTERNS, + UNSAFE_CODE, + MISSING_DOCS, + MISSING_COPY_IMPLEMENTATIONS, + MISSING_DEBUG_IMPLEMENTATIONS, + ANONYMOUS_PARAMETERS, + UNUSED_DOC_COMMENTS, + NO_MANGLE_CONST_ITEMS, + NO_MANGLE_GENERIC_ITEMS, + MUTABLE_TRANSMUTES, + UNSTABLE_FEATURES, + UNREACHABLE_PUB, + TYPE_ALIAS_BOUNDS, + TRIVIAL_BOUNDS, + DOUBLE_NEGATIONS, + ] + } +} declare_lint! { /// The `ellipsis_inclusive_range_patterns` lint detects the [`...` range diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index df12502c7e5a8..53a84d1285298 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -17,7 +17,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { clashing_extern_declarations, ..*providers }; } -pub(crate) fn get_lints() -> LintVec { +pub(crate) fn lint_vec() -> LintVec { vec![CLASHING_EXTERN_DECLARATIONS] } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index dc7cb1270f902..e10ee05e01d91 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -369,7 +369,12 @@ declare_tool_lint! { report_in_external_macro: true } -declare_lint_pass!(TypeIr => [DIRECT_USE_OF_RUSTC_TYPE_IR, NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_TRAITS]); +declare_lint_pass!(TypeIr => [ + DIRECT_USE_OF_RUSTC_TYPE_IR, + NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, + USAGE_OF_TYPE_IR_INHERENT, + USAGE_OF_TYPE_IR_TRAITS +]); impl<'tcx> LateLintPass<'tcx> for TypeIr { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { @@ -561,8 +566,6 @@ fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { declare_tool_lint! { /// The `symbol_intern_string_literal` detects `Symbol::intern` being called on a string literal pub rustc::SYMBOL_INTERN_STRING_LITERAL, - // rustc_driver crates out of the compiler can't/shouldn't add preinterned symbols; - // bootstrap will deny this manually Allow, "Forbid uses of string literals in `Symbol::intern`, suggesting preinterning instead", report_in_external_macro: true diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 0a074c6652a1d..19008a771dedd 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -14,7 +14,6 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::Session; use rustc_session::lint::LintPass; -use rustc_session::lint::builtin::HardwiredLints; use rustc_span::Span; use tracing::debug; @@ -437,7 +436,6 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { }) .collect(); - filtered_passes.push(Box::new(HardwiredLints)); let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] }; let mut cx = LateContextAndPass { context, pass }; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index aaa0371b4ec3e..6d69421b83161 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -132,7 +132,7 @@ use unused::must_use::*; use unused::*; #[rustfmt::skip] -pub use builtin::{MissingDoc, SoftLints}; +pub use builtin::MissingDoc; pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; pub use early::diagnostics::DiagAndSess; pub use early::{EarlyCheckNode, check_ast_node}; @@ -281,11 +281,11 @@ fn register_builtins(store: &mut LintStore) { ) } - store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints()); - store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); - store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); - store.register_lints(&foreign_modules::get_lints()); - store.register_lints(&HardwiredLints::lint_vec()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::lint_vec()); + store.register_lints(&BuiltinCombinedEarlyLintPass::lint_vec()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::lint_vec()); + store.register_lints(&foreign_modules::lint_vec()); + store.register_lints(&hardwired::lint_vec()); add_lint_group!( "nonstandard_style", @@ -665,6 +665,10 @@ fn register_builtins(store: &mut LintStore) { fn register_internals(store: &mut LintStore) { store.register_lints(&LintPassImpl::lint_vec()); store.register_early_pass(|| Box::new(LintPassImpl)); + store.register_lints(&ImplicitSysrootCrateImport::lint_vec()); + store.register_early_pass(|| Box::new(ImplicitSysrootCrateImport)); + store.register_lints(&BadUseOfFindAttr::lint_vec()); + store.register_early_pass(|| Box::new(BadUseOfFindAttr)); store.register_lints(&DefaultHashTypes::lint_vec()); store.register_late_mod_pass(|_| Box::new(DefaultHashTypes)); store.register_lints(&QueryStability::lint_vec()); @@ -681,10 +685,6 @@ fn register_internals(store: &mut LintStore) { store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt)); store.register_lints(&SymbolInternStringLiteral::lint_vec()); store.register_late_mod_pass(|_| Box::new(SymbolInternStringLiteral)); - store.register_lints(&ImplicitSysrootCrateImport::lint_vec()); - store.register_early_pass(|| Box::new(ImplicitSysrootCrateImport)); - store.register_lints(&BadUseOfFindAttr::lint_vec()); - store.register_early_pass(|| Box::new(BadUseOfFindAttr)); store.register_lints(&RustcMustMatchExhaustively::lint_vec()); store.register_late_pass(|_| Box::new(RustcMustMatchExhaustively)); store.register_group( @@ -692,21 +692,39 @@ fn register_internals(store: &mut LintStore) { "rustc::internal", None, vec![ + // Early pass: LintPassImpl + LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), + // Early pass: ImplicitSysrootCrateImport + LintId::of(IMPLICIT_SYSROOT_CRATE_IMPORT), + // Early pass: BadUseOfFindAttr + LintId::of(BAD_USE_OF_FIND_ATTR), + // Late pass: DefaultHashTypes LintId::of(DEFAULT_HASH_TYPES), + // Late pass: QueryStability LintId::of(POTENTIAL_QUERY_INSTABILITY), LintId::of(UNTRACKED_QUERY_INFORMATION), + // Late pass: TyTyKind LintId::of(USAGE_OF_TY_TYKIND), - LintId::of(DISALLOWED_PASS_BY_REF), - LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(USAGE_OF_QUALIFIED_TY), + // Late pass: TypeIr + LintId::of(DIRECT_USE_OF_RUSTC_TYPE_IR), LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT), LintId::of(USAGE_OF_TYPE_IR_INHERENT), LintId::of(USAGE_OF_TYPE_IR_TRAITS), + // Late pass: BadOptAccess LintId::of(BAD_OPT_ACCESS), + // Late pass: DisallowedPassByRef + LintId::of(DISALLOWED_PASS_BY_REF), + // Late pass: SpanUseEqCtxt LintId::of(SPAN_USE_EQ_CTXT), - LintId::of(DIRECT_USE_OF_RUSTC_TYPE_IR), - LintId::of(IMPLICIT_SYSROOT_CRATE_IMPORT), - LintId::of(BAD_USE_OF_FIND_ATTR), + // Late pass: SymbolInternStringLiteral + // Note: this one is not included in rustc::internal because rustc_driver crates + // outside the compiler can't/shouldn't add preinterned symbols. For rustc itself, + // bootstrap enables this lint manually. For rustdoc, + // `warn(symbol_intern_string_literal)` is used. + // LintId::of(SYMBOL_INTERN_STRING_LITERAL), + // + // Late pass: RustcMustMatchExhaustively LintId::of(RUSTC_MUST_MATCH_EXHAUSTIVELY), ], ); diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index ae145543e70dc..66484b01ff7a8 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -1,5 +1,4 @@ use rustc_session::lint::LintPass; -use rustc_session::lint::builtin::HardwiredLints; use crate::context::{EarlyContext, LateContext}; @@ -71,8 +70,6 @@ macro_rules! declare_late_lint_pass { // for all the `check_*` methods. late_lint_methods!(declare_late_lint_pass, []); -impl LateLintPass<'_> for HardwiredLints {} - #[macro_export] macro_rules! expand_combined_late_lint_pass_method { ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({ @@ -109,7 +106,7 @@ macro_rules! declare_combined_late_lint_pass { } } - $v fn get_lints() -> $crate::LintVec { + $v fn lint_vec() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::lint_vec());)* lints @@ -126,7 +123,7 @@ macro_rules! declare_combined_late_lint_pass { stringify!($name) } fn get_lints(&self) -> LintVec { - $name::get_lints() + $name::lint_vec() } } ) @@ -226,7 +223,7 @@ macro_rules! declare_combined_early_lint_pass { } } - $v fn get_lints() -> $crate::LintVec { + $v fn lint_vec() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::lint_vec());)* lints diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7f7dc6a1ef105..d38b1cf47bd6f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -9,151 +9,153 @@ use crate::{declare_lint, declare_lint_pass, fcw}; -declare_lint_pass! { - /// Does nothing as a lint pass, but registers some `Lint`s - /// that are used by other parts of the compiler. - HardwiredLints => [ - // tidy-alphabetical-start - AARCH64_SOFTFLOAT_NEON, - ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, - AMBIGUOUS_ASSOCIATED_ITEMS, - AMBIGUOUS_DERIVE_HELPERS, - AMBIGUOUS_GLOB_IMPORTED_TRAITS, - AMBIGUOUS_GLOB_IMPORTS, - AMBIGUOUS_GLOB_REEXPORTS, - AMBIGUOUS_IMPORT_VISIBILITIES, - AMBIGUOUS_PANIC_IMPORTS, - ARITHMETIC_OVERFLOW, - ASM_SUB_REGISTER, - BAD_ASM_STYLE, - BARE_TRAIT_OBJECTS, - BINDINGS_WITH_VARIANT_NAME, - BREAK_WITH_LABEL_AND_LOOP, - COHERENCE_LEAK_CHECK, - CONFLICTING_REPR_HINTS, - CONST_EVALUATABLE_UNCHECKED, - CONST_ITEM_MUTATION, - DEAD_CODE, - DEAD_CODE_PUB_IN_BINARY, - DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, - DEPRECATED, - DEPRECATED_IN_FUTURE, - DEPRECATED_LLVM_INTRINSIC, - DEPRECATED_SAFE_2024, - DEPRECATED_WHERE_CLAUSE_LOCATION, - DUPLICATE_FEATURES, - DUPLICATE_MACRO_ATTRIBUTES, - ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, - ELIDED_LIFETIMES_IN_PATHS, - EXPLICIT_BUILTIN_CFGS_IN_FLAGS, - EXPORTED_PRIVATE_DEPENDENCIES, - FFI_UNWIND_CALLS, - FLOAT_LITERAL_F32_FALLBACK, - FORBIDDEN_LINT_GROUPS, - FUNCTION_ITEM_REFERENCES, - HIDDEN_GLOB_REEXPORTS, - ILL_FORMED_ATTRIBUTE_INPUT, - INCOMPLETE_INCLUDE, - INEFFECTIVE_UNSTABLE_TRAIT_IMPL, - INLINE_NO_SANITIZE, - INVALID_DOC_ATTRIBUTES, - INVALID_MACRO_EXPORT_ARGUMENTS, - INVALID_TYPE_PARAM_DEFAULT, - IRREFUTABLE_LET_PATTERNS, - LARGE_ASSIGNMENTS, - LATE_BOUND_LIFETIME_ARGUMENTS, - LEGACY_DERIVE_HELPERS, - LINKER_INFO, - LINKER_MESSAGES, - LONG_RUNNING_CONST_EVAL, - MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - MACRO_USE_EXTERN_CRATE, - MALFORMED_DIAGNOSTIC_ATTRIBUTES, - MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, - META_VARIABLE_MISUSE, - MISPLACED_DIAGNOSTIC_ATTRIBUTES, - MISSING_ABI, - MISSING_UNSAFE_ON_EXTERN, - MUST_NOT_SUSPEND, - NAMED_ARGUMENTS_USED_POSITIONALLY, - NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, - NON_CONTIGUOUS_RANGE_ENDPOINTS, - NON_EXHAUSTIVE_OMITTED_PATTERNS, - OUT_OF_SCOPE_MACRO_CALLS, - OVERLAPPING_RANGE_ENDPOINTS, - PATTERNS_IN_FNS_WITHOUT_BODY, - PRIVATE_BOUNDS, - PRIVATE_INTERFACES, - PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - PUB_USE_OF_PRIVATE_EXTERN_CRATE, - REDUNDANT_IMPORTS, - REDUNDANT_LIFETIMES, - REFINING_IMPL_TRAIT_INTERNAL, - REFINING_IMPL_TRAIT_REACHABLE, - RENAMED_AND_REMOVED_LINTS, - REPR_C_ENUMS_LARGER_THAN_INT, - RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS, - RTSAN_NONBLOCKING_ASYNC, - RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, - RUST_2021_INCOMPATIBLE_OR_PATTERNS, - RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, - RUST_2021_PRELUDE_COLLISIONS, - RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX, - RUST_2024_INCOMPATIBLE_PAT, - RUST_2024_PRELUDE_COLLISIONS, - SELF_CONSTRUCTOR_FROM_OUTER_ITEM, - SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, - SHADOWING_SUPERTRAIT_ITEMS, - SINGLE_USE_LIFETIMES, - STABLE_FEATURES, - TAIL_CALL_TRACK_CALLER, - TAIL_EXPR_DROP_ORDER, - TEST_UNSTABLE_LINT, - TEXT_DIRECTION_CODEPOINT_IN_COMMENT, - TEXT_DIRECTION_CODEPOINT_IN_LITERAL, - TRIVIAL_CASTS, - TRIVIAL_NUMERIC_CASTS, - TYVAR_BEHIND_RAW_POINTER, - UNCONDITIONAL_PANIC, - UNCONDITIONAL_RECURSION, - UNCOVERED_PARAM_IN_PROJECTION, - UNEXPECTED_CFGS, - UNFULFILLED_LINT_EXPECTATIONS, - UNINHABITED_STATIC, - UNKNOWN_CRATE_TYPES, - UNKNOWN_DIAGNOSTIC_ATTRIBUTES, - UNKNOWN_LINTS, - UNNAMEABLE_TEST_ITEMS, - UNNAMEABLE_TYPES, - UNREACHABLE_CFG_SELECT_PREDICATES, - UNREACHABLE_CODE, - UNREACHABLE_PATTERNS, - UNSAFE_ATTR_OUTSIDE_UNSAFE, - UNSAFE_OP_IN_UNSAFE_FN, - UNSTABLE_NAME_COLLISIONS, - UNSTABLE_SYNTAX_PRE_EXPANSION, - UNSUPPORTED_CALLING_CONVENTIONS, - UNUSED_ASSIGNMENTS, - UNUSED_ASSOCIATED_TYPE_BOUNDS, - UNUSED_ATTRIBUTES, - UNUSED_CRATE_DEPENDENCIES, - UNUSED_EXTERN_CRATES, - UNUSED_FEATURES, - UNUSED_IMPORTS, - UNUSED_LABELS, - UNUSED_LIFETIMES, - UNUSED_MACROS, - UNUSED_MACRO_RULES, - UNUSED_MUT, - UNUSED_QUALIFICATIONS, - UNUSED_UNSAFE, - UNUSED_VARIABLES, - UNUSED_VISIBILITIES, - USELESS_DEPRECATED, - VARARGS_WITHOUT_PATTERN, - WARNINGS, - // tidy-alphabetical-end - ] +pub mod hardwired { + use super::*; + + pub fn lint_vec() -> crate::LintVec { + vec![ + // tidy-alphabetical-start + AARCH64_SOFTFLOAT_NEON, + ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, + AMBIGUOUS_ASSOCIATED_ITEMS, + AMBIGUOUS_DERIVE_HELPERS, + AMBIGUOUS_GLOB_IMPORTED_TRAITS, + AMBIGUOUS_GLOB_IMPORTS, + AMBIGUOUS_GLOB_REEXPORTS, + AMBIGUOUS_IMPORT_VISIBILITIES, + AMBIGUOUS_PANIC_IMPORTS, + ARITHMETIC_OVERFLOW, + ASM_SUB_REGISTER, + BAD_ASM_STYLE, + BARE_TRAIT_OBJECTS, + BINDINGS_WITH_VARIANT_NAME, + BREAK_WITH_LABEL_AND_LOOP, + COHERENCE_LEAK_CHECK, + CONFLICTING_REPR_HINTS, + CONST_EVALUATABLE_UNCHECKED, + CONST_ITEM_MUTATION, + DEAD_CODE, + DEAD_CODE_PUB_IN_BINARY, + DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, + DEPRECATED, + DEPRECATED_IN_FUTURE, + DEPRECATED_LLVM_INTRINSIC, + DEPRECATED_SAFE_2024, + DEPRECATED_WHERE_CLAUSE_LOCATION, + DUPLICATE_FEATURES, + DUPLICATE_MACRO_ATTRIBUTES, + ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, + ELIDED_LIFETIMES_IN_PATHS, + EXPLICIT_BUILTIN_CFGS_IN_FLAGS, + EXPORTED_PRIVATE_DEPENDENCIES, + FFI_UNWIND_CALLS, + FLOAT_LITERAL_F32_FALLBACK, + FORBIDDEN_LINT_GROUPS, + FUNCTION_ITEM_REFERENCES, + HIDDEN_GLOB_REEXPORTS, + ILL_FORMED_ATTRIBUTE_INPUT, + INCOMPLETE_INCLUDE, + INEFFECTIVE_UNSTABLE_TRAIT_IMPL, + INLINE_NO_SANITIZE, + INVALID_DOC_ATTRIBUTES, + INVALID_MACRO_EXPORT_ARGUMENTS, + INVALID_TYPE_PARAM_DEFAULT, + IRREFUTABLE_LET_PATTERNS, + LARGE_ASSIGNMENTS, + LATE_BOUND_LIFETIME_ARGUMENTS, + LEGACY_DERIVE_HELPERS, + LINKER_INFO, + LINKER_MESSAGES, + LONG_RUNNING_CONST_EVAL, + MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, + MACRO_USE_EXTERN_CRATE, + MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, + META_VARIABLE_MISUSE, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, + MISSING_ABI, + MISSING_UNSAFE_ON_EXTERN, + MUST_NOT_SUSPEND, + NAMED_ARGUMENTS_USED_POSITIONALLY, + NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, + NON_CONTIGUOUS_RANGE_ENDPOINTS, + NON_EXHAUSTIVE_OMITTED_PATTERNS, + OUT_OF_SCOPE_MACRO_CALLS, + OVERLAPPING_RANGE_ENDPOINTS, + PATTERNS_IN_FNS_WITHOUT_BODY, + PRIVATE_BOUNDS, + PRIVATE_INTERFACES, + PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + PUB_USE_OF_PRIVATE_EXTERN_CRATE, + REDUNDANT_IMPORTS, + REDUNDANT_LIFETIMES, + REFINING_IMPL_TRAIT_INTERNAL, + REFINING_IMPL_TRAIT_REACHABLE, + RENAMED_AND_REMOVED_LINTS, + REPR_C_ENUMS_LARGER_THAN_INT, + RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS, + RTSAN_NONBLOCKING_ASYNC, + RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, + RUST_2021_INCOMPATIBLE_OR_PATTERNS, + RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, + RUST_2021_PRELUDE_COLLISIONS, + RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX, + RUST_2024_INCOMPATIBLE_PAT, + RUST_2024_PRELUDE_COLLISIONS, + SELF_CONSTRUCTOR_FROM_OUTER_ITEM, + SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, + SHADOWING_SUPERTRAIT_ITEMS, + SINGLE_USE_LIFETIMES, + STABLE_FEATURES, + TAIL_CALL_TRACK_CALLER, + TAIL_EXPR_DROP_ORDER, + TEST_UNSTABLE_LINT, + TEXT_DIRECTION_CODEPOINT_IN_COMMENT, + TEXT_DIRECTION_CODEPOINT_IN_LITERAL, + TRIVIAL_CASTS, + TRIVIAL_NUMERIC_CASTS, + TYVAR_BEHIND_RAW_POINTER, + UNCONDITIONAL_PANIC, + UNCONDITIONAL_RECURSION, + UNCOVERED_PARAM_IN_PROJECTION, + UNEXPECTED_CFGS, + UNFULFILLED_LINT_EXPECTATIONS, + UNINHABITED_STATIC, + UNKNOWN_CRATE_TYPES, + UNKNOWN_DIAGNOSTIC_ATTRIBUTES, + UNKNOWN_LINTS, + UNNAMEABLE_TEST_ITEMS, + UNNAMEABLE_TYPES, + UNREACHABLE_CFG_SELECT_PREDICATES, + UNREACHABLE_CODE, + UNREACHABLE_PATTERNS, + UNSAFE_ATTR_OUTSIDE_UNSAFE, + UNSAFE_OP_IN_UNSAFE_FN, + UNSTABLE_NAME_COLLISIONS, + UNSTABLE_SYNTAX_PRE_EXPANSION, + UNSUPPORTED_CALLING_CONVENTIONS, + UNUSED_ASSIGNMENTS, + UNUSED_ASSOCIATED_TYPE_BOUNDS, + UNUSED_ATTRIBUTES, + UNUSED_CRATE_DEPENDENCIES, + UNUSED_EXTERN_CRATES, + UNUSED_FEATURES, + UNUSED_IMPORTS, + UNUSED_LABELS, + UNUSED_LIFETIMES, + UNUSED_MACROS, + UNUSED_MACRO_RULES, + UNUSED_MUT, + UNUSED_QUALIFICATIONS, + UNUSED_UNSAFE, + UNUSED_VARIABLES, + UNUSED_VISIBILITIES, + USELESS_DEPRECATED, + VARARGS_WITHOUT_PATTERN, + WARNINGS, + // tidy-alphabetical-end + ] + } } declare_lint! { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 72990de7e58aa..c2c7041c663df 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -878,6 +878,8 @@ symbols! { // to be detected if it accidentally does get used. empty: "", empty_braces: "{}", + empty_brackets: "[]", + empty_parens: "()", enable, end, entry_nops, @@ -1698,6 +1700,7 @@ symbols! { return_address, return_position_impl_trait_in_trait, return_type_notation, + right_arrow: "->", riscv32, riscv64, riscv_target_feature, diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 914db4bd75c0b..51ab9b5fd1eac 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -27,6 +27,7 @@ where I: [const] SliceIndex<[T]>, { #[inline(always)] + #[rustc_no_writable] fn index_mut(&mut self, index: I) -> &mut I::Output { index.index_mut(self) } @@ -185,6 +186,7 @@ const unsafe impl SliceIndex<[T]> for usize { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { if self < slice.len() { // SAFETY: `self` is checked to be in bounds. @@ -233,6 +235,7 @@ const unsafe impl SliceIndex<[T]> for usize { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut T { // N.B., use intrinsic indexing &mut (*slice)[self] @@ -256,6 +259,7 @@ const unsafe impl SliceIndex<[T]> for ops::IndexRange { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if self.end() <= slice.len() { // SAFETY: `self` is checked to be valid and in bounds above. @@ -304,6 +308,7 @@ const unsafe impl SliceIndex<[T]> for ops::IndexRange { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.end() <= slice.len() { // SAFETY: `self` is checked to be valid and in bounds above. @@ -336,6 +341,7 @@ const unsafe impl SliceIndex<[T]> for ops::Range { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if let Some(new_len) = usize::checked_sub(self.end, self.start) && self.end <= slice.len() @@ -405,6 +411,7 @@ const unsafe impl SliceIndex<[T]> for ops::Range { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { // Using checked_sub is a safe way to get `SubUnchecked` in MIR if let Some(new_len) = usize::checked_sub(self.end, self.start) @@ -429,6 +436,7 @@ const unsafe impl SliceIndex<[T]> for range::Range { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { ops::Range::from(self).get_mut(slice) } @@ -451,6 +459,7 @@ const unsafe impl SliceIndex<[T]> for range::Range { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { ops::Range::from(self).index_mut(slice) } @@ -468,6 +477,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeTo { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..self.end).get_mut(slice) } @@ -490,6 +500,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeTo { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..self.end).index_mut(slice) } @@ -507,6 +518,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeFrom { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (self.start..slice.len()).get_mut(slice) } @@ -536,6 +548,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeFrom { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { if self.start > slice.len() { slice_index_fail(self.start, slice.len(), slice.len()) @@ -559,6 +572,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeFrom { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { ops::RangeFrom::from(self).get_mut(slice) } @@ -581,6 +595,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeFrom { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { ops::RangeFrom::from(self).index_mut(slice) } @@ -597,6 +612,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeFull { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { Some(slice) } @@ -617,6 +633,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeFull { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { slice } @@ -636,6 +653,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeInclusive { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { if *self.end() >= slice.len() { None } else { self.into_slice_range().get_mut(slice) } } @@ -668,6 +686,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeInclusive { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { let Self { mut start, mut end, exhausted } = self; let len = slice.len(); @@ -694,6 +713,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeInclusive { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { ops::RangeInclusive::from(self).get_mut(slice) } @@ -716,6 +736,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeInclusive { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { ops::RangeInclusive::from(self).index_mut(slice) } @@ -733,6 +754,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..=self.end).get_mut(slice) } @@ -755,6 +777,7 @@ const unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.end).index_mut(slice) } @@ -772,6 +795,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeToInclusive { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { (0..=self.last).get_mut(slice) } @@ -794,6 +818,7 @@ const unsafe impl SliceIndex<[T]> for range::RangeToInclusive { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut [T] { (0..=self.last).index_mut(slice) } @@ -1007,6 +1032,7 @@ unsafe impl SliceIndex<[T]> for (ops::Bound, ops::Bound) { } #[inline] + #[rustc_no_writable] fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { try_into_slice_range(slice.len(), self)?.get_mut(slice) } @@ -1029,6 +1055,7 @@ unsafe impl SliceIndex<[T]> for (ops::Bound, ops::Bound) { } #[inline] + #[rustc_no_writable] fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { into_slice_range(slice.len(), self).index_mut(slice) } diff --git a/library/std/src/attribute_docs.rs b/library/std/src/attribute_docs.rs new file mode 100644 index 0000000000000..1d8dddb7ca54a --- /dev/null +++ b/library/std/src/attribute_docs.rs @@ -0,0 +1,87 @@ +#[doc(attribute = "must_use")] +// +/// Warn when a value is ignored. +/// +/// The `must_use` attribute applies to values where simply creating or returning them is +/// often not enough. If a value marked with `#[must_use]` is produced and then ignored, the +/// compiler warns through the [`unused_must_use`] lint. +/// +/// This is most common on types that represent an important state or outcome. For example, +/// [`Result`] is marked `#[must_use]` because ignoring an error value can hide a failed operation. +/// In the following example, the returned `Result` is the only sign that writing the message +/// might have failed: +/// +/// ```rust +/// # #![allow(unused_must_use)] +/// fn write_message() -> std::io::Result<()> { +/// // Write the message... +/// Ok(()) +/// } +/// +/// write_message(); +/// ``` +/// +/// Ignoring that `Result` triggers this warning: +/// +/// ```text +/// warning: unused `Result` that must be used +/// = note: this `Result` may be an `Err` variant, which should be handled +/// = note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default +/// help: use `let _ = ...` to ignore the resulting value +/// ``` +/// +/// Future values are also `#[must_use]`: creating a future does not run it, so ignoring one often +/// means the intended asynchronous work never happens. +/// +/// You can also place `#[must_use]` on a function, method, or trait declaration. On a function or +/// method, the warning is tied to ignoring that call's return value: +/// +/// ```rust +/// # #![allow(unused_must_use)] +/// #[must_use] +/// fn make_token() -> String { +/// String::from("token") +/// } +/// +/// // Ignoring this call's return value triggers `unused_must_use`. +/// make_token(); +/// ``` +/// +/// On a trait, the warning applies when a function returns an opaque type (`impl Trait`) or trait +/// object (`dyn Trait`) whose bounds include that trait. This is how futures warn if you create one +/// but never poll or await it, since an `async fn` returns an opaque type implementing [`Future`]. +/// +/// The attribute can include a message explaining what the caller should do with the value: +/// +/// ```rust +/// # #![allow(dead_code)] +/// #[must_use = "call `.finish()` to complete the operation"] +/// fn start_operation() -> Operation { +/// Operation +/// } +/// +/// struct Operation; +/// ``` +/// +/// If intentionally ignoring the value is correct, bind it to `_` or call [`drop`]: +/// +/// ```rust +/// # #[must_use] +/// # fn make_token() -> String { +/// # String::from("token") +/// # } +/// let _ = make_token(); +/// drop(make_token()); +/// ``` +/// +/// The attribute is a warning tool, not a type-system rule. Code can still explicitly discard a +/// `#[must_use]` value, and the compiler does not require callers to inspect or otherwise act on +/// the value. +/// +/// For more information, see the Reference on [the `must_use` attribute]. +/// +/// [`Result`]: result::Result +/// [`Future`]: future::Future +/// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use +/// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute +mod must_use_attribute {} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0c64c16d045e3..c9e884d89c85e 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -787,6 +787,11 @@ include!("../../core/src/primitive_docs.rs"); // because rustdoc only looks for these modules at the crate level. include!("keyword_docs.rs"); +// Include private modules that exist solely to provide rustdoc +// documentation for built-in attributes. Using `include!` because rustdoc +// only looks for these modules at the crate level. +include!("attribute_docs.rs"); + // This is required to avoid an unstable error when `restricted-std` is not // enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std // is unconditional, so the unstable feature needs to be defined somewhere. diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 00aeb70e6e076..955d1f61e7535 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -26,9 +26,10 @@ //! non-zero exit code. //! //! When the main thread of a Rust program terminates, the entire program shuts -//! down, even if other threads are still running. However, this module provides -//! convenient facilities for automatically waiting for the termination of a -//! thread (i.e., join). +//! down, even if other threads are still running, and any destructors on the +//! remaining threads' stacks may not be executed. However, this module +//! provides convenient facilities for automatically waiting for the +//! termination of a thread (i.e., join). //! //! ## Spawning a thread //! diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f49840a4b21f9..a2ab1d99d9b75 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -323,7 +323,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { warn!( "tried to get argument name from PatKind::Expr, which is silly in function arguments" ); - return Symbol::intern("()"); + return sym::empty_parens; } PatKind::Slice(begin, mid, end) => { fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display { diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 6ee56cdd5a8a3..6ebd9a5ab9da5 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1787,7 +1787,7 @@ pub(crate) fn build_index( RenderTypeId::Primitive(PrimitiveType::Array | PrimitiveType::Slice) => { insert_into_map( ItemType::Primitive, - &[Symbol::intern("[]")], + &[sym::empty_brackets], None, false, serialized_index, @@ -1798,7 +1798,7 @@ pub(crate) fn build_index( // typeNameIdOfArrayOrSlice insert_into_map( ItemType::Primitive, - &[Symbol::intern("()")], + &[sym::empty_parens], None, false, serialized_index, @@ -1809,7 +1809,7 @@ pub(crate) fn build_index( RenderTypeId::Primitive(PrimitiveType::Fn) => { insert_into_map( ItemType::Primitive, - &[Symbol::intern("->")], + &[sym::right_arrow], None, false, serialized_index, @@ -1823,7 +1823,7 @@ pub(crate) fn build_index( { insert_into_map( ItemType::Primitive, - &[Symbol::intern("->")], + &[sym::right_arrow], None, false, serialized_index, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 24fa74cc84321..a4f8e3e12e510 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -16,6 +16,7 @@ #![feature(variant_count)] #![recursion_limit = "256"] #![warn(rustc::internal)] +#![warn(rustc::symbol_intern_string_literal)] // tidy-alphabetical-end // N.B. these need `extern crate` even in 2018 edition diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index b09ea05688595..91f92b799889b 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -31,9 +31,9 @@ where allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints::lint_vec() + lint::builtin::hardwired::lint_vec() .into_iter() - .chain(rustc_lint::SoftLints::lint_vec()) + .chain(rustc_lint::builtin::soft::lint_vec()) }; let lint_opts = lints() diff --git a/src/tools/miri/tests/pass/tree_borrows/implicit_writes/unchecked_mut.rs b/src/tools/miri/tests/pass/tree_borrows/slice_get_mut_no_implicit_write.rs similarity index 50% rename from src/tools/miri/tests/pass/tree_borrows/implicit_writes/unchecked_mut.rs rename to src/tools/miri/tests/pass/tree_borrows/slice_get_mut_no_implicit_write.rs index e2785183ff599..789f0a8b88ce6 100644 --- a/src/tools/miri/tests/pass/tree_borrows/implicit_writes/unchecked_mut.rs +++ b/src/tools/miri/tests/pass/tree_borrows/slice_get_mut_no_implicit_write.rs @@ -1,28 +1,48 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes + // This test reproduces the pattern used by `BorrowedCursor::as_mut`, which appears in `Socket::recv_with_flags` and `std::fs::read`. // Many crates depend on similar patterns. Before https://github.com/rust-lang/rust/pull/157202 this failed under Tree // Borrows with Implicit Writes. With the attribute `#[rustc_no_writable]` added to // `slice::get_unchecked_mut`, both this test and the affected crates work. -//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes - -struct BorrowedBuf<'a> { - buf: &'a mut [u8], -} - -impl<'a> BorrowedBuf<'a> { - fn capacity(&self) -> usize { - self.buf.len() +fn borrowed_buf() { + struct BorrowedBuf<'a> { + buf: &'a mut [u8], } - unsafe fn as_mut(&mut self) -> &mut [u8] { - unsafe { self.buf.get_unchecked_mut(..) } + impl<'a> BorrowedBuf<'a> { + fn capacity(&self) -> usize { + self.buf.len() + } + + unsafe fn as_mut(&mut self) -> &mut [u8] { + unsafe { self.buf.get_unchecked_mut(..) } + } } -} -fn main() { let mut arr = [0u8; 4]; let mut buf = BorrowedBuf { buf: &mut arr }; let ptr = unsafe { buf.as_mut() }.as_mut_ptr(); let _ = buf.capacity(); - unsafe { ptr.write(42); } + unsafe { + ptr.write(42); + } +} + +// A variant of the above that uses `index_mut` notation. +fn index_mut() { + fn dostuff(x: &mut [u8]) { + unsafe { + let ptr = (&mut x[..]).as_mut_ptr(); + let _len = x.len(); + ptr.write(99); + } + } + + dostuff(&mut [1, 2, 3, 4]); +} + +fn main() { + borrowed_buf(); + index_mut(); }