| author | bors <bors@rust-lang.org> 2026-05-25 13:13:32 UTC |
| committer | bors <bors@rust-lang.org> 2026-05-25 13:13:32 UTC |
| log | 50439483a755a404e7d36f877fe283d44662b50f |
| tree | b4dd8c5ee6254d1c771a23f0a176e39484822777 |
| parent | 6083f7891b5088184968e050d0eaecc7bcfd2b3d |
| parent | 9545845017f8922623e6613c7d860bbfe020c8c6 |
Rollup of 3 pull requests
Successful merges:
- rust-lang/rust#156862 (Convert strict_provenance_lints to late lint passes)
- rust-lang/rust#156879 (Replace rustfmt code of conduct with link)
- rust-lang/rust#156901 (compiletest: Simplify `//@ needs-asm-mnemonic: ret` to just `//@ needs-asm-ret`)19 files changed, 296 insertions(+), 468 deletions(-)
compiler/rustc_hir_typeck/src/cast.rs+3-62| ... | ... | @@ -28,7 +28,6 @@ |
| 28 | 28 | //! expression, `e as U2` is not necessarily so (in fact it will only be valid if |
| 29 | 29 | //! `U1` coerces to `U2`). |
| 30 | 30 | |
| 31 | use rustc_ast::util::parser::ExprPrecedence; | |
| 32 | 31 | use rustc_data_structures::fx::FxHashSet; |
| 33 | 32 | use rustc_errors::codes::*; |
| 34 | 33 | use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; |
| ... | ... | @@ -860,19 +859,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 860 | 859 | (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast |
| 861 | 860 | |
| 862 | 861 | // ptr-addr-cast |
| 863 | (Ptr(m_expr), Int(t_c)) => { | |
| 864 | self.lossy_provenance_ptr2int_lint(fcx, t_c); | |
| 865 | self.check_ptr_addr_cast(fcx, m_expr) | |
| 866 | } | |
| 862 | (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), | |
| 863 | ||
| 867 | 864 | (FnPtr, Int(_)) => { |
| 868 | 865 | // FIXME(#95489): there should eventually be a lint for these casts |
| 869 | 866 | Ok(CastKind::FnPtrAddrCast) |
| 870 | 867 | } |
| 871 | 868 | // addr-ptr-cast |
| 872 | (Int(_), Ptr(mt)) => { | |
| 873 | self.fuzzy_provenance_int2ptr_lint(fcx); | |
| 874 | self.check_addr_ptr_cast(fcx, mt) | |
| 875 | } | |
| 869 | (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), | |
| 876 | 870 | // fn-ptr-cast |
| 877 | 871 | (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt), |
| 878 | 872 | |
| ... | ... | @@ -1133,59 +1127,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 1133 | 1127 | } |
| 1134 | 1128 | } |
| 1135 | 1129 | |
| 1136 | fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) { | |
| 1137 | let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); | |
| 1138 | let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); | |
| 1139 | ||
| 1140 | let sugg = self.span.can_be_used_for_suggestions().then(|| { | |
| 1141 | let expr_prec = fcx.precedence(self.expr); | |
| 1142 | let needs_parens = expr_prec < ExprPrecedence::Unambiguous; | |
| 1143 | let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize)); | |
| 1144 | let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span); | |
| 1145 | let expr_span = self.expr_span.shrink_to_lo(); | |
| 1146 | match (needs_parens, needs_cast) { | |
| 1147 | (true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast { | |
| 1148 | expr_span, | |
| 1149 | cast_span, | |
| 1150 | cast_ty, | |
| 1151 | }, | |
| 1152 | (true, false) => { | |
| 1153 | errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span } | |
| 1154 | } | |
| 1155 | (false, true) => { | |
| 1156 | errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty } | |
| 1157 | } | |
| 1158 | (false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span }, | |
| 1159 | } | |
| 1160 | }); | |
| 1161 | ||
| 1162 | let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg }; | |
| 1163 | fcx.tcx.emit_node_span_lint( | |
| 1164 | lint::builtin::LOSSY_PROVENANCE_CASTS, | |
| 1165 | self.expr.hir_id, | |
| 1166 | self.span, | |
| 1167 | lint, | |
| 1168 | ); | |
| 1169 | } | |
| 1170 | ||
| 1171 | fn fuzzy_provenance_int2ptr_lint(&self, fcx: &FnCtxt<'a, 'tcx>) { | |
| 1172 | let sugg = self.span.can_be_used_for_suggestions().then(|| { | |
| 1173 | errors::LossyProvenanceInt2PtrSuggestion { | |
| 1174 | lo: self.expr_span.shrink_to_lo(), | |
| 1175 | hi: self.expr_span.shrink_to_hi().to(self.cast_span), | |
| 1176 | } | |
| 1177 | }); | |
| 1178 | let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); | |
| 1179 | let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); | |
| 1180 | let lint = errors::LossyProvenanceInt2Ptr { expr_ty, cast_ty, sugg }; | |
| 1181 | fcx.tcx.emit_node_span_lint( | |
| 1182 | lint::builtin::FUZZY_PROVENANCE_CASTS, | |
| 1183 | self.expr.hir_id, | |
| 1184 | self.span, | |
| 1185 | lint, | |
| 1186 | ); | |
| 1187 | } | |
| 1188 | ||
| 1189 | 1130 | /// Attempt to suggest using `.is_empty` when trying to cast from a |
| 1190 | 1131 | /// collection type to a boolean. |
| 1191 | 1132 | fn try_suggest_collection_to_bool(&self, fcx: &FnCtxt<'a, 'tcx>, err: &mut Diag<'_>) { |
compiler/rustc_hir_typeck/src/errors.rs-82| ... | ... | @@ -377,18 +377,6 @@ impl Subdiagnostic for TypeMismatchFruTypo { |
| 377 | 377 | } |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | #[derive(Diagnostic)] | |
| 381 | #[diag("strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`")] | |
| 382 | #[help( | |
| 383 | "if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead" | |
| 384 | )] | |
| 385 | pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { | |
| 386 | pub expr_ty: Ty<'tcx>, | |
| 387 | pub cast_ty: Ty<'tcx>, | |
| 388 | #[subdiagnostic] | |
| 389 | pub sugg: Option<LossyProvenanceInt2PtrSuggestion>, | |
| 390 | } | |
| 391 | ||
| 392 | 380 | #[derive(Diagnostic)] |
| 393 | 381 | #[diag("cannot add {$traits_len -> |
| 394 | 382 | [1] auto trait {$traits} |
| ... | ... | @@ -404,76 +392,6 @@ pub(crate) struct PtrCastAddAutoToObject { |
| 404 | 392 | pub traits: DiagSymbolList<String>, |
| 405 | 393 | } |
| 406 | 394 | |
| 407 | #[derive(Subdiagnostic)] | |
| 408 | #[multipart_suggestion( | |
| 409 | "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address", | |
| 410 | applicability = "has-placeholders" | |
| 411 | )] | |
| 412 | pub(crate) struct LossyProvenanceInt2PtrSuggestion { | |
| 413 | #[suggestion_part(code = "(...).with_addr(")] | |
| 414 | pub lo: Span, | |
| 415 | #[suggestion_part(code = ")")] | |
| 416 | pub hi: Span, | |
| 417 | } | |
| 418 | ||
| 419 | #[derive(Diagnostic)] | |
| 420 | #[diag( | |
| 421 | "under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`" | |
| 422 | )] | |
| 423 | #[help( | |
| 424 | "if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead" | |
| 425 | )] | |
| 426 | pub(crate) struct LossyProvenancePtr2Int<'tcx> { | |
| 427 | pub expr_ty: Ty<'tcx>, | |
| 428 | pub cast_ty: Ty<'tcx>, | |
| 429 | #[subdiagnostic] | |
| 430 | pub sugg: Option<LossyProvenancePtr2IntSuggestion<'tcx>>, | |
| 431 | } | |
| 432 | ||
| 433 | #[derive(Subdiagnostic)] | |
| 434 | pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { | |
| 435 | #[multipart_suggestion( | |
| 436 | "use `.addr()` to obtain the address of a pointer", | |
| 437 | applicability = "maybe-incorrect" | |
| 438 | )] | |
| 439 | NeedsParensCast { | |
| 440 | #[suggestion_part(code = "(")] | |
| 441 | expr_span: Span, | |
| 442 | #[suggestion_part(code = ").addr() as {cast_ty}")] | |
| 443 | cast_span: Span, | |
| 444 | cast_ty: Ty<'tcx>, | |
| 445 | }, | |
| 446 | #[multipart_suggestion( | |
| 447 | "use `.addr()` to obtain the address of a pointer", | |
| 448 | applicability = "maybe-incorrect" | |
| 449 | )] | |
| 450 | NeedsParens { | |
| 451 | #[suggestion_part(code = "(")] | |
| 452 | expr_span: Span, | |
| 453 | #[suggestion_part(code = ").addr()")] | |
| 454 | cast_span: Span, | |
| 455 | }, | |
| 456 | #[suggestion( | |
| 457 | "use `.addr()` to obtain the address of a pointer", | |
| 458 | code = ".addr() as {cast_ty}", | |
| 459 | applicability = "maybe-incorrect" | |
| 460 | )] | |
| 461 | NeedsCast { | |
| 462 | #[primary_span] | |
| 463 | cast_span: Span, | |
| 464 | cast_ty: Ty<'tcx>, | |
| 465 | }, | |
| 466 | #[suggestion( | |
| 467 | "use `.addr()` to obtain the address of a pointer", | |
| 468 | code = ".addr()", | |
| 469 | applicability = "maybe-incorrect" | |
| 470 | )] | |
| 471 | Other { | |
| 472 | #[primary_span] | |
| 473 | cast_span: Span, | |
| 474 | }, | |
| 475 | } | |
| 476 | ||
| 477 | 395 | #[derive(Subdiagnostic)] |
| 478 | 396 | pub(crate) enum HelpUseLatestEdition { |
| 479 | 397 | #[help("set `edition = \"{$edition}\"` in `Cargo.toml`")] |
compiler/rustc_lint/src/fuzzy_provenance_casts.rs created+79| ... | ... | @@ -0,0 +1,79 @@ |
| 1 | use rustc_hir as hir; | |
| 2 | use rustc_session::{declare_lint, declare_lint_pass}; | |
| 3 | ||
| 4 | use crate::lints::{LossyProvenanceInt2Ptr, LossyProvenanceInt2PtrSuggestion}; | |
| 5 | use crate::{LateContext, LateLintPass}; | |
| 6 | ||
| 7 | declare_lint! { | |
| 8 | /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer | |
| 9 | /// and a pointer. | |
| 10 | /// | |
| 11 | /// ### Example | |
| 12 | /// | |
| 13 | /// ```rust | |
| 14 | /// #![feature(strict_provenance_lints)] | |
| 15 | /// #![warn(fuzzy_provenance_casts)] | |
| 16 | /// | |
| 17 | /// fn main() { | |
| 18 | /// let _dangling = 16_usize as *const u8; | |
| 19 | /// } | |
| 20 | /// ``` | |
| 21 | /// | |
| 22 | /// {{produces}} | |
| 23 | /// | |
| 24 | /// ### Explanation | |
| 25 | /// | |
| 26 | /// This lint is part of the strict provenance effort, see [issue #95228]. | |
| 27 | /// Casting an integer to a pointer is considered bad style, as a pointer | |
| 28 | /// contains, besides the *address* also a *provenance*, indicating what | |
| 29 | /// memory the pointer is allowed to read/write. Casting an integer, which | |
| 30 | /// doesn't have provenance, to a pointer requires the compiler to assign | |
| 31 | /// (guess) provenance. The compiler assigns "all exposed valid" (see the | |
| 32 | /// docs of [`ptr::with_exposed_provenance`] for more information about this | |
| 33 | /// "exposing"). This penalizes the optimiser and is not well suited for | |
| 34 | /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI | |
| 35 | /// platforms). | |
| 36 | /// | |
| 37 | /// It is much better to use [`ptr::with_addr`] instead to specify the | |
| 38 | /// provenance you want. If using this function is not possible because the | |
| 39 | /// code relies on exposed provenance then there is as an escape hatch | |
| 40 | /// [`ptr::with_exposed_provenance`]. | |
| 41 | /// | |
| 42 | /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 | |
| 43 | /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr | |
| 44 | /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html | |
| 45 | pub FUZZY_PROVENANCE_CASTS, | |
| 46 | Allow, | |
| 47 | "a fuzzy integer to pointer cast is used", | |
| 48 | @feature_gate = strict_provenance_lints; | |
| 49 | } | |
| 50 | ||
| 51 | declare_lint_pass!( | |
| 52 | /// Lint for `as` casts between an integer and a pointer. | |
| 53 | FuzzyProvenanceCasts => [FUZZY_PROVENANCE_CASTS] | |
| 54 | ); | |
| 55 | ||
| 56 | impl<'tcx> LateLintPass<'tcx> for FuzzyProvenanceCasts { | |
| 57 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { | |
| 58 | let hir::ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind else { return }; | |
| 59 | ||
| 60 | let typeck_results = cx.typeck_results(); | |
| 61 | // Only lint casts from integer to pointer | |
| 62 | let cast_from_ty = typeck_results.expr_ty(cast_from_expr); | |
| 63 | if !cast_from_ty.is_integral() { | |
| 64 | return; | |
| 65 | } | |
| 66 | let cast_to_ty = typeck_results.expr_ty(expr); | |
| 67 | if !cast_to_ty.is_raw_ptr() { | |
| 68 | return; | |
| 69 | } | |
| 70 | ||
| 71 | let sugg = | |
| 72 | expr.span.can_be_used_for_suggestions().then(|| LossyProvenanceInt2PtrSuggestion { | |
| 73 | lo: cast_from_expr.span.shrink_to_lo(), | |
| 74 | hi: cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span), | |
| 75 | }); | |
| 76 | let lint = LossyProvenanceInt2Ptr { expr_ty: cast_from_ty, cast_ty: cast_to_ty, sugg }; | |
| 77 | cx.tcx.emit_node_span_lint(FUZZY_PROVENANCE_CASTS, expr.hir_id, expr.span, lint) | |
| 78 | } | |
| 79 | } |
compiler/rustc_lint/src/lib.rs+6| ... | ... | @@ -45,6 +45,7 @@ mod expect; |
| 45 | 45 | mod for_loops_over_fallibles; |
| 46 | 46 | mod foreign_modules; |
| 47 | 47 | mod function_cast_as_integer; |
| 48 | mod fuzzy_provenance_casts; | |
| 48 | 49 | mod gpukernel_abi; |
| 49 | 50 | mod if_let_rescope; |
| 50 | 51 | mod impl_trait_overcaptures; |
| ... | ... | @@ -56,6 +57,7 @@ mod let_underscore; |
| 56 | 57 | mod levels; |
| 57 | 58 | pub mod lifetime_syntax; |
| 58 | 59 | mod lints; |
| 60 | mod lossy_provenance_casts; | |
| 59 | 61 | mod macro_expr_fragment_specifier_2024_migration; |
| 60 | 62 | mod map_unit_fn; |
| 61 | 63 | mod multiple_supertrait_upcastable; |
| ... | ... | @@ -92,6 +94,7 @@ use drop_forget_useless::*; |
| 92 | 94 | use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; |
| 93 | 95 | use for_loops_over_fallibles::*; |
| 94 | 96 | use function_cast_as_integer::*; |
| 97 | use fuzzy_provenance_casts::FuzzyProvenanceCasts; | |
| 95 | 98 | use gpukernel_abi::*; |
| 96 | 99 | use if_let_rescope::IfLetRescope; |
| 97 | 100 | use impl_trait_overcaptures::ImplTraitOvercaptures; |
| ... | ... | @@ -100,6 +103,7 @@ use internal::*; |
| 100 | 103 | use invalid_from_utf8::*; |
| 101 | 104 | use let_underscore::*; |
| 102 | 105 | use lifetime_syntax::*; |
| 106 | use lossy_provenance_casts::LossyProvenanceCasts; | |
| 103 | 107 | use macro_expr_fragment_specifier_2024_migration::*; |
| 104 | 108 | use map_unit_fn::*; |
| 105 | 109 | use multiple_supertrait_upcastable::*; |
| ... | ... | @@ -250,6 +254,8 @@ late_lint_methods!( |
| 250 | 254 | CheckTransmutes: CheckTransmutes, |
| 251 | 255 | LifetimeSyntax: LifetimeSyntax, |
| 252 | 256 | InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, |
| 257 | FuzzyProvenanceCasts: FuzzyProvenanceCasts, | |
| 258 | LossyProvenanceCasts: LossyProvenanceCasts, | |
| 253 | 259 | ] |
| 254 | 260 | ] |
| 255 | 261 | ); |
compiler/rustc_lint/src/lints.rs+82| ... | ... | @@ -2932,3 +2932,85 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { |
| 2932 | 2932 | #[diag("`Eq::assert_receiver_is_total_eq` should never be implemented by hand")] |
| 2933 | 2933 | #[note("this method was used to add checks to the `Eq` derive macro")] |
| 2934 | 2934 | pub(crate) struct EqInternalMethodImplemented; |
| 2935 | ||
| 2936 | #[derive(Diagnostic)] | |
| 2937 | #[diag("strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`")] | |
| 2938 | #[help( | |
| 2939 | "if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead" | |
| 2940 | )] | |
| 2941 | pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { | |
| 2942 | pub expr_ty: Ty<'tcx>, | |
| 2943 | pub cast_ty: Ty<'tcx>, | |
| 2944 | #[subdiagnostic] | |
| 2945 | pub sugg: Option<LossyProvenanceInt2PtrSuggestion>, | |
| 2946 | } | |
| 2947 | ||
| 2948 | #[derive(Subdiagnostic)] | |
| 2949 | #[multipart_suggestion( | |
| 2950 | "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address", | |
| 2951 | applicability = "has-placeholders" | |
| 2952 | )] | |
| 2953 | pub(crate) struct LossyProvenanceInt2PtrSuggestion { | |
| 2954 | #[suggestion_part(code = "(...).with_addr(")] | |
| 2955 | pub lo: Span, | |
| 2956 | #[suggestion_part(code = ")")] | |
| 2957 | pub hi: Span, | |
| 2958 | } | |
| 2959 | ||
| 2960 | #[derive(Diagnostic)] | |
| 2961 | #[diag( | |
| 2962 | "under strict provenance it is considered bad style to cast pointer `{$cast_from_ty}` to integer `{$cast_to_ty}`" | |
| 2963 | )] | |
| 2964 | #[help( | |
| 2965 | "if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead" | |
| 2966 | )] | |
| 2967 | pub(crate) struct LossyProvenancePtr2Int<'tcx> { | |
| 2968 | pub cast_from_ty: Ty<'tcx>, | |
| 2969 | pub cast_to_ty: Ty<'tcx>, | |
| 2970 | #[subdiagnostic] | |
| 2971 | pub sugg: Option<LossyProvenancePtr2IntSuggestion<'tcx>>, | |
| 2972 | } | |
| 2973 | ||
| 2974 | #[derive(Subdiagnostic)] | |
| 2975 | pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { | |
| 2976 | #[multipart_suggestion( | |
| 2977 | "use `.addr()` to obtain the address of a pointer", | |
| 2978 | applicability = "maybe-incorrect" | |
| 2979 | )] | |
| 2980 | NeedsParensCast { | |
| 2981 | #[suggestion_part(code = "(")] | |
| 2982 | expr_span: Span, | |
| 2983 | #[suggestion_part(code = ").addr() as {cast_to_ty}")] | |
| 2984 | cast_span: Span, | |
| 2985 | cast_to_ty: Ty<'tcx>, | |
| 2986 | }, | |
| 2987 | #[multipart_suggestion( | |
| 2988 | "use `.addr()` to obtain the address of a pointer", | |
| 2989 | applicability = "maybe-incorrect" | |
| 2990 | )] | |
| 2991 | NeedsParens { | |
| 2992 | #[suggestion_part(code = "(")] | |
| 2993 | expr_span: Span, | |
| 2994 | #[suggestion_part(code = ").addr()")] | |
| 2995 | cast_span: Span, | |
| 2996 | }, | |
| 2997 | #[suggestion( | |
| 2998 | "use `.addr()` to obtain the address of a pointer", | |
| 2999 | code = ".addr() as {cast_to_ty}", | |
| 3000 | applicability = "maybe-incorrect" | |
| 3001 | )] | |
| 3002 | NeedsCast { | |
| 3003 | #[primary_span] | |
| 3004 | cast_span: Span, | |
| 3005 | cast_to_ty: Ty<'tcx>, | |
| 3006 | }, | |
| 3007 | #[suggestion( | |
| 3008 | "use `.addr()` to obtain the address of a pointer", | |
| 3009 | code = ".addr()", | |
| 3010 | applicability = "maybe-incorrect" | |
| 3011 | )] | |
| 3012 | Other { | |
| 3013 | #[primary_span] | |
| 3014 | cast_span: Span, | |
| 3015 | }, | |
| 3016 | } |
compiler/rustc_lint/src/lossy_provenance_casts.rs created+98| ... | ... | @@ -0,0 +1,98 @@ |
| 1 | use rustc_ast::util::parser::ExprPrecedence; | |
| 2 | use rustc_hir as hir; | |
| 3 | use rustc_session::{declare_lint, declare_lint_pass}; | |
| 4 | ||
| 5 | use crate::lints::{LossyProvenancePtr2Int, LossyProvenancePtr2IntSuggestion}; | |
| 6 | use crate::{LateContext, LateLintPass}; | |
| 7 | ||
| 8 | declare_lint! { | |
| 9 | /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer | |
| 10 | /// and an integer. | |
| 11 | /// | |
| 12 | /// ### Example | |
| 13 | /// | |
| 14 | /// ```rust | |
| 15 | /// #![feature(strict_provenance_lints)] | |
| 16 | /// #![warn(lossy_provenance_casts)] | |
| 17 | /// | |
| 18 | /// fn main() { | |
| 19 | /// let x: u8 = 37; | |
| 20 | /// let _addr: usize = &x as *const u8 as usize; | |
| 21 | /// } | |
| 22 | /// ``` | |
| 23 | /// | |
| 24 | /// {{produces}} | |
| 25 | /// | |
| 26 | /// ### Explanation | |
| 27 | /// | |
| 28 | /// This lint is part of the strict provenance effort, see [issue #95228]. | |
| 29 | /// Casting a pointer to an integer is a lossy operation, because beyond | |
| 30 | /// just an *address* a pointer may be associated with a particular | |
| 31 | /// *provenance*. This information is used by the optimiser and for dynamic | |
| 32 | /// analysis/dynamic program verification (e.g. Miri or CHERI platforms). | |
| 33 | /// | |
| 34 | /// Since this cast is lossy, it is considered good style to use the | |
| 35 | /// [`ptr::addr`] method instead, which has a similar effect, but doesn't | |
| 36 | /// "expose" the pointer provenance. This improves optimisation potential. | |
| 37 | /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information | |
| 38 | /// about exposing pointer provenance. | |
| 39 | /// | |
| 40 | /// If your code can't comply with strict provenance and needs to expose | |
| 41 | /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch, | |
| 42 | /// which preserves the behaviour of `as usize` casts while being explicit | |
| 43 | /// about the semantics. | |
| 44 | /// | |
| 45 | /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 | |
| 46 | /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr | |
| 47 | /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance | |
| 48 | pub LOSSY_PROVENANCE_CASTS, | |
| 49 | Allow, | |
| 50 | "a lossy pointer to integer cast is used", | |
| 51 | @feature_gate = strict_provenance_lints; | |
| 52 | } | |
| 53 | ||
| 54 | declare_lint_pass!( | |
| 55 | /// Lint for `as` casts between a pointer and an integer. | |
| 56 | LossyProvenanceCasts => [LOSSY_PROVENANCE_CASTS] | |
| 57 | ); | |
| 58 | ||
| 59 | impl<'tcx> LateLintPass<'tcx> for LossyProvenanceCasts { | |
| 60 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { | |
| 61 | let hir::ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind else { return }; | |
| 62 | ||
| 63 | let typeck_results = cx.typeck_results(); | |
| 64 | // Only lint casts from pointer to integer | |
| 65 | let cast_from_ty = typeck_results.expr_ty(cast_from_expr); | |
| 66 | if !cast_from_ty.is_raw_ptr() { | |
| 67 | return; | |
| 68 | } | |
| 69 | let cast_to_ty = typeck_results.expr_ty(expr); | |
| 70 | if !cast_to_ty.is_integral() { | |
| 71 | return; | |
| 72 | } | |
| 73 | ||
| 74 | let sugg = expr.span.can_be_used_for_suggestions().then(|| { | |
| 75 | let needs_parens = cx.precedence(cast_from_expr) < ExprPrecedence::Unambiguous; | |
| 76 | let needs_cast = !cast_to_ty.is_usize(); | |
| 77 | let cast_span = cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span); | |
| 78 | let expr_span = cast_from_expr.span.shrink_to_lo(); | |
| 79 | match (needs_parens, needs_cast) { | |
| 80 | (true, true) => LossyProvenancePtr2IntSuggestion::NeedsParensCast { | |
| 81 | expr_span, | |
| 82 | cast_span, | |
| 83 | cast_to_ty, | |
| 84 | }, | |
| 85 | (true, false) => { | |
| 86 | LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span } | |
| 87 | } | |
| 88 | (false, true) => { | |
| 89 | LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_to_ty } | |
| 90 | } | |
| 91 | (false, false) => LossyProvenancePtr2IntSuggestion::Other { cast_span }, | |
| 92 | } | |
| 93 | }); | |
| 94 | ||
| 95 | let lint = LossyProvenancePtr2Int { cast_from_ty, cast_to_ty, sugg }; | |
| 96 | cx.tcx.emit_node_span_lint(LOSSY_PROVENANCE_CASTS, expr.hir_id, expr.span, lint); | |
| 97 | } | |
| 98 | } |
compiler/rustc_lint_defs/src/builtin.rs-92| ... | ... | @@ -51,7 +51,6 @@ declare_lint_pass! { |
| 51 | 51 | FLOAT_LITERAL_F32_FALLBACK, |
| 52 | 52 | FORBIDDEN_LINT_GROUPS, |
| 53 | 53 | FUNCTION_ITEM_REFERENCES, |
| 54 | FUZZY_PROVENANCE_CASTS, | |
| 55 | 54 | HIDDEN_GLOB_REEXPORTS, |
| 56 | 55 | ILL_FORMED_ATTRIBUTE_INPUT, |
| 57 | 56 | INCOMPLETE_INCLUDE, |
| ... | ... | @@ -67,7 +66,6 @@ declare_lint_pass! { |
| 67 | 66 | LINKER_INFO, |
| 68 | 67 | LINKER_MESSAGES, |
| 69 | 68 | LONG_RUNNING_CONST_EVAL, |
| 70 | LOSSY_PROVENANCE_CASTS, | |
| 71 | 69 | MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, |
| 72 | 70 | MACRO_USE_EXTERN_CRATE, |
| 73 | 71 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| ... | ... | @@ -2593,96 +2591,6 @@ declare_lint! { |
| 2593 | 2591 | @edition Edition2024 => Warn; |
| 2594 | 2592 | } |
| 2595 | 2593 | |
| 2596 | declare_lint! { | |
| 2597 | /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer | |
| 2598 | /// and a pointer. | |
| 2599 | /// | |
| 2600 | /// ### Example | |
| 2601 | /// | |
| 2602 | /// ```rust | |
| 2603 | /// #![feature(strict_provenance_lints)] | |
| 2604 | /// #![warn(fuzzy_provenance_casts)] | |
| 2605 | /// | |
| 2606 | /// fn main() { | |
| 2607 | /// let _dangling = 16_usize as *const u8; | |
| 2608 | /// } | |
| 2609 | /// ``` | |
| 2610 | /// | |
| 2611 | /// {{produces}} | |
| 2612 | /// | |
| 2613 | /// ### Explanation | |
| 2614 | /// | |
| 2615 | /// This lint is part of the strict provenance effort, see [issue #95228]. | |
| 2616 | /// Casting an integer to a pointer is considered bad style, as a pointer | |
| 2617 | /// contains, besides the *address* also a *provenance*, indicating what | |
| 2618 | /// memory the pointer is allowed to read/write. Casting an integer, which | |
| 2619 | /// doesn't have provenance, to a pointer requires the compiler to assign | |
| 2620 | /// (guess) provenance. The compiler assigns "all exposed valid" (see the | |
| 2621 | /// docs of [`ptr::with_exposed_provenance`] for more information about this | |
| 2622 | /// "exposing"). This penalizes the optimiser and is not well suited for | |
| 2623 | /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI | |
| 2624 | /// platforms). | |
| 2625 | /// | |
| 2626 | /// It is much better to use [`ptr::with_addr`] instead to specify the | |
| 2627 | /// provenance you want. If using this function is not possible because the | |
| 2628 | /// code relies on exposed provenance then there is as an escape hatch | |
| 2629 | /// [`ptr::with_exposed_provenance`]. | |
| 2630 | /// | |
| 2631 | /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 | |
| 2632 | /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr | |
| 2633 | /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html | |
| 2634 | pub FUZZY_PROVENANCE_CASTS, | |
| 2635 | Allow, | |
| 2636 | "a fuzzy integer to pointer cast is used", | |
| 2637 | @feature_gate = strict_provenance_lints; | |
| 2638 | } | |
| 2639 | ||
| 2640 | declare_lint! { | |
| 2641 | /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer | |
| 2642 | /// and an integer. | |
| 2643 | /// | |
| 2644 | /// ### Example | |
| 2645 | /// | |
| 2646 | /// ```rust | |
| 2647 | /// #![feature(strict_provenance_lints)] | |
| 2648 | /// #![warn(lossy_provenance_casts)] | |
| 2649 | /// | |
| 2650 | /// fn main() { | |
| 2651 | /// let x: u8 = 37; | |
| 2652 | /// let _addr: usize = &x as *const u8 as usize; | |
| 2653 | /// } | |
| 2654 | /// ``` | |
| 2655 | /// | |
| 2656 | /// {{produces}} | |
| 2657 | /// | |
| 2658 | /// ### Explanation | |
| 2659 | /// | |
| 2660 | /// This lint is part of the strict provenance effort, see [issue #95228]. | |
| 2661 | /// Casting a pointer to an integer is a lossy operation, because beyond | |
| 2662 | /// just an *address* a pointer may be associated with a particular | |
| 2663 | /// *provenance*. This information is used by the optimiser and for dynamic | |
| 2664 | /// analysis/dynamic program verification (e.g. Miri or CHERI platforms). | |
| 2665 | /// | |
| 2666 | /// Since this cast is lossy, it is considered good style to use the | |
| 2667 | /// [`ptr::addr`] method instead, which has a similar effect, but doesn't | |
| 2668 | /// "expose" the pointer provenance. This improves optimisation potential. | |
| 2669 | /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information | |
| 2670 | /// about exposing pointer provenance. | |
| 2671 | /// | |
| 2672 | /// If your code can't comply with strict provenance and needs to expose | |
| 2673 | /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch, | |
| 2674 | /// which preserves the behaviour of `as usize` casts while being explicit | |
| 2675 | /// about the semantics. | |
| 2676 | /// | |
| 2677 | /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 | |
| 2678 | /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr | |
| 2679 | /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance | |
| 2680 | pub LOSSY_PROVENANCE_CASTS, | |
| 2681 | Allow, | |
| 2682 | "a lossy pointer to integer cast is used", | |
| 2683 | @feature_gate = strict_provenance_lints; | |
| 2684 | } | |
| 2685 | ||
| 2686 | 2594 | declare_lint! { |
| 2687 | 2595 | /// The `const_evaluatable_unchecked` lint detects a generic constant used |
| 2688 | 2596 | /// in a type. |
src/doc/rustc-dev-guide/src/tests/compiletest.md-11| ... | ... | @@ -346,17 +346,6 @@ See also the [codegen tests](#codegen-tests) for a similar set of tests. |
| 346 | 346 | If you need to work with `#![no_std]` cross-compiling tests, consult the |
| 347 | 347 | [`minicore` test auxiliary](./minicore.md) chapter. |
| 348 | 348 | |
| 349 | #### Conditional assembly tests based on instruction support | |
| 350 | ||
| 351 | Tests that depend on specific assembly instructions being available can use the | |
| 352 | `//@ needs-asm-mnemonic: <MNEMONIC>` directive. | |
| 353 | This will skip the test if the target backend does not support the specified instruction mnemonic. | |
| 354 | ||
| 355 | For example, a test that requires the `RET` instruction: | |
| 356 | ```rust,ignore | |
| 357 | //@ needs-asm-mnemonic: RET | |
| 358 | ``` | |
| 359 | ||
| 360 | 349 | [`tests/assembly-llvm`]: https://github.com/rust-lang/rust/tree/HEAD/tests/assembly-llvm |
| 361 | 350 | |
| 362 | 351 |
src/doc/rustc-dev-guide/src/tests/directives.md+4-3| ... | ... | @@ -164,9 +164,10 @@ The following directives will check rustc build settings and target settings: |
| 164 | 164 | For tests that cross-compile to explicit targets |
| 165 | 165 | via `--target`, use `needs-llvm-components` instead to ensure the appropriate |
| 166 | 166 | backend is available. |
| 167 | - `needs-asm-mnemonic: <MNEMONIC>` — ignores if the target backend does not | |
| 168 | support the specified assembly mnemonic (e.g., `RET`, `NOP`). | |
| 169 | Only supported with the LLVM backend. | |
| 167 | - `needs-asm-ret` - ignores if the target does not have a `ret` instruction | |
| 168 | in its assembly syntax. Most target architectures have this instruction, | |
| 169 | making it handy for portable inline-assembly tests, but some architectures | |
| 170 | (e.g. 32-bit ARM) do not have it. | |
| 170 | 171 | - `needs-profiler-runtime` — ignores the test if the profiler runtime was not |
| 171 | 172 | enabled for the target (`build.profiler = true` in `bootstrap.toml`) |
| 172 | 173 | - `needs-sanitizer-support` — ignores if the sanitizer support was not enabled |
src/tools/compiletest/src/directives/directive_names.rs+1-1| ... | ... | @@ -159,7 +159,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ |
| 159 | 159 | "min-llvm-version", |
| 160 | 160 | "min-system-llvm-version", |
| 161 | 161 | "minicore-compile-flags", |
| 162 | "needs-asm-mnemonic", | |
| 162 | "needs-asm-ret", | |
| 163 | 163 | "needs-asm-support", |
| 164 | 164 | "needs-backends", |
| 165 | 165 | "needs-crate-type", |
src/tools/compiletest/src/directives/needs.rs+9-41| ... | ... | @@ -101,37 +101,6 @@ pub(super) fn handle_needs( |
| 101 | 101 | } |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | if name == "needs-asm-mnemonic" { | |
| 105 | let Some(rest) = ln.value_after_colon() else { | |
| 106 | return IgnoreDecision::Error { | |
| 107 | message: "expected `needs-asm-mnemonic` to have a mnemonic name after colon" | |
| 108 | .to_string(), | |
| 109 | }; | |
| 110 | }; | |
| 111 | ||
| 112 | if !config.default_codegen_backend.is_llvm() { | |
| 113 | return IgnoreDecision::Ignore { | |
| 114 | reason: "skipping test as non-LLVM backend does not support mnemonic queries" | |
| 115 | .to_string(), | |
| 116 | }; | |
| 117 | } | |
| 118 | ||
| 119 | let mnemonic = rest.trim(); | |
| 120 | let has_mnemonic = match mnemonic { | |
| 121 | "ret" => conditions.has_ret_mnemonic, | |
| 122 | "nop" => conditions.has_nop_mnemonic, | |
| 123 | _ => has_mnemonic(config, mnemonic), | |
| 124 | }; | |
| 125 | ||
| 126 | if has_mnemonic { | |
| 127 | return IgnoreDecision::Continue; | |
| 128 | } else { | |
| 129 | return IgnoreDecision::Ignore { | |
| 130 | reason: format!("skipping test as target does not have `{mnemonic}` mnemonic"), | |
| 131 | }; | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | 104 | // Handled elsewhere. |
| 136 | 105 | if name == "needs-llvm-components" || name == "needs-backends" { |
| 137 | 106 | return IgnoreDecision::Continue; |
| ... | ... | @@ -163,11 +132,6 @@ struct Need { |
| 163 | 132 | pub(crate) struct PreparedNeedsConditions { |
| 164 | 133 | /// The `//@ needs-*` conditions that can be treated as a simple name->boolean mapping. |
| 165 | 134 | simple_needs: HashMap<&'static str, Need>, |
| 166 | ||
| 167 | /// Might add particular other mnemonics heavily needed by tests here. | |
| 168 | /// Otherwise call into llvm for every check | |
| 169 | has_ret_mnemonic: bool, | |
| 170 | has_nop_mnemonic: bool, | |
| 171 | 135 | } |
| 172 | 136 | |
| 173 | 137 | pub(crate) fn prepare_needs_conditions(config: &Config) -> PreparedNeedsConditions { |
| ... | ... | @@ -177,6 +141,14 @@ pub(crate) fn prepare_needs_conditions(config: &Config) -> PreparedNeedsConditio |
| 177 | 141 | // Note that we intentionally still put the needs- prefix here to make the file show up when |
| 178 | 142 | // grepping for a directive name, even though we could technically strip that. |
| 179 | 143 | let simple_needs = vec![ |
| 144 | // This used to be a more general `//@ needs-asm-mnemonic: ret` directive, | |
| 145 | // but was simplified to just `//@ needs-asm-ret` because there are very | |
| 146 | // few other mnemonics (`nop`?) that it could ever be useful with. | |
| 147 | Need { | |
| 148 | name: "needs-asm-ret", | |
| 149 | condition: has_mnemonic(config, "ret"), | |
| 150 | ignore_reason: "ignored on targets without a `ret` assembly instruction", | |
| 151 | }, | |
| 180 | 152 | Need { |
| 181 | 153 | name: "needs-asm-support", |
| 182 | 154 | condition: config.has_asm_support(), |
| ... | ... | @@ -398,11 +370,7 @@ pub(crate) fn prepare_needs_conditions(config: &Config) -> PreparedNeedsConditio |
| 398 | 370 | }) |
| 399 | 371 | .collect::<HashMap<_, _>>(); |
| 400 | 372 | |
| 401 | PreparedNeedsConditions { | |
| 402 | simple_needs, | |
| 403 | has_ret_mnemonic: has_mnemonic(config, "ret"), | |
| 404 | has_nop_mnemonic: has_mnemonic(config, "nop"), | |
| 405 | } | |
| 373 | PreparedNeedsConditions { simple_needs } | |
| 406 | 374 | } |
| 407 | 375 | |
| 408 | 376 | fn find_dlltool(config: &Config) -> bool { |
src/tools/compiletest/src/directives/tests.rs+9-17| ... | ... | @@ -1270,23 +1270,15 @@ fn test_edition_range_edition_to_test() { |
| 1270 | 1270 | } |
| 1271 | 1271 | |
| 1272 | 1272 | #[test] |
| 1273 | fn needs_asm_mnemonic() { | |
| 1273 | fn needs_asm_ret() { | |
| 1274 | 1274 | let config_x86_64 = cfg().target("x86_64-unknown-linux-gnu").build(); |
| 1275 | 1275 | let config_aarch64 = cfg().target("aarch64-unknown-linux-gnu").build(); |
| 1276 | ||
| 1277 | // invalid mnemonic | |
| 1278 | assert!(check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:GRUGGY")); | |
| 1279 | assert!(check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:gruggy")); | |
| 1280 | ||
| 1281 | // valid x86 and aarch64 | |
| 1282 | assert!(!check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:RET")); | |
| 1283 | assert!(!check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:ret")); | |
| 1284 | ||
| 1285 | // this is aarch64 specific | |
| 1286 | assert!(check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:ldrsbwui")); | |
| 1287 | assert!(!check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:LDRSBWui")); | |
| 1288 | ||
| 1289 | // this is x86 specific | |
| 1290 | assert!(check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:CMPxCHG16B")); | |
| 1291 | assert!(!check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:CMPXchg16B")); | |
| 1276 | // 32-bit ARM does not have a "ret" mnemonic. | |
| 1277 | let config_arm32 = cfg().target("armv7a-none-eabi").build(); | |
| 1278 | let config_wasm = cfg().target("wasm32v1-none").build(); | |
| 1279 | ||
| 1280 | assert!(!check_ignore(&config_x86_64, "//@ needs-asm-ret")); | |
| 1281 | assert!(!check_ignore(&config_aarch64, "//@ needs-asm-ret")); | |
| 1282 | assert!(check_ignore(&config_arm32, "//@ needs-asm-ret")); | |
| 1283 | assert!(check_ignore(&config_wasm, "//@ needs-asm-ret")); | |
| 1292 | 1284 | } |
src/tools/rustfmt/CODE_OF_CONDUCT.md+1-38| ... | ... | @@ -1,40 +1,3 @@ |
| 1 | 1 | # The Rust Code of Conduct |
| 2 | 2 | |
| 3 | A version of this document [can be found online](https://www.rust-lang.org/conduct.html). | |
| 4 | ||
| 5 | ## Conduct | |
| 6 | ||
| 7 | **Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org) | |
| 8 | ||
| 9 | * We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. | |
| 10 | * On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. | |
| 11 | * Please be kind and courteous. There's no need to be mean or rude. | |
| 12 | * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. | |
| 13 | * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. | |
| 14 | * We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the <a href="https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md/">Citizen Code of Conduct</a>; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. | |
| 15 | * Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. | |
| 16 | * Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. | |
| 17 | ||
| 18 | ## Moderation | |
| 19 | ||
| 20 | ||
| 21 | These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team]. | |
| 22 | ||
| 23 | 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) | |
| 24 | 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. | |
| 25 | 3. Moderators will first respond to such remarks with a warning. | |
| 26 | 4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. | |
| 27 | 5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. | |
| 28 | 6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. | |
| 29 | 7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. | |
| 30 | 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. | |
| 31 | ||
| 32 | In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. | |
| 33 | ||
| 34 | And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. | |
| 35 | ||
| 36 | The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. | |
| 37 | ||
| 38 | *Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* | |
| 39 | ||
| 40 | [mod_team]: https://www.rust-lang.org/team.html#Moderation-team | |
| 3 | The Code of Conduct for this repository [can be found online](https://www.rust-lang.org/conduct.html). |
tests/codegen-llvm/cffi/c-variadic-naked.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ needs-asm-support |
| 2 | //@ needs-asm-mnemonic: ret | |
| 2 | //@ needs-asm-ret | |
| 3 | 3 | |
| 4 | 4 | // tests that `va_start` is not injected into naked functions |
| 5 | 5 |
tests/codegen-llvm/naked-fn/aligned.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 |
| 2 | 2 | //@ needs-asm-support |
| 3 | //@ needs-asm-mnemonic: ret | |
| 3 | //@ needs-asm-ret | |
| 4 | 4 | //@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) |
| 5 | 5 | |
| 6 | 6 | #![crate_type = "lib"] |
tests/codegen-llvm/naked-fn/min-function-alignment.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16 |
| 2 | 2 | //@ needs-asm-support |
| 3 | //@ needs-asm-mnemonic: ret | |
| 3 | //@ needs-asm-ret | |
| 4 | 4 | //@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) |
| 5 | 5 | |
| 6 | 6 | // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity |
tests/run-make/naked-dead-code-elimination/rmake.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ ignore-cross-compile |
| 2 | 2 | //@ needs-asm-support |
| 3 | //@ needs-asm-mnemonic: RET | |
| 3 | //@ needs-asm-ret | |
| 4 | 4 | |
| 5 | 5 | use run_make_support::symbols::object_contains_any_symbol; |
| 6 | 6 | use run_make_support::{bin_name, rustc}; |
tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | // Regression test for #137588. | |
| 2 | // The compiler used to ICE when emitting a `fuzzy_provenance_casts` lint | |
| 3 | // diagnostic for code with an inner attribute spanning the entire file, | |
| 4 | // causing `draw_code_line` to panic on an empty `file_lines` from a dummy span. | |
| 5 | ||
| 6 | //@ edition:2024 | |
| 7 | //@ compile-flags: -Wfuzzy-provenance-casts | |
| 8 | ||
| 9 | #![feature(strict_provenance_lints)] | |
| 10 | //~^ ERROR too many leading `super` keywords [E0433] | |
| 11 | //~| ERROR cannot find type `Ts` in this scope [E0425] | |
| 12 | //~| ERROR `#[prelude_import]` is for use by rustc only [E0658] | |
| 13 | //~| WARN strict provenance disallows casting integer `usize` to pointer `*const u32` | |
| 14 | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | |
| 15 | //~^ ERROR use of unstable library feature `contracts` [E0658] | |
| 16 | //~| ERROR inner macro attributes are unstable [E0658] | |
| 17 | //~| ERROR cannot find type `Stars` in this scope [E0433] | |
| 18 | ||
| 19 | pub(super) fn foo() -> *const Ts { | |
| 20 | unsafe { | |
| 21 | let p2 = 0x52 as *const u32; | |
| 22 | } | |
| 23 | } | |
| 24 | //~^ ERROR `main` function not found in crate |
tests/ui/lint/ice-fuzzy-provenance-casts-with-inner-attr.stderr deleted-93| ... | ... | @@ -1,93 +0,0 @@ |
| 1 | error[E0658]: use of unstable library feature `contracts` | |
| 2 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:4 | |
| 3 | | | |
| 4 | LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information | |
| 8 | = help: add `#![feature(contracts)]` to the crate attributes to enable | |
| 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 10 | ||
| 11 | error[E0658]: inner macro attributes are unstable | |
| 12 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:4 | |
| 13 | | | |
| 14 | LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | |
| 15 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 16 | | | |
| 17 | = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information | |
| 18 | = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable | |
| 19 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 20 | ||
| 21 | error[E0433]: too many leading `super` keywords | |
| 22 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 | |
| 23 | | | |
| 24 | LL | / #![feature(strict_provenance_lints)] | |
| 25 | ... | | |
| 26 | LL | | } | |
| 27 | | |_^ there are too many leading `super` keywords | |
| 28 | ||
| 29 | error[E0425]: cannot find type `Ts` in this scope | |
| 30 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 | |
| 31 | | | |
| 32 | LL | / #![feature(strict_provenance_lints)] | |
| 33 | ... | | |
| 34 | LL | | } | |
| 35 | | |_^ not found in this scope | |
| 36 | ||
| 37 | error[E0658]: `#[prelude_import]` is for use by rustc only | |
| 38 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 | |
| 39 | | | |
| 40 | LL | / #![feature(strict_provenance_lints)] | |
| 41 | ... | | |
| 42 | LL | | } | |
| 43 | | |_^ | |
| 44 | | | |
| 45 | = help: add `#![feature(prelude_import)]` to the crate attributes to enable | |
| 46 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 47 | ||
| 48 | error[E0601]: `main` function not found in crate `ice_fuzzy_provenance_casts_with_inner_attr` | |
| 49 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:23:2 | |
| 50 | | | |
| 51 | LL | } | |
| 52 | | ^ consider adding a `main` function to `$DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs` | |
| 53 | ||
| 54 | error[E0433]: cannot find type `Stars` in this scope | |
| 55 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:14:50 | |
| 56 | | | |
| 57 | LL | #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | |
| 58 | | ^^^^^ use of undeclared type `Stars` | |
| 59 | ||
| 60 | warning: strict provenance disallows casting integer `usize` to pointer `*const u32` | |
| 61 | --> $DIR/ice-fuzzy-provenance-casts-with-inner-attr.rs:9:1 | |
| 62 | | | |
| 63 | LL | / #![feature(strict_provenance_lints)] | |
| 64 | ... | | |
| 65 | LL | | } | |
| 66 | | |_^ | |
| 67 | | | |
| 68 | = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead | |
| 69 | = note: requested on the command line with `-W fuzzy-provenance-casts` | |
| 70 | help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address | |
| 71 | | | |
| 72 | LL - #![feature(strict_provenance_lints)] | |
| 73 | LL - | |
| 74 | LL - | |
| 75 | LL - | |
| 76 | LL - | |
| 77 | LL - #![core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | |
| 78 | LL - | |
| 79 | LL - | |
| 80 | LL - | |
| 81 | LL - | |
| 82 | LL - pub(super) fn foo() -> *const Ts { | |
| 83 | LL - unsafe { | |
| 84 | LL - let p2 = 0x52 as *const u32; | |
| 85 | LL - } | |
| 86 | LL - } | |
| 87 | LL + (...).with_addr() | |
| 88 | | | |
| 89 | ||
| 90 | error: aborting due to 7 previous errors; 1 warning emitted | |
| 91 | ||
| 92 | Some errors have detailed explanations: E0425, E0433, E0601, E0658. | |
| 93 | For more information about an error, try `rustc --explain E0425`. |