| author | bors <bors@rust-lang.org> 2025-06-07 23:05:07 UTC |
| committer | bors <bors@rust-lang.org> 2025-06-07 23:05:07 UTC |
| log | a5584a8fe16037dc01782064fa41424a6dbe9987 |
| tree | 45868373b3a39501ee019af887db69e453052a40 |
| parent | cdd545be1b4f024d38360aa9f000dcb782fbc81b |
| parent | aa940603f543cfac35045d5be947f84d63e5609e |
Rollup of 9 pull requests
Successful merges:
- rust-lang/rust#140560 (Allow `#![doc(test(attr(..)))]` everywhere)
- rust-lang/rust#141447 (Document representation of `Option<unsafe fn()>`)
- rust-lang/rust#141661 (Make the `dangerous_implicit_autorefs` lint deny-by-default)
- rust-lang/rust#142065 (Stabilize `const_eq_ignore_ascii_case`)
- rust-lang/rust#142116 (Fix bootstrap tracing imports)
- rust-lang/rust#142126 (Treat normalizing consts like normalizing types in deeply normalize)
- rust-lang/rust#142140 (compiler: Sort and doc ExternAbi variants)
- rust-lang/rust#142148 (compiler: Treat ForceWarning as a Warning for diagnostic level)
- rust-lang/rust#142154 (get rid of spurious cfg(bootstrap))
r? `@ghost`
`@rustbot` modify labels: rollup45 files changed, 988 insertions(+), 344 deletions(-)
compiler/rustc_abi/src/extern_abi.rs+63-36| ... | ... | @@ -12,66 +12,93 @@ use crate::AbiFromStrErr; |
| 12 | 12 | #[cfg(test)] |
| 13 | 13 | mod tests; |
| 14 | 14 | |
| 15 | use ExternAbi as Abi; | |
| 16 | ||
| 15 | /// ABI we expect to see within `extern "{abi}"` | |
| 17 | 16 | #[derive(Clone, Copy, Debug)] |
| 18 | 17 | #[cfg_attr(feature = "nightly", derive(Encodable, Decodable))] |
| 19 | 18 | pub enum ExternAbi { |
| 20 | // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the | |
| 21 | // hashing tests. These are used in many places, so giving them stable values reduces test | |
| 22 | // churn. The specific values are meaningless. | |
| 23 | Rust, | |
| 19 | /* universal */ | |
| 20 | /// presumed C ABI for the platform | |
| 24 | 21 | C { |
| 25 | 22 | unwind: bool, |
| 26 | 23 | }, |
| 27 | Cdecl { | |
| 24 | /// ABI of the "system" interface, e.g. the Win32 API, always "aliasing" | |
| 25 | System { | |
| 28 | 26 | unwind: bool, |
| 29 | 27 | }, |
| 30 | Stdcall { | |
| 28 | ||
| 29 | /// that's us! | |
| 30 | Rust, | |
| 31 | /// the mostly-unused `unboxed_closures` ABI, effectively now an impl detail unless someone | |
| 32 | /// puts in the work to make it viable again... but would we need a special ABI? | |
| 33 | RustCall, | |
| 34 | /// For things unlikely to be called, where reducing register pressure in | |
| 35 | /// `extern "Rust"` callers is worth paying extra cost in the callee. | |
| 36 | /// Stronger than just `#[cold]` because `fn` pointers might be incompatible. | |
| 37 | RustCold, | |
| 38 | ||
| 39 | /// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM. | |
| 40 | /// Even normally-compatible Rust types can become ABI-incompatible with this ABI! | |
| 41 | Unadjusted, | |
| 42 | ||
| 43 | /// UEFI ABI, usually an alias of C, but sometimes an arch-specific alias | |
| 44 | /// and only valid on platforms that have a UEFI standard | |
| 45 | EfiApi, | |
| 46 | ||
| 47 | /* arm */ | |
| 48 | /// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this | |
| 49 | Aapcs { | |
| 31 | 50 | unwind: bool, |
| 32 | 51 | }, |
| 33 | Fastcall { | |
| 52 | /// extremely constrained barely-C ABI for TrustZone | |
| 53 | CCmseNonSecureCall, | |
| 54 | /// extremely constrained barely-C ABI for TrustZone | |
| 55 | CCmseNonSecureEntry, | |
| 56 | ||
| 57 | /* gpu */ | |
| 58 | /// An entry-point function called by the GPU's host | |
| 59 | // FIXME: should not be callable from Rust on GPU targets, is for host's use only | |
| 60 | GpuKernel, | |
| 61 | /// An entry-point function called by the GPU's host | |
| 62 | // FIXME: why do we have two of these? | |
| 63 | PtxKernel, | |
| 64 | ||
| 65 | /* interrupt */ | |
| 66 | AvrInterrupt, | |
| 67 | AvrNonBlockingInterrupt, | |
| 68 | Msp430Interrupt, | |
| 69 | RiscvInterruptM, | |
| 70 | RiscvInterruptS, | |
| 71 | X86Interrupt, | |
| 72 | ||
| 73 | /* x86 */ | |
| 74 | /// `ExternAbi::C` but spelled funny because x86 | |
| 75 | Cdecl { | |
| 34 | 76 | unwind: bool, |
| 35 | 77 | }, |
| 36 | Vectorcall { | |
| 78 | /// gnu-stdcall on "unix" and win-stdcall on "windows" | |
| 79 | Stdcall { | |
| 37 | 80 | unwind: bool, |
| 38 | 81 | }, |
| 39 | Thiscall { | |
| 82 | /// gnu-fastcall on "unix" and win-fastcall on "windows" | |
| 83 | Fastcall { | |
| 40 | 84 | unwind: bool, |
| 41 | 85 | }, |
| 42 | Aapcs { | |
| 86 | /// windows C++ ABI | |
| 87 | Thiscall { | |
| 43 | 88 | unwind: bool, |
| 44 | 89 | }, |
| 45 | Win64 { | |
| 90 | /// uses AVX and stuff | |
| 91 | Vectorcall { | |
| 46 | 92 | unwind: bool, |
| 47 | 93 | }, |
| 94 | ||
| 95 | /* x86_64 */ | |
| 48 | 96 | SysV64 { |
| 49 | 97 | unwind: bool, |
| 50 | 98 | }, |
| 51 | PtxKernel, | |
| 52 | Msp430Interrupt, | |
| 53 | X86Interrupt, | |
| 54 | /// An entry-point function called by the GPU's host | |
| 55 | // FIXME: should not be callable from Rust on GPU targets, is for host's use only | |
| 56 | GpuKernel, | |
| 57 | EfiApi, | |
| 58 | AvrInterrupt, | |
| 59 | AvrNonBlockingInterrupt, | |
| 60 | CCmseNonSecureCall, | |
| 61 | CCmseNonSecureEntry, | |
| 62 | System { | |
| 99 | Win64 { | |
| 63 | 100 | unwind: bool, |
| 64 | 101 | }, |
| 65 | RustCall, | |
| 66 | /// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even | |
| 67 | /// normally ABI-compatible Rust types can become ABI-incompatible with this ABI! | |
| 68 | Unadjusted, | |
| 69 | /// For things unlikely to be called, where reducing register pressure in | |
| 70 | /// `extern "Rust"` callers is worth paying extra cost in the callee. | |
| 71 | /// Stronger than just `#[cold]` because `fn` pointers might be incompatible. | |
| 72 | RustCold, | |
| 73 | RiscvInterruptM, | |
| 74 | RiscvInterruptS, | |
| 75 | 102 | } |
| 76 | 103 | |
| 77 | 104 | macro_rules! abi_impls { |
| ... | ... | @@ -224,7 +251,7 @@ pub fn all_names() -> Vec<&'static str> { |
| 224 | 251 | |
| 225 | 252 | impl ExternAbi { |
| 226 | 253 | /// Default ABI chosen for `extern fn` declarations without an explicit ABI. |
| 227 | pub const FALLBACK: Abi = Abi::C { unwind: false }; | |
| 254 | pub const FALLBACK: ExternAbi = ExternAbi::C { unwind: false }; | |
| 228 | 255 | |
| 229 | 256 | pub fn name(self) -> &'static str { |
| 230 | 257 | self.as_str() |
compiler/rustc_errors/src/lib.rs+1-1| ... | ... | @@ -1529,7 +1529,7 @@ impl DiagCtxtInner { |
| 1529 | 1529 | // Future breakages aren't emitted if they're `Level::Allow` or |
| 1530 | 1530 | // `Level::Expect`, but they still need to be constructed and |
| 1531 | 1531 | // stashed below, so they'll trigger the must_produce_diag check. |
| 1532 | assert_matches!(diagnostic.level, Error | Warning | Allow | Expect); | |
| 1532 | assert_matches!(diagnostic.level, Error | ForceWarning | Warning | Allow | Expect); | |
| 1533 | 1533 | self.future_breakage_diagnostics.push(diagnostic.clone()); |
| 1534 | 1534 | } |
| 1535 | 1535 |
compiler/rustc_infer/src/infer/mod.rs+7| ... | ... | @@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> { |
| 823 | 823 | ty::Region::new_var(self.tcx, region_var) |
| 824 | 824 | } |
| 825 | 825 | |
| 826 | pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> { | |
| 827 | match term.kind() { | |
| 828 | ty::TermKind::Ty(_) => self.next_ty_var(span).into(), | |
| 829 | ty::TermKind::Const(_) => self.next_const_var(span).into(), | |
| 830 | } | |
| 831 | } | |
| 832 | ||
| 826 | 833 | /// Return the universe that the region `r` was created in. For |
| 827 | 834 | /// most regions (e.g., `'static`, named regions from the user, |
| 828 | 835 | /// etc) this is the root universe U0. For inference variables or |
compiler/rustc_lint/src/autorefs.rs+2-2| ... | ... | @@ -16,7 +16,7 @@ declare_lint! { |
| 16 | 16 | /// |
| 17 | 17 | /// ### Example |
| 18 | 18 | /// |
| 19 | /// ```rust | |
| 19 | /// ```rust,compile_fail | |
| 20 | 20 | /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] { |
| 21 | 21 | /// unsafe { &raw mut (*ptr)[..16] } |
| 22 | 22 | /// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`, |
| ... | ... | @@ -51,7 +51,7 @@ declare_lint! { |
| 51 | 51 | /// } |
| 52 | 52 | /// ``` |
| 53 | 53 | pub DANGEROUS_IMPLICIT_AUTOREFS, |
| 54 | Warn, | |
| 54 | Deny, | |
| 55 | 55 | "implicit reference to a dereference of a raw pointer", |
| 56 | 56 | report_in_external_macro |
| 57 | 57 | } |
compiler/rustc_passes/src/check_attr.rs+9-7| ... | ... | @@ -1266,13 +1266,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 1266 | 1266 | true |
| 1267 | 1267 | } |
| 1268 | 1268 | |
| 1269 | /// Checks that `doc(test(...))` attribute contains only valid attributes. Returns `true` if | |
| 1270 | /// valid. | |
| 1271 | fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) { | |
| 1269 | /// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place. | |
| 1270 | fn check_test_attr(&self, attr: &Attribute, meta: &MetaItemInner, hir_id: HirId) { | |
| 1272 | 1271 | if let Some(metas) = meta.meta_item_list() { |
| 1273 | 1272 | for i_meta in metas { |
| 1274 | 1273 | match (i_meta.name(), i_meta.meta_item()) { |
| 1275 | (Some(sym::attr | sym::no_crate_inject), _) => {} | |
| 1274 | (Some(sym::attr), _) => { | |
| 1275 | // Allowed everywhere like `#[doc]` | |
| 1276 | } | |
| 1277 | (Some(sym::no_crate_inject), _) => { | |
| 1278 | self.check_attr_crate_level(attr, meta, hir_id); | |
| 1279 | } | |
| 1276 | 1280 | (_, Some(m)) => { |
| 1277 | 1281 | self.tcx.emit_node_span_lint( |
| 1278 | 1282 | INVALID_DOC_ATTRIBUTES, |
| ... | ... | @@ -1359,9 +1363,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 1359 | 1363 | } |
| 1360 | 1364 | |
| 1361 | 1365 | Some(sym::test) => { |
| 1362 | if self.check_attr_crate_level(attr, meta, hir_id) { | |
| 1363 | self.check_test_attr(meta, hir_id); | |
| 1364 | } | |
| 1366 | self.check_test_attr(attr, meta, hir_id); | |
| 1365 | 1367 | } |
| 1366 | 1368 | |
| 1367 | 1369 | Some( |
compiler/rustc_trait_selection/src/solve/inspect/analyse.rs+1-4| ... | ... | @@ -231,10 +231,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { |
| 231 | 231 | let infcx = self.goal.infcx; |
| 232 | 232 | match goal.predicate.kind().no_bound_vars() { |
| 233 | 233 | Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { |
| 234 | let unconstrained_term = match term.kind() { | |
| 235 | ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(), | |
| 236 | ty::TermKind::Const(_) => infcx.next_const_var(span).into(), | |
| 237 | }; | |
| 234 | let unconstrained_term = infcx.next_term_var_of_kind(term, span); | |
| 238 | 235 | let goal = |
| 239 | 236 | goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term }); |
| 240 | 237 | // We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the |
compiler/rustc_trait_selection/src/solve/normalize.rs+25-66| ... | ... | @@ -1,4 +1,3 @@ |
| 1 | use std::assert_matches::assert_matches; | |
| 2 | 1 | use std::fmt::Debug; |
| 3 | 2 | |
| 4 | 3 | use rustc_data_structures::stack::ensure_sufficient_stack; |
| ... | ... | @@ -16,7 +15,6 @@ use tracing::instrument; |
| 16 | 15 | use super::{FulfillmentCtxt, NextSolverError}; |
| 17 | 16 | use crate::error_reporting::InferCtxtErrorExt; |
| 18 | 17 | use crate::error_reporting::traits::OverflowCause; |
| 19 | use crate::traits::query::evaluate_obligation::InferCtxtExt; | |
| 20 | 18 | use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; |
| 21 | 19 | |
| 22 | 20 | /// Deeply normalize all aliases in `value`. This does not handle inference and expects |
| ... | ... | @@ -97,19 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E> |
| 97 | 95 | where |
| 98 | 96 | E: FromSolverError<'tcx, NextSolverError<'tcx>>, |
| 99 | 97 | { |
| 100 | fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> { | |
| 101 | assert_matches!(alias_ty.kind(), ty::Alias(..)); | |
| 102 | ||
| 98 | fn normalize_alias_term( | |
| 99 | &mut self, | |
| 100 | alias_term: ty::Term<'tcx>, | |
| 101 | ) -> Result<ty::Term<'tcx>, Vec<E>> { | |
| 103 | 102 | let infcx = self.at.infcx; |
| 104 | 103 | let tcx = infcx.tcx; |
| 105 | 104 | let recursion_limit = tcx.recursion_limit(); |
| 106 | 105 | if !recursion_limit.value_within_limit(self.depth) { |
| 107 | let ty::Alias(_, data) = *alias_ty.kind() else { | |
| 108 | unreachable!(); | |
| 109 | }; | |
| 106 | let term = alias_term.to_alias_term().unwrap(); | |
| 110 | 107 | |
| 111 | 108 | self.at.infcx.err_ctxt().report_overflow_error( |
| 112 | OverflowCause::DeeplyNormalize(data.into()), | |
| 109 | OverflowCause::DeeplyNormalize(term), | |
| 113 | 110 | self.at.cause.span, |
| 114 | 111 | true, |
| 115 | 112 | |_| {}, |
| ... | ... | @@ -118,14 +115,14 @@ where |
| 118 | 115 | |
| 119 | 116 | self.depth += 1; |
| 120 | 117 | |
| 121 | let new_infer_ty = infcx.next_ty_var(self.at.cause.span); | |
| 118 | let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span); | |
| 122 | 119 | let obligation = Obligation::new( |
| 123 | 120 | tcx, |
| 124 | 121 | self.at.cause.clone(), |
| 125 | 122 | self.at.param_env, |
| 126 | 123 | ty::PredicateKind::AliasRelate( |
| 127 | alias_ty.into(), | |
| 128 | new_infer_ty.into(), | |
| 124 | alias_term.into(), | |
| 125 | infer_term.into(), | |
| 129 | 126 | ty::AliasRelationDirection::Equate, |
| 130 | 127 | ), |
| 131 | 128 | ); |
| ... | ... | @@ -135,50 +132,13 @@ where |
| 135 | 132 | |
| 136 | 133 | // Alias is guaranteed to be fully structurally resolved, |
| 137 | 134 | // so we can super fold here. |
| 138 | let ty = infcx.resolve_vars_if_possible(new_infer_ty); | |
| 139 | let result = ty.try_super_fold_with(self)?; | |
| 140 | self.depth -= 1; | |
| 141 | Ok(result) | |
| 142 | } | |
| 143 | ||
| 144 | fn normalize_unevaluated_const( | |
| 145 | &mut self, | |
| 146 | uv: ty::UnevaluatedConst<'tcx>, | |
| 147 | ) -> Result<ty::Const<'tcx>, Vec<E>> { | |
| 148 | let infcx = self.at.infcx; | |
| 149 | let tcx = infcx.tcx; | |
| 150 | let recursion_limit = tcx.recursion_limit(); | |
| 151 | if !recursion_limit.value_within_limit(self.depth) { | |
| 152 | self.at.infcx.err_ctxt().report_overflow_error( | |
| 153 | OverflowCause::DeeplyNormalize(uv.into()), | |
| 154 | self.at.cause.span, | |
| 155 | true, | |
| 156 | |_| {}, | |
| 157 | ); | |
| 158 | } | |
| 159 | ||
| 160 | self.depth += 1; | |
| 161 | ||
| 162 | let new_infer_ct = infcx.next_const_var(self.at.cause.span); | |
| 163 | let obligation = Obligation::new( | |
| 164 | tcx, | |
| 165 | self.at.cause.clone(), | |
| 166 | self.at.param_env, | |
| 167 | ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() }, | |
| 168 | ); | |
| 169 | ||
| 170 | let result = if infcx.predicate_may_hold(&obligation) { | |
| 171 | self.fulfill_cx.register_predicate_obligation(infcx, obligation); | |
| 172 | let errors = self.fulfill_cx.select_where_possible(infcx); | |
| 173 | if !errors.is_empty() { | |
| 174 | return Err(errors); | |
| 175 | } | |
| 176 | let ct = infcx.resolve_vars_if_possible(new_infer_ct); | |
| 177 | ct.try_fold_with(self)? | |
| 178 | } else { | |
| 179 | ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)? | |
| 135 | let term = infcx.resolve_vars_if_possible(infer_term); | |
| 136 | // super-folding the `term` will directly fold the `Ty` or `Const` so | |
| 137 | // we have to match on the term and super-fold them manually. | |
| 138 | let result = match term.kind() { | |
| 139 | ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(), | |
| 140 | ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(), | |
| 180 | 141 | }; |
| 181 | ||
| 182 | 142 | self.depth -= 1; |
| 183 | 143 | Ok(result) |
| 184 | 144 | } |
| ... | ... | @@ -238,7 +198,8 @@ where |
| 238 | 198 | if ty.has_escaping_bound_vars() { |
| 239 | 199 | let (ty, mapped_regions, mapped_types, mapped_consts) = |
| 240 | 200 | BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty); |
| 241 | let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?; | |
| 201 | let result = | |
| 202 | ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type(); | |
| 242 | 203 | Ok(PlaceholderReplacer::replace_placeholders( |
| 243 | 204 | infcx, |
| 244 | 205 | mapped_regions, |
| ... | ... | @@ -248,7 +209,7 @@ where |
| 248 | 209 | result, |
| 249 | 210 | )) |
| 250 | 211 | } else { |
| 251 | ensure_sufficient_stack(|| self.normalize_alias_ty(ty)) | |
| 212 | Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type()) | |
| 252 | 213 | } |
| 253 | 214 | } |
| 254 | 215 | |
| ... | ... | @@ -260,15 +221,13 @@ where |
| 260 | 221 | return Ok(ct); |
| 261 | 222 | } |
| 262 | 223 | |
| 263 | let uv = match ct.kind() { | |
| 264 | ty::ConstKind::Unevaluated(ct) => ct, | |
| 265 | _ => return ct.try_super_fold_with(self), | |
| 266 | }; | |
| 224 | let ty::ConstKind::Unevaluated(..) = ct.kind() else { return ct.try_super_fold_with(self) }; | |
| 267 | 225 | |
| 268 | if uv.has_escaping_bound_vars() { | |
| 269 | let (uv, mapped_regions, mapped_types, mapped_consts) = | |
| 270 | BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv); | |
| 271 | let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?; | |
| 226 | if ct.has_escaping_bound_vars() { | |
| 227 | let (ct, mapped_regions, mapped_types, mapped_consts) = | |
| 228 | BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct); | |
| 229 | let result = | |
| 230 | ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const(); | |
| 272 | 231 | Ok(PlaceholderReplacer::replace_placeholders( |
| 273 | 232 | infcx, |
| 274 | 233 | mapped_regions, |
| ... | ... | @@ -278,7 +237,7 @@ where |
| 278 | 237 | result, |
| 279 | 238 | )) |
| 280 | 239 | } else { |
| 281 | ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv)) | |
| 240 | Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const()) | |
| 282 | 241 | } |
| 283 | 242 | } |
| 284 | 243 | } |
compiler/rustc_trait_selection/src/traits/structural_normalize.rs+1-4| ... | ... | @@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> { |
| 39 | 39 | return Ok(term); |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | let new_infer = match term.kind() { | |
| 43 | ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(), | |
| 44 | ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(), | |
| 45 | }; | |
| 42 | let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span); | |
| 46 | 43 | |
| 47 | 44 | // We simply emit an `alias-eq` goal here, since that will take care of |
| 48 | 45 | // normalizing the LHS of the projection until it is a rigid projection |
library/core/src/iter/sources/generator.rs-3| ... | ... | @@ -9,8 +9,6 @@ |
| 9 | 9 | /// |
| 10 | 10 | /// ``` |
| 11 | 11 | /// #![feature(iter_macro, coroutines)] |
| 12 | /// # #[cfg(not(bootstrap))] | |
| 13 | /// # { | |
| 14 | 12 | /// |
| 15 | 13 | /// let it = std::iter::iter!{|| { |
| 16 | 14 | /// yield 1; |
| ... | ... | @@ -19,7 +17,6 @@ |
| 19 | 17 | /// } }(); |
| 20 | 18 | /// let v: Vec<_> = it.collect(); |
| 21 | 19 | /// assert_eq!(v, [1, 2, 3]); |
| 22 | /// # } | |
| 23 | 20 | /// ``` |
| 24 | 21 | #[unstable(feature = "iter_macro", issue = "none", reason = "generators are unstable")] |
| 25 | 22 | #[allow_internal_unstable(coroutines, iter_from_coroutine)] |
library/core/src/option.rs+1-1| ... | ... | @@ -137,7 +137,7 @@ |
| 137 | 137 | //! | [`ptr::NonNull<U>`] | when `U: Sized` | |
| 138 | 138 | //! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type | |
| 139 | 139 | //! |
| 140 | //! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`) | |
| 140 | //! [^extern_fn]: this remains true for `unsafe` variants, any argument/return types, and any other ABI: `[unsafe] extern "abi" fn` (_e.g._, `extern "system" fn`) | |
| 141 | 141 | //! |
| 142 | 142 | //! Under some conditions the above types `T` are also null pointer optimized when wrapped in a [`Result`][result_repr]. |
| 143 | 143 | //! |
library/core/src/slice/ascii.rs+1-1| ... | ... | @@ -52,7 +52,7 @@ impl [u8] { |
| 52 | 52 | /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, |
| 53 | 53 | /// but without allocating and copying temporaries. |
| 54 | 54 | #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] |
| 55 | #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")] | |
| 55 | #[rustc_const_stable(feature = "const_eq_ignore_ascii_case", since = "CURRENT_RUSTC_VERSION")] | |
| 56 | 56 | #[must_use] |
| 57 | 57 | #[inline] |
| 58 | 58 | pub const fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool { |
library/core/src/str/mod.rs+1-1| ... | ... | @@ -2671,7 +2671,7 @@ impl str { |
| 2671 | 2671 | /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS")); |
| 2672 | 2672 | /// ``` |
| 2673 | 2673 | #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] |
| 2674 | #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")] | |
| 2674 | #[rustc_const_stable(feature = "const_eq_ignore_ascii_case", since = "CURRENT_RUSTC_VERSION")] | |
| 2675 | 2675 | #[must_use] |
| 2676 | 2676 | #[inline] |
| 2677 | 2677 | pub const fn eq_ignore_ascii_case(&self, other: &str) -> bool { |
src/bootstrap/src/core/config/config.rs-2| ... | ... | @@ -28,8 +28,6 @@ use build_helper::git::{GitConfig, PathFreshness, check_path_modifications, outp |
| 28 | 28 | use serde::Deserialize; |
| 29 | 29 | #[cfg(feature = "tracing")] |
| 30 | 30 | use tracing::{instrument, span}; |
| 31 | #[cfg(feature = "tracing")] | |
| 32 | use tracing::{instrument, span}; | |
| 33 | 31 | |
| 34 | 32 | use crate::core::build_steps::llvm; |
| 35 | 33 | use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS; |
src/bootstrap/src/core/config/mod.rs-2| ... | ... | @@ -39,8 +39,6 @@ pub use toml::BUILDER_CONFIG_FILENAME; |
| 39 | 39 | pub use toml::change_id::ChangeId; |
| 40 | 40 | pub use toml::rust::LldMode; |
| 41 | 41 | pub use toml::target::Target; |
| 42 | #[cfg(feature = "tracing")] | |
| 43 | use tracing::{instrument, span}; | |
| 44 | 42 | |
| 45 | 43 | use crate::Display; |
| 46 | 44 | use crate::str::FromStr; |
src/doc/rustdoc/src/write-documentation/the-doc-attribute.md+23-9| ... | ... | @@ -143,15 +143,6 @@ But if you include this: |
| 143 | 143 | |
| 144 | 144 | it will not. |
| 145 | 145 | |
| 146 | ### `test(attr(...))` | |
| 147 | ||
| 148 | This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For | |
| 149 | example, if you want your doctests to fail if they have dead code, you could add this: | |
| 150 | ||
| 151 | ```rust,no_run | |
| 152 | #![doc(test(attr(deny(dead_code))))] | |
| 153 | ``` | |
| 154 | ||
| 155 | 146 | ## At the item level |
| 156 | 147 | |
| 157 | 148 | These forms of the `#[doc]` attribute are used on individual items, to control how |
| ... | ... | @@ -283,3 +274,26 @@ To get around this limitation, we just add `#[doc(alias = "lib_name_do_something |
| 283 | 274 | on the `do_something` method and then it's all good! |
| 284 | 275 | Users can now look for `lib_name_do_something` in our crate directly and find |
| 285 | 276 | `Obj::do_something`. |
| 277 | ||
| 278 | ### `test(attr(...))` | |
| 279 | ||
| 280 | This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For | |
| 281 | example, if you want your doctests to fail if they have dead code, you could add this: | |
| 282 | ||
| 283 | ```rust,no_run | |
| 284 | #![doc(test(attr(deny(dead_code))))] | |
| 285 | ||
| 286 | mod my_mod { | |
| 287 | #![doc(test(attr(allow(dead_code))))] // but allow `dead_code` for this module | |
| 288 | } | |
| 289 | ``` | |
| 290 | ||
| 291 | `test(attr(..))` attributes are appended to the parent module's, they do not replace the current | |
| 292 | list of attributes. In the previous example, both attributes would be present: | |
| 293 | ||
| 294 | ```rust,no_run | |
| 295 | // For every doctest in `my_mod` | |
| 296 | ||
| 297 | #![deny(dead_code)] // from the crate-root | |
| 298 | #![allow(dead_code)] // from `my_mod` | |
| 299 | ``` |
src/librustdoc/doctest.rs+29-20| ... | ... | @@ -5,6 +5,7 @@ mod runner; |
| 5 | 5 | mod rust; |
| 6 | 6 | |
| 7 | 7 | use std::fs::File; |
| 8 | use std::hash::{Hash, Hasher}; | |
| 8 | 9 | use std::io::{self, Write}; |
| 9 | 10 | use std::path::{Path, PathBuf}; |
| 10 | 11 | use std::process::{self, Command, Stdio}; |
| ... | ... | @@ -14,7 +15,7 @@ use std::{panic, str}; |
| 14 | 15 | |
| 15 | 16 | pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder}; |
| 16 | 17 | pub(crate) use markdown::test as test_markdown; |
| 17 | use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; | |
| 18 | use rustc_data_structures::fx::{FxHashMap, FxHasher, FxIndexMap, FxIndexSet}; | |
| 18 | 19 | use rustc_errors::emitter::HumanReadableErrorType; |
| 19 | 20 | use rustc_errors::{ColorConfig, DiagCtxtHandle}; |
| 20 | 21 | use rustc_hir as hir; |
| ... | ... | @@ -45,8 +46,6 @@ pub(crate) struct GlobalTestOptions { |
| 45 | 46 | /// Whether inserting extra indent spaces in code block, |
| 46 | 47 | /// default is `false`, only `true` for generating code link of Rust playground |
| 47 | 48 | pub(crate) insert_indent_space: bool, |
| 48 | /// Additional crate-level attributes to add to doctests. | |
| 49 | pub(crate) attrs: Vec<String>, | |
| 50 | 49 | /// Path to file containing arguments for the invocation of rustc. |
| 51 | 50 | pub(crate) args_file: PathBuf, |
| 52 | 51 | } |
| ... | ... | @@ -283,7 +282,7 @@ pub(crate) fn run_tests( |
| 283 | 282 | rustdoc_options: &Arc<RustdocOptions>, |
| 284 | 283 | unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>, |
| 285 | 284 | mut standalone_tests: Vec<test::TestDescAndFn>, |
| 286 | mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>, | |
| 285 | mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>, | |
| 287 | 286 | // We pass this argument so we can drop it manually before using `exit`. |
| 288 | 287 | mut temp_dir: Option<TempDir>, |
| 289 | 288 | ) { |
| ... | ... | @@ -298,7 +297,7 @@ pub(crate) fn run_tests( |
| 298 | 297 | let mut ran_edition_tests = 0; |
| 299 | 298 | let target_str = rustdoc_options.target.to_string(); |
| 300 | 299 | |
| 301 | for (edition, mut doctests) in mergeable_tests { | |
| 300 | for (MergeableTestKey { edition, global_crate_attrs_hash }, mut doctests) in mergeable_tests { | |
| 302 | 301 | if doctests.is_empty() { |
| 303 | 302 | continue; |
| 304 | 303 | } |
| ... | ... | @@ -308,8 +307,8 @@ pub(crate) fn run_tests( |
| 308 | 307 | |
| 309 | 308 | let rustdoc_test_options = IndividualTestOptions::new( |
| 310 | 309 | rustdoc_options, |
| 311 | &Some(format!("merged_doctest_{edition}")), | |
| 312 | PathBuf::from(format!("doctest_{edition}.rs")), | |
| 310 | &Some(format!("merged_doctest_{edition}_{global_crate_attrs_hash}")), | |
| 311 | PathBuf::from(format!("doctest_{edition}_{global_crate_attrs_hash}.rs")), | |
| 313 | 312 | ); |
| 314 | 313 | |
| 315 | 314 | for (doctest, scraped_test) in &doctests { |
| ... | ... | @@ -371,12 +370,9 @@ fn scrape_test_config( |
| 371 | 370 | attrs: &[hir::Attribute], |
| 372 | 371 | args_file: PathBuf, |
| 373 | 372 | ) -> GlobalTestOptions { |
| 374 | use rustc_ast_pretty::pprust; | |
| 375 | ||
| 376 | 373 | let mut opts = GlobalTestOptions { |
| 377 | 374 | crate_name, |
| 378 | 375 | no_crate_inject: false, |
| 379 | attrs: Vec::new(), | |
| 380 | 376 | insert_indent_space: false, |
| 381 | 377 | args_file, |
| 382 | 378 | }; |
| ... | ... | @@ -393,13 +389,7 @@ fn scrape_test_config( |
| 393 | 389 | if attr.has_name(sym::no_crate_inject) { |
| 394 | 390 | opts.no_crate_inject = true; |
| 395 | 391 | } |
| 396 | if attr.has_name(sym::attr) | |
| 397 | && let Some(l) = attr.meta_item_list() | |
| 398 | { | |
| 399 | for item in l { | |
| 400 | opts.attrs.push(pprust::meta_list_item_to_string(item)); | |
| 401 | } | |
| 402 | } | |
| 392 | // NOTE: `test(attr(..))` is handled when discovering the individual tests | |
| 403 | 393 | } |
| 404 | 394 | |
| 405 | 395 | opts |
| ... | ... | @@ -848,6 +838,7 @@ pub(crate) struct ScrapedDocTest { |
| 848 | 838 | text: String, |
| 849 | 839 | name: String, |
| 850 | 840 | span: Span, |
| 841 | global_crate_attrs: Vec<String>, | |
| 851 | 842 | } |
| 852 | 843 | |
| 853 | 844 | impl ScrapedDocTest { |
| ... | ... | @@ -858,6 +849,7 @@ impl ScrapedDocTest { |
| 858 | 849 | langstr: LangString, |
| 859 | 850 | text: String, |
| 860 | 851 | span: Span, |
| 852 | global_crate_attrs: Vec<String>, | |
| 861 | 853 | ) -> Self { |
| 862 | 854 | let mut item_path = logical_path.join("::"); |
| 863 | 855 | item_path.retain(|c| c != ' '); |
| ... | ... | @@ -867,7 +859,7 @@ impl ScrapedDocTest { |
| 867 | 859 | let name = |
| 868 | 860 | format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly()); |
| 869 | 861 | |
| 870 | Self { filename, line, langstr, text, name, span } | |
| 862 | Self { filename, line, langstr, text, name, span, global_crate_attrs } | |
| 871 | 863 | } |
| 872 | 864 | fn edition(&self, opts: &RustdocOptions) -> Edition { |
| 873 | 865 | self.langstr.edition.unwrap_or(opts.edition) |
| ... | ... | @@ -896,9 +888,15 @@ pub(crate) trait DocTestVisitor { |
| 896 | 888 | fn visit_header(&mut self, _name: &str, _level: u32) {} |
| 897 | 889 | } |
| 898 | 890 | |
| 891 | #[derive(Clone, Debug, Hash, Eq, PartialEq)] | |
| 892 | pub(crate) struct MergeableTestKey { | |
| 893 | edition: Edition, | |
| 894 | global_crate_attrs_hash: u64, | |
| 895 | } | |
| 896 | ||
| 899 | 897 | struct CreateRunnableDocTests { |
| 900 | 898 | standalone_tests: Vec<test::TestDescAndFn>, |
| 901 | mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>, | |
| 899 | mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>, | |
| 902 | 900 | |
| 903 | 901 | rustdoc_options: Arc<RustdocOptions>, |
| 904 | 902 | opts: GlobalTestOptions, |
| ... | ... | @@ -949,6 +947,7 @@ impl CreateRunnableDocTests { |
| 949 | 947 | let edition = scraped_test.edition(&self.rustdoc_options); |
| 950 | 948 | let doctest = BuildDocTestBuilder::new(&scraped_test.text) |
| 951 | 949 | .crate_name(&self.opts.crate_name) |
| 950 | .global_crate_attrs(scraped_test.global_crate_attrs.clone()) | |
| 952 | 951 | .edition(edition) |
| 953 | 952 | .can_merge_doctests(self.can_merge_doctests) |
| 954 | 953 | .test_id(test_id) |
| ... | ... | @@ -965,7 +964,17 @@ impl CreateRunnableDocTests { |
| 965 | 964 | let test_desc = self.generate_test_desc_and_fn(doctest, scraped_test); |
| 966 | 965 | self.standalone_tests.push(test_desc); |
| 967 | 966 | } else { |
| 968 | self.mergeable_tests.entry(edition).or_default().push((doctest, scraped_test)); | |
| 967 | self.mergeable_tests | |
| 968 | .entry(MergeableTestKey { | |
| 969 | edition, | |
| 970 | global_crate_attrs_hash: { | |
| 971 | let mut hasher = FxHasher::default(); | |
| 972 | scraped_test.global_crate_attrs.hash(&mut hasher); | |
| 973 | hasher.finish() | |
| 974 | }, | |
| 975 | }) | |
| 976 | .or_default() | |
| 977 | .push((doctest, scraped_test)); | |
| 969 | 978 | } |
| 970 | 979 | } |
| 971 | 980 |
src/librustdoc/doctest/extracted.rs+4-1| ... | ... | @@ -35,13 +35,16 @@ impl ExtractedDocTests { |
| 35 | 35 | ) { |
| 36 | 36 | let edition = scraped_test.edition(options); |
| 37 | 37 | |
| 38 | let ScrapedDocTest { filename, line, langstr, text, name, .. } = scraped_test; | |
| 38 | let ScrapedDocTest { filename, line, langstr, text, name, global_crate_attrs, .. } = | |
| 39 | scraped_test; | |
| 39 | 40 | |
| 40 | 41 | let doctest = BuildDocTestBuilder::new(&text) |
| 41 | 42 | .crate_name(&opts.crate_name) |
| 43 | .global_crate_attrs(global_crate_attrs) | |
| 42 | 44 | .edition(edition) |
| 43 | 45 | .lang_str(&langstr) |
| 44 | 46 | .build(None); |
| 47 | ||
| 45 | 48 | let (full_test_code, size) = doctest.generate_unique_doctest( |
| 46 | 49 | &text, |
| 47 | 50 | langstr.test_harness, |
src/librustdoc/doctest/make.rs+18-3| ... | ... | @@ -45,6 +45,7 @@ pub(crate) struct BuildDocTestBuilder<'a> { |
| 45 | 45 | test_id: Option<String>, |
| 46 | 46 | lang_str: Option<&'a LangString>, |
| 47 | 47 | span: Span, |
| 48 | global_crate_attrs: Vec<String>, | |
| 48 | 49 | } |
| 49 | 50 | |
| 50 | 51 | impl<'a> BuildDocTestBuilder<'a> { |
| ... | ... | @@ -57,6 +58,7 @@ impl<'a> BuildDocTestBuilder<'a> { |
| 57 | 58 | test_id: None, |
| 58 | 59 | lang_str: None, |
| 59 | 60 | span: DUMMY_SP, |
| 61 | global_crate_attrs: Vec::new(), | |
| 60 | 62 | } |
| 61 | 63 | } |
| 62 | 64 | |
| ... | ... | @@ -96,6 +98,12 @@ impl<'a> BuildDocTestBuilder<'a> { |
| 96 | 98 | self |
| 97 | 99 | } |
| 98 | 100 | |
| 101 | #[inline] | |
| 102 | pub(crate) fn global_crate_attrs(mut self, global_crate_attrs: Vec<String>) -> Self { | |
| 103 | self.global_crate_attrs = global_crate_attrs; | |
| 104 | self | |
| 105 | } | |
| 106 | ||
| 99 | 107 | pub(crate) fn build(self, dcx: Option<DiagCtxtHandle<'_>>) -> DocTestBuilder { |
| 100 | 108 | let BuildDocTestBuilder { |
| 101 | 109 | source, |
| ... | ... | @@ -106,6 +114,7 @@ impl<'a> BuildDocTestBuilder<'a> { |
| 106 | 114 | test_id, |
| 107 | 115 | lang_str, |
| 108 | 116 | span, |
| 117 | global_crate_attrs, | |
| 109 | 118 | } = self; |
| 110 | 119 | let can_merge_doctests = can_merge_doctests |
| 111 | 120 | && lang_str.is_some_and(|lang_str| { |
| ... | ... | @@ -133,6 +142,7 @@ impl<'a> BuildDocTestBuilder<'a> { |
| 133 | 142 | // If the AST returned an error, we don't want this doctest to be merged with the |
| 134 | 143 | // others. |
| 135 | 144 | return DocTestBuilder::invalid( |
| 145 | Vec::new(), | |
| 136 | 146 | String::new(), |
| 137 | 147 | String::new(), |
| 138 | 148 | String::new(), |
| ... | ... | @@ -155,6 +165,7 @@ impl<'a> BuildDocTestBuilder<'a> { |
| 155 | 165 | DocTestBuilder { |
| 156 | 166 | supports_color, |
| 157 | 167 | has_main_fn, |
| 168 | global_crate_attrs, | |
| 158 | 169 | crate_attrs, |
| 159 | 170 | maybe_crate_attrs, |
| 160 | 171 | crates, |
| ... | ... | @@ -173,6 +184,7 @@ pub(crate) struct DocTestBuilder { |
| 173 | 184 | pub(crate) supports_color: bool, |
| 174 | 185 | pub(crate) already_has_extern_crate: bool, |
| 175 | 186 | pub(crate) has_main_fn: bool, |
| 187 | pub(crate) global_crate_attrs: Vec<String>, | |
| 176 | 188 | pub(crate) crate_attrs: String, |
| 177 | 189 | /// If this is a merged doctest, it will be put into `everything_else`, otherwise it will |
| 178 | 190 | /// put into `crate_attrs`. |
| ... | ... | @@ -186,6 +198,7 @@ pub(crate) struct DocTestBuilder { |
| 186 | 198 | |
| 187 | 199 | impl DocTestBuilder { |
| 188 | 200 | fn invalid( |
| 201 | global_crate_attrs: Vec<String>, | |
| 189 | 202 | crate_attrs: String, |
| 190 | 203 | maybe_crate_attrs: String, |
| 191 | 204 | crates: String, |
| ... | ... | @@ -195,6 +208,7 @@ impl DocTestBuilder { |
| 195 | 208 | Self { |
| 196 | 209 | supports_color: false, |
| 197 | 210 | has_main_fn: false, |
| 211 | global_crate_attrs, | |
| 198 | 212 | crate_attrs, |
| 199 | 213 | maybe_crate_attrs, |
| 200 | 214 | crates, |
| ... | ... | @@ -224,7 +238,8 @@ impl DocTestBuilder { |
| 224 | 238 | let mut line_offset = 0; |
| 225 | 239 | let mut prog = String::new(); |
| 226 | 240 | let everything_else = self.everything_else.trim(); |
| 227 | if opts.attrs.is_empty() { | |
| 241 | ||
| 242 | if self.global_crate_attrs.is_empty() { | |
| 228 | 243 | // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some |
| 229 | 244 | // lints that are commonly triggered in doctests. The crate-level test attributes are |
| 230 | 245 | // commonly used to make tests fail in case they trigger warnings, so having this there in |
| ... | ... | @@ -233,8 +248,8 @@ impl DocTestBuilder { |
| 233 | 248 | line_offset += 1; |
| 234 | 249 | } |
| 235 | 250 | |
| 236 | // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. | |
| 237 | for attr in &opts.attrs { | |
| 251 | // Next, any attributes that came from #![doc(test(attr(...)))]. | |
| 252 | for attr in &self.global_crate_attrs { | |
| 238 | 253 | prog.push_str(&format!("#![{attr}]\n")); |
| 239 | 254 | line_offset += 1; |
| 240 | 255 | } |
src/librustdoc/doctest/markdown.rs+1-1| ... | ... | @@ -31,6 +31,7 @@ impl DocTestVisitor for MdCollector { |
| 31 | 31 | config, |
| 32 | 32 | test, |
| 33 | 33 | DUMMY_SP, |
| 34 | Vec::new(), | |
| 34 | 35 | )); |
| 35 | 36 | } |
| 36 | 37 | |
| ... | ... | @@ -96,7 +97,6 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { |
| 96 | 97 | crate_name, |
| 97 | 98 | no_crate_inject: true, |
| 98 | 99 | insert_indent_space: false, |
| 99 | attrs: vec![], | |
| 100 | 100 | args_file, |
| 101 | 101 | }; |
| 102 | 102 |
src/librustdoc/doctest/runner.rs+8-3| ... | ... | @@ -12,6 +12,7 @@ use crate::html::markdown::{Ignore, LangString}; |
| 12 | 12 | /// Convenient type to merge compatible doctests into one. |
| 13 | 13 | pub(crate) struct DocTestRunner { |
| 14 | 14 | crate_attrs: FxIndexSet<String>, |
| 15 | global_crate_attrs: FxIndexSet<String>, | |
| 15 | 16 | ids: String, |
| 16 | 17 | output: String, |
| 17 | 18 | output_merged_tests: String, |
| ... | ... | @@ -23,6 +24,7 @@ impl DocTestRunner { |
| 23 | 24 | pub(crate) fn new() -> Self { |
| 24 | 25 | Self { |
| 25 | 26 | crate_attrs: FxIndexSet::default(), |
| 27 | global_crate_attrs: FxIndexSet::default(), | |
| 26 | 28 | ids: String::new(), |
| 27 | 29 | output: String::new(), |
| 28 | 30 | output_merged_tests: String::new(), |
| ... | ... | @@ -46,6 +48,9 @@ impl DocTestRunner { |
| 46 | 48 | for line in doctest.crate_attrs.split('\n') { |
| 47 | 49 | self.crate_attrs.insert(line.to_string()); |
| 48 | 50 | } |
| 51 | for line in &doctest.global_crate_attrs { | |
| 52 | self.global_crate_attrs.insert(line.to_string()); | |
| 53 | } | |
| 49 | 54 | } |
| 50 | 55 | self.ids.push_str(&format!( |
| 51 | 56 | "tests.push({}::TEST);\n", |
| ... | ... | @@ -85,7 +90,7 @@ impl DocTestRunner { |
| 85 | 90 | code_prefix.push('\n'); |
| 86 | 91 | } |
| 87 | 92 | |
| 88 | if opts.attrs.is_empty() { | |
| 93 | if self.global_crate_attrs.is_empty() { | |
| 89 | 94 | // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some |
| 90 | 95 | // lints that are commonly triggered in doctests. The crate-level test attributes are |
| 91 | 96 | // commonly used to make tests fail in case they trigger warnings, so having this there in |
| ... | ... | @@ -93,8 +98,8 @@ impl DocTestRunner { |
| 93 | 98 | code_prefix.push_str("#![allow(unused)]\n"); |
| 94 | 99 | } |
| 95 | 100 | |
| 96 | // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. | |
| 97 | for attr in &opts.attrs { | |
| 101 | // Next, any attributes that came from #![doc(test(attr(...)))]. | |
| 102 | for attr in &self.global_crate_attrs { | |
| 98 | 103 | code_prefix.push_str(&format!("#![{attr}]\n")); |
| 99 | 104 | } |
| 100 | 105 |
src/librustdoc/doctest/rust.rs+28-1| ... | ... | @@ -4,6 +4,7 @@ use std::cell::Cell; |
| 4 | 4 | use std::env; |
| 5 | 5 | use std::sync::Arc; |
| 6 | 6 | |
| 7 | use rustc_ast_pretty::pprust; | |
| 7 | 8 | use rustc_data_structures::fx::FxHashSet; |
| 8 | 9 | use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; |
| 9 | 10 | use rustc_hir::{self as hir, CRATE_HIR_ID, intravisit}; |
| ... | ... | @@ -11,7 +12,7 @@ use rustc_middle::hir::nested_filter; |
| 11 | 12 | use rustc_middle::ty::TyCtxt; |
| 12 | 13 | use rustc_resolve::rustdoc::span_of_fragments; |
| 13 | 14 | use rustc_span::source_map::SourceMap; |
| 14 | use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span}; | |
| 15 | use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span, sym}; | |
| 15 | 16 | |
| 16 | 17 | use super::{DocTestVisitor, ScrapedDocTest}; |
| 17 | 18 | use crate::clean::{Attributes, extract_cfg_from_attrs}; |
| ... | ... | @@ -22,6 +23,7 @@ struct RustCollector { |
| 22 | 23 | tests: Vec<ScrapedDocTest>, |
| 23 | 24 | cur_path: Vec<String>, |
| 24 | 25 | position: Span, |
| 26 | global_crate_attrs: Vec<String>, | |
| 25 | 27 | } |
| 26 | 28 | |
| 27 | 29 | impl RustCollector { |
| ... | ... | @@ -75,6 +77,7 @@ impl DocTestVisitor for RustCollector { |
| 75 | 77 | config, |
| 76 | 78 | test, |
| 77 | 79 | span, |
| 80 | self.global_crate_attrs.clone(), | |
| 78 | 81 | )); |
| 79 | 82 | } |
| 80 | 83 | |
| ... | ... | @@ -94,6 +97,7 @@ impl<'tcx> HirCollector<'tcx> { |
| 94 | 97 | cur_path: vec![], |
| 95 | 98 | position: DUMMY_SP, |
| 96 | 99 | tests: vec![], |
| 100 | global_crate_attrs: Vec::new(), | |
| 97 | 101 | }; |
| 98 | 102 | Self { codes, tcx, collector } |
| 99 | 103 | } |
| ... | ... | @@ -123,6 +127,26 @@ impl HirCollector<'_> { |
| 123 | 127 | return; |
| 124 | 128 | } |
| 125 | 129 | |
| 130 | // Try collecting `#[doc(test(attr(...)))]` | |
| 131 | let old_global_crate_attrs_len = self.collector.global_crate_attrs.len(); | |
| 132 | for doc_test_attrs in ast_attrs | |
| 133 | .iter() | |
| 134 | .filter(|a| a.has_name(sym::doc)) | |
| 135 | .flat_map(|a| a.meta_item_list().unwrap_or_default()) | |
| 136 | .filter(|a| a.has_name(sym::test)) | |
| 137 | { | |
| 138 | let Some(doc_test_attrs) = doc_test_attrs.meta_item_list() else { continue }; | |
| 139 | for attr in doc_test_attrs | |
| 140 | .iter() | |
| 141 | .filter(|a| a.has_name(sym::attr)) | |
| 142 | .flat_map(|a| a.meta_item_list().unwrap_or_default()) | |
| 143 | .map(|i| pprust::meta_list_item_to_string(i)) | |
| 144 | { | |
| 145 | // Add the additional attributes to the global_crate_attrs vector | |
| 146 | self.collector.global_crate_attrs.push(attr); | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 126 | 150 | let mut has_name = false; |
| 127 | 151 | if let Some(name) = name { |
| 128 | 152 | self.collector.cur_path.push(name); |
| ... | ... | @@ -157,6 +181,9 @@ impl HirCollector<'_> { |
| 157 | 181 | |
| 158 | 182 | nested(self); |
| 159 | 183 | |
| 184 | // Restore global_crate_attrs to it's previous size/content | |
| 185 | self.collector.global_crate_attrs.truncate(old_global_crate_attrs_len); | |
| 186 | ||
| 160 | 187 | if has_name { |
| 161 | 188 | self.collector.cur_path.pop(); |
| 162 | 189 | } |
src/librustdoc/doctest/tests.rs+39-29| ... | ... | @@ -7,9 +7,11 @@ fn make_test( |
| 7 | 7 | crate_name: Option<&str>, |
| 8 | 8 | dont_insert_main: bool, |
| 9 | 9 | opts: &GlobalTestOptions, |
| 10 | global_crate_attrs: Vec<&str>, | |
| 10 | 11 | test_id: Option<&str>, |
| 11 | 12 | ) -> (String, usize) { |
| 12 | let mut builder = BuildDocTestBuilder::new(test_code); | |
| 13 | let mut builder = BuildDocTestBuilder::new(test_code) | |
| 14 | .global_crate_attrs(global_crate_attrs.into_iter().map(|a| a.to_string()).collect()); | |
| 13 | 15 | if let Some(crate_name) = crate_name { |
| 14 | 16 | builder = builder.crate_name(crate_name); |
| 15 | 17 | } |
| ... | ... | @@ -28,7 +30,6 @@ fn default_global_opts(crate_name: impl Into<String>) -> GlobalTestOptions { |
| 28 | 30 | crate_name: crate_name.into(), |
| 29 | 31 | no_crate_inject: false, |
| 30 | 32 | insert_indent_space: false, |
| 31 | attrs: vec![], | |
| 32 | 33 | args_file: PathBuf::new(), |
| 33 | 34 | } |
| 34 | 35 | } |
| ... | ... | @@ -43,7 +44,7 @@ fn main() { |
| 43 | 44 | assert_eq!(2+2, 4); |
| 44 | 45 | }" |
| 45 | 46 | .to_string(); |
| 46 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 47 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 47 | 48 | assert_eq!((output, len), (expected, 2)); |
| 48 | 49 | } |
| 49 | 50 | |
| ... | ... | @@ -58,7 +59,7 @@ fn main() { |
| 58 | 59 | assert_eq!(2+2, 4); |
| 59 | 60 | }" |
| 60 | 61 | .to_string(); |
| 61 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 62 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 62 | 63 | assert_eq!((output, len), (expected, 2)); |
| 63 | 64 | } |
| 64 | 65 | |
| ... | ... | @@ -77,7 +78,7 @@ use asdf::qwop; |
| 77 | 78 | assert_eq!(2+2, 4); |
| 78 | 79 | }" |
| 79 | 80 | .to_string(); |
| 80 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 81 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 81 | 82 | assert_eq!((output, len), (expected, 3)); |
| 82 | 83 | } |
| 83 | 84 | |
| ... | ... | @@ -94,7 +95,7 @@ use asdf::qwop; |
| 94 | 95 | assert_eq!(2+2, 4); |
| 95 | 96 | }" |
| 96 | 97 | .to_string(); |
| 97 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 98 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 98 | 99 | assert_eq!((output, len), (expected, 2)); |
| 99 | 100 | } |
| 100 | 101 | |
| ... | ... | @@ -112,7 +113,7 @@ use std::*; |
| 112 | 113 | assert_eq!(2+2, 4); |
| 113 | 114 | }" |
| 114 | 115 | .to_string(); |
| 115 | let (output, len) = make_test(input, Some("std"), false, &opts, None); | |
| 116 | let (output, len) = make_test(input, Some("std"), false, &opts, Vec::new(), None); | |
| 116 | 117 | assert_eq!((output, len), (expected, 2)); |
| 117 | 118 | } |
| 118 | 119 | |
| ... | ... | @@ -131,7 +132,7 @@ use asdf::qwop; |
| 131 | 132 | assert_eq!(2+2, 4); |
| 132 | 133 | }" |
| 133 | 134 | .to_string(); |
| 134 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 135 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 135 | 136 | assert_eq!((output, len), (expected, 2)); |
| 136 | 137 | } |
| 137 | 138 | |
| ... | ... | @@ -148,7 +149,7 @@ use asdf::qwop; |
| 148 | 149 | assert_eq!(2+2, 4); |
| 149 | 150 | }" |
| 150 | 151 | .to_string(); |
| 151 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 152 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 152 | 153 | assert_eq!((output, len), (expected, 2)); |
| 153 | 154 | } |
| 154 | 155 | |
| ... | ... | @@ -156,8 +157,7 @@ assert_eq!(2+2, 4); |
| 156 | 157 | fn make_test_opts_attrs() { |
| 157 | 158 | // If you supplied some doctest attributes with `#![doc(test(attr(...)))]`, it will use |
| 158 | 159 | // those instead of the stock `#![allow(unused)]`. |
| 159 | let mut opts = default_global_opts("asdf"); | |
| 160 | opts.attrs.push("feature(sick_rad)".to_string()); | |
| 160 | let opts = default_global_opts("asdf"); | |
| 161 | 161 | let input = "use asdf::qwop; |
| 162 | 162 | assert_eq!(2+2, 4);"; |
| 163 | 163 | let expected = "#![feature(sick_rad)] |
| ... | ... | @@ -168,11 +168,10 @@ use asdf::qwop; |
| 168 | 168 | assert_eq!(2+2, 4); |
| 169 | 169 | }" |
| 170 | 170 | .to_string(); |
| 171 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 171 | let (output, len) = | |
| 172 | make_test(input, Some("asdf"), false, &opts, vec!["feature(sick_rad)"], None); | |
| 172 | 173 | assert_eq!((output, len), (expected, 3)); |
| 173 | 174 | |
| 174 | // Adding more will also bump the returned line offset. | |
| 175 | opts.attrs.push("feature(hella_dope)".to_string()); | |
| 176 | 175 | let expected = "#![feature(sick_rad)] |
| 177 | 176 | #![feature(hella_dope)] |
| 178 | 177 | #[allow(unused_extern_crates)] |
| ... | ... | @@ -182,7 +181,18 @@ use asdf::qwop; |
| 182 | 181 | assert_eq!(2+2, 4); |
| 183 | 182 | }" |
| 184 | 183 | .to_string(); |
| 185 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 184 | let (output, len) = make_test( | |
| 185 | input, | |
| 186 | Some("asdf"), | |
| 187 | false, | |
| 188 | &opts, | |
| 189 | vec![ | |
| 190 | "feature(sick_rad)", | |
| 191 | // Adding more will also bump the returned line offset. | |
| 192 | "feature(hella_dope)", | |
| 193 | ], | |
| 194 | None, | |
| 195 | ); | |
| 186 | 196 | assert_eq!((output, len), (expected, 4)); |
| 187 | 197 | } |
| 188 | 198 | |
| ... | ... | @@ -200,7 +210,7 @@ fn main() { |
| 200 | 210 | assert_eq!(2+2, 4); |
| 201 | 211 | }" |
| 202 | 212 | .to_string(); |
| 203 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 213 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 204 | 214 | assert_eq!((output, len), (expected, 2)); |
| 205 | 215 | } |
| 206 | 216 | |
| ... | ... | @@ -216,7 +226,7 @@ fn main() { |
| 216 | 226 | assert_eq!(2+2, 4); |
| 217 | 227 | }" |
| 218 | 228 | .to_string(); |
| 219 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 229 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 220 | 230 | assert_eq!((output, len), (expected, 1)); |
| 221 | 231 | } |
| 222 | 232 | |
| ... | ... | @@ -232,7 +242,7 @@ fn main() { |
| 232 | 242 | assert_eq!(2+2, 4); |
| 233 | 243 | }" |
| 234 | 244 | .to_string(); |
| 235 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 245 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 236 | 246 | assert_eq!((output, len), (expected, 2)); |
| 237 | 247 | } |
| 238 | 248 | |
| ... | ... | @@ -246,7 +256,7 @@ assert_eq!(2+2, 4);"; |
| 246 | 256 | //Ceci n'est pas une `fn main` |
| 247 | 257 | assert_eq!(2+2, 4);" |
| 248 | 258 | .to_string(); |
| 249 | let (output, len) = make_test(input, None, true, &opts, None); | |
| 259 | let (output, len) = make_test(input, None, true, &opts, Vec::new(), None); | |
| 250 | 260 | assert_eq!((output, len), (expected, 1)); |
| 251 | 261 | } |
| 252 | 262 | |
| ... | ... | @@ -264,7 +274,7 @@ assert_eq!(2+2, 4); |
| 264 | 274 | }" |
| 265 | 275 | .to_string(); |
| 266 | 276 | |
| 267 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 277 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 268 | 278 | assert_eq!((output, len), (expected, 2)); |
| 269 | 279 | } |
| 270 | 280 | |
| ... | ... | @@ -284,7 +294,7 @@ assert_eq!(asdf::foo, 4); |
| 284 | 294 | }" |
| 285 | 295 | .to_string(); |
| 286 | 296 | |
| 287 | let (output, len) = make_test(input, Some("asdf"), false, &opts, None); | |
| 297 | let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None); | |
| 288 | 298 | assert_eq!((output, len), (expected, 3)); |
| 289 | 299 | } |
| 290 | 300 | |
| ... | ... | @@ -302,7 +312,7 @@ test_wrapper! { |
| 302 | 312 | }" |
| 303 | 313 | .to_string(); |
| 304 | 314 | |
| 305 | let (output, len) = make_test(input, Some("my_crate"), false, &opts, None); | |
| 315 | let (output, len) = make_test(input, Some("my_crate"), false, &opts, Vec::new(), None); | |
| 306 | 316 | assert_eq!((output, len), (expected, 1)); |
| 307 | 317 | } |
| 308 | 318 | |
| ... | ... | @@ -322,7 +332,7 @@ io::stdin().read_line(&mut input)?; |
| 322 | 332 | Ok::<(), io:Error>(()) |
| 323 | 333 | } _inner().unwrap() }" |
| 324 | 334 | .to_string(); |
| 325 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 335 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 326 | 336 | assert_eq!((output, len), (expected, 2)); |
| 327 | 337 | } |
| 328 | 338 | |
| ... | ... | @@ -336,7 +346,7 @@ fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() { |
| 336 | 346 | assert_eq!(2+2, 4); |
| 337 | 347 | } _doctest_main__some_unique_name() }" |
| 338 | 348 | .to_string(); |
| 339 | let (output, len) = make_test(input, None, false, &opts, Some("_some_unique_name")); | |
| 349 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), Some("_some_unique_name")); | |
| 340 | 350 | assert_eq!((output, len), (expected, 2)); |
| 341 | 351 | } |
| 342 | 352 | |
| ... | ... | @@ -355,7 +365,7 @@ fn main() { |
| 355 | 365 | eprintln!(\"hello anan\"); |
| 356 | 366 | }" |
| 357 | 367 | .to_string(); |
| 358 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 368 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 359 | 369 | assert_eq!((output, len), (expected, 2)); |
| 360 | 370 | } |
| 361 | 371 | |
| ... | ... | @@ -375,7 +385,7 @@ fn main() { |
| 375 | 385 | eprintln!(\"hello anan\"); |
| 376 | 386 | }" |
| 377 | 387 | .to_string(); |
| 378 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 388 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 379 | 389 | assert_eq!((output, len), (expected, 1)); |
| 380 | 390 | } |
| 381 | 391 | |
| ... | ... | @@ -400,7 +410,7 @@ fn main() { |
| 400 | 410 | |
| 401 | 411 | }" |
| 402 | 412 | .to_string(); |
| 403 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 413 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 404 | 414 | assert_eq!((output, len), (expected, 2)); |
| 405 | 415 | |
| 406 | 416 | // And same, if there is a `main` function provided by the user, we ensure that it's |
| ... | ... | @@ -420,7 +430,7 @@ fn main() {}"; |
| 420 | 430 | |
| 421 | 431 | fn main() {}" |
| 422 | 432 | .to_string(); |
| 423 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 433 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 424 | 434 | assert_eq!((output, len), (expected, 1)); |
| 425 | 435 | } |
| 426 | 436 | |
| ... | ... | @@ -448,6 +458,6 @@ pub mod outer_module { |
| 448 | 458 | } |
| 449 | 459 | }" |
| 450 | 460 | .to_string(); |
| 451 | let (output, len) = make_test(input, None, false, &opts, None); | |
| 461 | let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); | |
| 452 | 462 | assert_eq!((output, len), (expected, 2)); |
| 453 | 463 | } |
src/librustdoc/html/markdown.rs-1| ... | ... | @@ -300,7 +300,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { |
| 300 | 300 | crate_name: krate.map(String::from).unwrap_or_default(), |
| 301 | 301 | no_crate_inject: false, |
| 302 | 302 | insert_indent_space: true, |
| 303 | attrs: vec![], | |
| 304 | 303 | args_file: PathBuf::new(), |
| 305 | 304 | }; |
| 306 | 305 | let mut builder = doctest::BuildDocTestBuilder::new(&test).edition(edition); |
src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs-14| ... | ... | @@ -4451,20 +4451,6 @@ The tracking issue for this feature is: [#133214] |
| 4451 | 4451 | |
| 4452 | 4452 | [#133214]: https://github.com/rust-lang/rust/issues/133214 |
| 4453 | 4453 | |
| 4454 | ------------------------ | |
| 4455 | "##, | |
| 4456 | default_severity: Severity::Allow, | |
| 4457 | warn_since: None, | |
| 4458 | deny_since: None, | |
| 4459 | }, | |
| 4460 | Lint { | |
| 4461 | label: "const_eq_ignore_ascii_case", | |
| 4462 | description: r##"# `const_eq_ignore_ascii_case` | |
| 4463 | ||
| 4464 | The tracking issue for this feature is: [#131719] | |
| 4465 | ||
| 4466 | [#131719]: https://github.com/rust-lang/rust/issues/131719 | |
| 4467 | ||
| 4468 | 4454 | ------------------------ |
| 4469 | 4455 | "##, |
| 4470 | 4456 | default_severity: Severity::Allow, |
tests/crashes/140571.rs deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | //@ known-bug: #140571 | |
| 2 | pub trait IsVoid { | |
| 3 | const IS_VOID: bool; | |
| 4 | } | |
| 5 | impl<T> IsVoid for T { | |
| 6 | default const IS_VOID: bool = false; | |
| 7 | } | |
| 8 | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {} | |
| 9 | ||
| 10 | pub trait NotVoid {} | |
| 11 | impl<T> NotVoid for T where T: IsVoid<IS_VOID = false> + ?Sized {} | |
| 12 | ||
| 13 | pub trait Maybe<T> {} | |
| 14 | impl<T> Maybe<T> for T {} |
tests/run-make/doctests-keep-binaries-2024/rmake.rs+16-1| ... | ... | @@ -16,7 +16,22 @@ fn setup_test_env<F: FnOnce(&Path, &Path)>(callback: F) { |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | 18 | fn check_generated_binaries() { |
| 19 | run("doctests/merged_doctest_2024/rust_out"); | |
| 19 | let mut found_merged_doctest = false; | |
| 20 | rfs::read_dir_entries("doctests/", |path| { | |
| 21 | if path | |
| 22 | .file_name() | |
| 23 | .and_then(|name| name.to_str()) | |
| 24 | .is_some_and(|name| name.starts_with("merged_doctest_2024")) | |
| 25 | { | |
| 26 | found_merged_doctest = true; | |
| 27 | let rust_out = path.join("rust_out"); | |
| 28 | let rust_out = rust_out.to_string_lossy(); | |
| 29 | run(&*rust_out); | |
| 30 | } | |
| 31 | }); | |
| 32 | if !found_merged_doctest { | |
| 33 | panic!("no directory starting with `merged_doctest_2024` found under `doctests/`"); | |
| 34 | } | |
| 20 | 35 | } |
| 21 | 36 | |
| 22 | 37 | fn main() { |
tests/rustdoc-ui/doctest/dead-code-items.rs created+116| ... | ... | @@ -0,0 +1,116 @@ |
| 1 | // Same test as dead-code-module but with 2 doc(test(attr())) at different levels. | |
| 2 | ||
| 3 | //@ edition: 2024 | |
| 4 | //@ compile-flags:--test --test-args=--test-threads=1 | |
| 5 | //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" | |
| 6 | //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" | |
| 7 | //@ failure-status: 101 | |
| 8 | ||
| 9 | #![doc(test(attr(deny(warnings))))] | |
| 10 | ||
| 11 | #[doc(test(attr(allow(dead_code))))] | |
| 12 | /// Example | |
| 13 | /// | |
| 14 | /// ```rust,no_run | |
| 15 | /// trait OnlyWarning { fn no_deny_warnings(); } | |
| 16 | /// ``` | |
| 17 | static S: u32 = 5; | |
| 18 | ||
| 19 | #[doc(test(attr(allow(dead_code))))] | |
| 20 | /// Example | |
| 21 | /// | |
| 22 | /// ```rust,no_run | |
| 23 | /// let unused_error = 5; | |
| 24 | /// | |
| 25 | /// fn dead_code_but_no_error() {} | |
| 26 | /// ``` | |
| 27 | const C: u32 = 5; | |
| 28 | ||
| 29 | #[doc(test(attr(allow(dead_code))))] | |
| 30 | /// Example | |
| 31 | /// | |
| 32 | /// ```rust,no_run | |
| 33 | /// trait OnlyWarningAtA { fn no_deny_warnings(); } | |
| 34 | /// ``` | |
| 35 | struct A { | |
| 36 | #[doc(test(attr(deny(dead_code))))] | |
| 37 | /// Example | |
| 38 | /// | |
| 39 | /// ```rust,no_run | |
| 40 | /// trait DeadCodeInField {} | |
| 41 | /// ``` | |
| 42 | field: u32 | |
| 43 | } | |
| 44 | ||
| 45 | #[doc(test(attr(allow(dead_code))))] | |
| 46 | /// Example | |
| 47 | /// | |
| 48 | /// ```rust,no_run | |
| 49 | /// trait OnlyWarningAtU { fn no_deny_warnings(); } | |
| 50 | /// ``` | |
| 51 | union U { | |
| 52 | #[doc(test(attr(deny(dead_code))))] | |
| 53 | /// Example | |
| 54 | /// | |
| 55 | /// ```rust,no_run | |
| 56 | /// trait DeadCodeInUnionField {} | |
| 57 | /// ``` | |
| 58 | field: u32, | |
| 59 | /// Example | |
| 60 | /// | |
| 61 | /// ```rust,no_run | |
| 62 | /// trait NotDeadCodeInUnionField {} | |
| 63 | /// ``` | |
| 64 | field2: u64, | |
| 65 | } | |
| 66 | ||
| 67 | #[doc(test(attr(deny(dead_code))))] | |
| 68 | /// Example | |
| 69 | /// | |
| 70 | /// ```rust,no_run | |
| 71 | /// let not_dead_code_but_unused = 5; | |
| 72 | /// ``` | |
| 73 | enum Enum { | |
| 74 | #[doc(test(attr(allow(dead_code))))] | |
| 75 | /// Example | |
| 76 | /// | |
| 77 | /// ```rust,no_run | |
| 78 | /// trait NotDeadCodeInVariant {} | |
| 79 | /// | |
| 80 | /// fn main() { let unused_in_variant = 5; } | |
| 81 | /// ``` | |
| 82 | Variant1, | |
| 83 | } | |
| 84 | ||
| 85 | #[doc(test(attr(allow(dead_code))))] | |
| 86 | /// Example | |
| 87 | /// | |
| 88 | /// ```rust,no_run | |
| 89 | /// trait OnlyWarningAtImplA { fn no_deny_warnings(); } | |
| 90 | /// ``` | |
| 91 | impl A { | |
| 92 | /// Example | |
| 93 | /// | |
| 94 | /// ```rust,no_run | |
| 95 | /// trait NotDeadCodeInImplMethod {} | |
| 96 | /// ``` | |
| 97 | fn method() {} | |
| 98 | } | |
| 99 | ||
| 100 | #[doc(test(attr(deny(dead_code))))] | |
| 101 | /// Example | |
| 102 | /// | |
| 103 | /// ```rust,no_run | |
| 104 | /// trait StillDeadCodeAtMyTrait { } | |
| 105 | /// ``` | |
| 106 | trait MyTrait { | |
| 107 | #[doc(test(attr(allow(dead_code))))] | |
| 108 | /// Example | |
| 109 | /// | |
| 110 | /// ```rust,no_run | |
| 111 | /// trait NotDeadCodeAtImplFn {} | |
| 112 | /// | |
| 113 | /// fn main() { let unused_in_impl = 5; } | |
| 114 | /// ``` | |
| 115 | fn my_trait_fn(); | |
| 116 | } |
tests/rustdoc-ui/doctest/dead-code-items.stdout created+146| ... | ... | @@ -0,0 +1,146 @@ |
| 1 | ||
| 2 | running 13 tests | |
| 3 | test $DIR/dead-code-items.rs - A (line 32) - compile ... ok | |
| 4 | test $DIR/dead-code-items.rs - A (line 88) - compile ... ok | |
| 5 | test $DIR/dead-code-items.rs - A::field (line 39) - compile ... FAILED | |
| 6 | test $DIR/dead-code-items.rs - A::method (line 94) - compile ... ok | |
| 7 | test $DIR/dead-code-items.rs - C (line 22) - compile ... FAILED | |
| 8 | test $DIR/dead-code-items.rs - Enum (line 70) - compile ... FAILED | |
| 9 | test $DIR/dead-code-items.rs - Enum::Variant1 (line 77) - compile ... FAILED | |
| 10 | test $DIR/dead-code-items.rs - MyTrait (line 103) - compile ... FAILED | |
| 11 | test $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) - compile ... FAILED | |
| 12 | test $DIR/dead-code-items.rs - S (line 14) - compile ... ok | |
| 13 | test $DIR/dead-code-items.rs - U (line 48) - compile ... ok | |
| 14 | test $DIR/dead-code-items.rs - U::field (line 55) - compile ... FAILED | |
| 15 | test $DIR/dead-code-items.rs - U::field2 (line 61) - compile ... ok | |
| 16 | ||
| 17 | failures: | |
| 18 | ||
| 19 | ---- $DIR/dead-code-items.rs - A::field (line 39) stdout ---- | |
| 20 | error: trait `DeadCodeInField` is never used | |
| 21 | --> $DIR/dead-code-items.rs:40:7 | |
| 22 | | | |
| 23 | LL | trait DeadCodeInField {} | |
| 24 | | ^^^^^^^^^^^^^^^ | |
| 25 | | | |
| 26 | note: the lint level is defined here | |
| 27 | --> $DIR/dead-code-items.rs:38:9 | |
| 28 | | | |
| 29 | LL | #![deny(dead_code)] | |
| 30 | | ^^^^^^^^^ | |
| 31 | ||
| 32 | error: aborting due to 1 previous error | |
| 33 | ||
| 34 | Couldn't compile the test. | |
| 35 | ---- $DIR/dead-code-items.rs - C (line 22) stdout ---- | |
| 36 | error: unused variable: `unused_error` | |
| 37 | --> $DIR/dead-code-items.rs:23:5 | |
| 38 | | | |
| 39 | LL | let unused_error = 5; | |
| 40 | | ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_error` | |
| 41 | | | |
| 42 | note: the lint level is defined here | |
| 43 | --> $DIR/dead-code-items.rs:20:9 | |
| 44 | | | |
| 45 | LL | #![deny(warnings)] | |
| 46 | | ^^^^^^^^ | |
| 47 | = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` | |
| 48 | ||
| 49 | error: aborting due to 1 previous error | |
| 50 | ||
| 51 | Couldn't compile the test. | |
| 52 | ---- $DIR/dead-code-items.rs - Enum (line 70) stdout ---- | |
| 53 | error: unused variable: `not_dead_code_but_unused` | |
| 54 | --> $DIR/dead-code-items.rs:71:5 | |
| 55 | | | |
| 56 | LL | let not_dead_code_but_unused = 5; | |
| 57 | | ^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_not_dead_code_but_unused` | |
| 58 | | | |
| 59 | note: the lint level is defined here | |
| 60 | --> $DIR/dead-code-items.rs:68:9 | |
| 61 | | | |
| 62 | LL | #![deny(warnings)] | |
| 63 | | ^^^^^^^^ | |
| 64 | = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` | |
| 65 | ||
| 66 | error: aborting due to 1 previous error | |
| 67 | ||
| 68 | Couldn't compile the test. | |
| 69 | ---- $DIR/dead-code-items.rs - Enum::Variant1 (line 77) stdout ---- | |
| 70 | error: unused variable: `unused_in_variant` | |
| 71 | --> $DIR/dead-code-items.rs:80:17 | |
| 72 | | | |
| 73 | LL | fn main() { let unused_in_variant = 5; } | |
| 74 | | ^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_variant` | |
| 75 | | | |
| 76 | note: the lint level is defined here | |
| 77 | --> $DIR/dead-code-items.rs:75:9 | |
| 78 | | | |
| 79 | LL | #![deny(warnings)] | |
| 80 | | ^^^^^^^^ | |
| 81 | = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` | |
| 82 | ||
| 83 | error: aborting due to 1 previous error | |
| 84 | ||
| 85 | Couldn't compile the test. | |
| 86 | ---- $DIR/dead-code-items.rs - MyTrait (line 103) stdout ---- | |
| 87 | error: trait `StillDeadCodeAtMyTrait` is never used | |
| 88 | --> $DIR/dead-code-items.rs:104:7 | |
| 89 | | | |
| 90 | LL | trait StillDeadCodeAtMyTrait { } | |
| 91 | | ^^^^^^^^^^^^^^^^^^^^^^ | |
| 92 | | | |
| 93 | note: the lint level is defined here | |
| 94 | --> $DIR/dead-code-items.rs:102:9 | |
| 95 | | | |
| 96 | LL | #![deny(dead_code)] | |
| 97 | | ^^^^^^^^^ | |
| 98 | ||
| 99 | error: aborting due to 1 previous error | |
| 100 | ||
| 101 | Couldn't compile the test. | |
| 102 | ---- $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) stdout ---- | |
| 103 | error: unused variable: `unused_in_impl` | |
| 104 | --> $DIR/dead-code-items.rs:113:17 | |
| 105 | | | |
| 106 | LL | fn main() { let unused_in_impl = 5; } | |
| 107 | | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_impl` | |
| 108 | | | |
| 109 | note: the lint level is defined here | |
| 110 | --> $DIR/dead-code-items.rs:108:9 | |
| 111 | | | |
| 112 | LL | #![deny(warnings)] | |
| 113 | | ^^^^^^^^ | |
| 114 | = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` | |
| 115 | ||
| 116 | error: aborting due to 1 previous error | |
| 117 | ||
| 118 | Couldn't compile the test. | |
| 119 | ---- $DIR/dead-code-items.rs - U::field (line 55) stdout ---- | |
| 120 | error: trait `DeadCodeInUnionField` is never used | |
| 121 | --> $DIR/dead-code-items.rs:56:7 | |
| 122 | | | |
| 123 | LL | trait DeadCodeInUnionField {} | |
| 124 | | ^^^^^^^^^^^^^^^^^^^^ | |
| 125 | | | |
| 126 | note: the lint level is defined here | |
| 127 | --> $DIR/dead-code-items.rs:54:9 | |
| 128 | | | |
| 129 | LL | #![deny(dead_code)] | |
| 130 | | ^^^^^^^^^ | |
| 131 | ||
| 132 | error: aborting due to 1 previous error | |
| 133 | ||
| 134 | Couldn't compile the test. | |
| 135 | ||
| 136 | failures: | |
| 137 | $DIR/dead-code-items.rs - A::field (line 39) | |
| 138 | $DIR/dead-code-items.rs - C (line 22) | |
| 139 | $DIR/dead-code-items.rs - Enum (line 70) | |
| 140 | $DIR/dead-code-items.rs - Enum::Variant1 (line 77) | |
| 141 | $DIR/dead-code-items.rs - MyTrait (line 103) | |
| 142 | $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) | |
| 143 | $DIR/dead-code-items.rs - U::field (line 55) | |
| 144 | ||
| 145 | test result: FAILED. 6 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 146 |
tests/rustdoc-ui/doctest/dead-code-module-2.rs created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | // Same test as dead-code-module but with 2 doc(test(attr())) at different levels. | |
| 2 | ||
| 3 | //@ edition: 2024 | |
| 4 | //@ compile-flags:--test | |
| 5 | //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" | |
| 6 | //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" | |
| 7 | //@ failure-status: 101 | |
| 8 | ||
| 9 | #![doc(test(attr(allow(unused_variables))))] | |
| 10 | ||
| 11 | mod my_mod { | |
| 12 | #![doc(test(attr(deny(warnings))))] | |
| 13 | ||
| 14 | /// Example | |
| 15 | /// | |
| 16 | /// ```rust,no_run | |
| 17 | /// trait T { fn f(); } | |
| 18 | /// ``` | |
| 19 | pub fn f() {} | |
| 20 | } | |
| 21 | ||
| 22 | /// Example | |
| 23 | /// | |
| 24 | /// ```rust,no_run | |
| 25 | /// trait OnlyWarning { fn no_deny_warnings(); } | |
| 26 | /// ``` | |
| 27 | pub fn g() {} |
tests/rustdoc-ui/doctest/dead-code-module-2.stdout created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | ||
| 2 | running 1 test | |
| 3 | test $DIR/dead-code-module-2.rs - g (line 24) - compile ... ok | |
| 4 | ||
| 5 | test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 6 | ||
| 7 | ||
| 8 | running 1 test | |
| 9 | test $DIR/dead-code-module-2.rs - my_mod::f (line 16) - compile ... FAILED | |
| 10 | ||
| 11 | failures: | |
| 12 | ||
| 13 | ---- $DIR/dead-code-module-2.rs - my_mod::f (line 16) stdout ---- | |
| 14 | error: trait `T` is never used | |
| 15 | --> $DIR/dead-code-module-2.rs:17:7 | |
| 16 | | | |
| 17 | LL | trait T { fn f(); } | |
| 18 | | ^ | |
| 19 | | | |
| 20 | note: the lint level is defined here | |
| 21 | --> $DIR/dead-code-module-2.rs:15:9 | |
| 22 | | | |
| 23 | LL | #![deny(warnings)] | |
| 24 | | ^^^^^^^^ | |
| 25 | = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` | |
| 26 | ||
| 27 | error: aborting due to 1 previous error | |
| 28 | ||
| 29 | Couldn't compile the test. | |
| 30 | ||
| 31 | failures: | |
| 32 | $DIR/dead-code-module-2.rs - my_mod::f (line 16) | |
| 33 | ||
| 34 | test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 35 |
tests/rustdoc-ui/doctest/dead-code-module.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | // Same test as dead-code but inside a module. | |
| 2 | ||
| 3 | //@ edition: 2024 | |
| 4 | //@ compile-flags:--test | |
| 5 | //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" | |
| 6 | //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" | |
| 7 | //@ failure-status: 101 | |
| 8 | ||
| 9 | mod my_mod { | |
| 10 | #![doc(test(attr(allow(unused_variables), deny(warnings))))] | |
| 11 | ||
| 12 | /// Example | |
| 13 | /// | |
| 14 | /// ```rust,no_run | |
| 15 | /// trait T { fn f(); } | |
| 16 | /// ``` | |
| 17 | pub fn f() {} | |
| 18 | } |
tests/rustdoc-ui/doctest/dead-code-module.stdout created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | ||
| 2 | running 1 test | |
| 3 | test $DIR/dead-code-module.rs - my_mod::f (line 14) - compile ... FAILED | |
| 4 | ||
| 5 | failures: | |
| 6 | ||
| 7 | ---- $DIR/dead-code-module.rs - my_mod::f (line 14) stdout ---- | |
| 8 | error: trait `T` is never used | |
| 9 | --> $DIR/dead-code-module.rs:15:7 | |
| 10 | | | |
| 11 | LL | trait T { fn f(); } | |
| 12 | | ^ | |
| 13 | | | |
| 14 | note: the lint level is defined here | |
| 15 | --> $DIR/dead-code-module.rs:13:9 | |
| 16 | | | |
| 17 | LL | #![deny(warnings)] | |
| 18 | | ^^^^^^^^ | |
| 19 | = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` | |
| 20 | ||
| 21 | error: aborting due to 1 previous error | |
| 22 | ||
| 23 | Couldn't compile the test. | |
| 24 | ||
| 25 | failures: | |
| 26 | $DIR/dead-code-module.rs - my_mod::f (line 14) | |
| 27 | ||
| 28 | test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 29 |
tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | //@ check-pass | |
| 2 | ||
| 3 | #![crate_type = "lib"] | |
| 4 | #![deny(invalid_doc_attributes)] | |
| 5 | #![doc(test(no_crate_inject))] | |
| 6 | ||
| 7 | mod my_mod { | |
| 8 | #![doc(test(attr(deny(warnings))))] | |
| 9 | ||
| 10 | pub fn foo() {} | |
| 11 | } |
tests/ui/future-incompatible-lint-group.rs+4-6| ... | ... | @@ -2,16 +2,14 @@ |
| 2 | 2 | // lints for changes that are not tied to an edition |
| 3 | 3 | #![deny(future_incompatible)] |
| 4 | 4 | |
| 5 | // Error since this is a `future_incompatible` lint | |
| 6 | macro_rules! m { ($i) => {} } //~ ERROR missing fragment specifier | |
| 7 | //~| WARN this was previously accepted | |
| 8 | ||
| 5 | 9 | trait Tr { |
| 6 | 10 | // Warn only since this is not a `future_incompatible` lint |
| 7 | 11 | fn f(u8) {} //~ WARN anonymous parameters are deprecated |
| 8 | 12 | //~| WARN this is accepted in the current edition |
| 9 | 13 | } |
| 10 | 14 | |
| 11 | pub mod submodule { | |
| 12 | // Error since this is a `future_incompatible` lint | |
| 13 | #![doc(test(some_test))] | |
| 14 | //~^ ERROR this attribute can only be applied at the crate level | |
| 15 | } | |
| 16 | ||
| 17 | 15 | fn main() {} |
tests/ui/future-incompatible-lint-group.stderr+31-9| ... | ... | @@ -1,5 +1,20 @@ |
| 1 | error: missing fragment specifier | |
| 2 | --> $DIR/future-incompatible-lint-group.rs:6:19 | |
| 3 | | | |
| 4 | LL | macro_rules! m { ($i) => {} } | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 8 | = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> | |
| 9 | note: the lint level is defined here | |
| 10 | --> $DIR/future-incompatible-lint-group.rs:3:9 | |
| 11 | | | |
| 12 | LL | #![deny(future_incompatible)] | |
| 13 | | ^^^^^^^^^^^^^^^^^^^ | |
| 14 | = note: `#[deny(missing_fragment_specifier)]` implied by `#[deny(future_incompatible)]` | |
| 15 | ||
| 1 | 16 | warning: anonymous parameters are deprecated and will be removed in the next edition |
| 2 | --> $DIR/future-incompatible-lint-group.rs:7:10 | |
| 17 | --> $DIR/future-incompatible-lint-group.rs:11:10 | |
| 3 | 18 | | |
| 4 | 19 | LL | fn f(u8) {} |
| 5 | 20 | | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` |
| ... | ... | @@ -8,14 +23,21 @@ LL | fn f(u8) {} |
| 8 | 23 | = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> |
| 9 | 24 | = note: `#[warn(anonymous_parameters)]` on by default |
| 10 | 25 | |
| 11 | error: this attribute can only be applied at the crate level | |
| 12 | --> $DIR/future-incompatible-lint-group.rs:13:12 | |
| 26 | error: aborting due to 1 previous error; 1 warning emitted | |
| 27 | ||
| 28 | Future incompatibility report: Future breakage diagnostic: | |
| 29 | error: missing fragment specifier | |
| 30 | --> $DIR/future-incompatible-lint-group.rs:6:19 | |
| 13 | 31 | | |
| 14 | LL | #![doc(test(some_test))] | |
| 15 | | ^^^^^^^^^^^^^^^ | |
| 32 | LL | macro_rules! m { ($i) => {} } | |
| 33 | | ^^ | |
| 16 | 34 | | |
| 17 | = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information | |
| 18 | = note: `#[deny(invalid_doc_attributes)]` on by default | |
| 19 | ||
| 20 | error: aborting due to 1 previous error; 1 warning emitted | |
| 35 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 36 | = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> | |
| 37 | note: the lint level is defined here | |
| 38 | --> $DIR/future-incompatible-lint-group.rs:3:9 | |
| 39 | | | |
| 40 | LL | #![deny(future_incompatible)] | |
| 41 | | ^^^^^^^^^^^^^^^^^^^ | |
| 42 | = note: `#[deny(missing_fragment_specifier)]` implied by `#[deny(future_incompatible)]` | |
| 21 | 43 |
tests/ui/lint/force-warn/ice-free.rs created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | //@ compile-flags: --force-warn pub_use_of_private_extern_crate | |
| 2 | //@ check-pass | |
| 3 | ||
| 4 | extern crate core; | |
| 5 | pub use core as reexported_core; | |
| 6 | //~^ warning: extern crate `core` is private | |
| 7 | //~| warning: this was previously accepted by the compiler | |
| 8 | ||
| 9 | fn main() {} |
tests/ui/lint/force-warn/ice-free.stderr created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | warning[E0365]: extern crate `core` is private and cannot be re-exported | |
| 2 | --> $DIR/ice-free.rs:5:9 | |
| 3 | | | |
| 4 | LL | pub use core as reexported_core; | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 8 | = note: for more information, see issue #127909 <https://github.com/rust-lang/rust/issues/127909> | |
| 9 | = note: requested on the command line with `--force-warn pub-use-of-private-extern-crate` | |
| 10 | help: consider making the `extern crate` item publicly accessible | |
| 11 | | | |
| 12 | LL | pub extern crate core; | |
| 13 | | +++ | |
| 14 | ||
| 15 | warning: 1 warning emitted | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0365`. | |
| 18 | Future incompatibility report: Future breakage diagnostic: | |
| 19 | warning[E0365]: extern crate `core` is private and cannot be re-exported | |
| 20 | --> $DIR/ice-free.rs:5:9 | |
| 21 | | | |
| 22 | LL | pub use core as reexported_core; | |
| 23 | | ^^^^^^^^^^^^^^^^^^^^^^^ | |
| 24 | | | |
| 25 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 26 | = note: for more information, see issue #127909 <https://github.com/rust-lang/rust/issues/127909> | |
| 27 | = note: requested on the command line with `--force-warn pub-use-of-private-extern-crate` | |
| 28 | help: consider making the `extern crate` item publicly accessible | |
| 29 | | | |
| 30 | LL | pub extern crate core; | |
| 31 | | +++ | |
| 32 |
tests/ui/lint/implicit_autorefs.fixed+28-25| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | //@ check-pass | |
| 1 | //@ check-fail | |
| 2 | 2 | //@ run-rustfix |
| 3 | 3 | |
| 4 | 4 | #![allow(dead_code)] // For the rustfix-ed code. |
| ... | ... | @@ -8,7 +8,7 @@ use std::ops::Deref; |
| 8 | 8 | |
| 9 | 9 | unsafe fn test_const(ptr: *const [u8]) { |
| 10 | 10 | let _ = (&(*ptr))[..16]; |
| 11 | //~^ WARN implicit autoref | |
| 11 | //~^ ERROR implicit autoref | |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | struct Test { |
| ... | ... | @@ -17,36 +17,36 @@ struct Test { |
| 17 | 17 | |
| 18 | 18 | unsafe fn test_field(ptr: *const Test) -> *const [u8] { |
| 19 | 19 | let l = (&(*ptr).field).len(); |
| 20 | //~^ WARN implicit autoref | |
| 20 | //~^ ERROR implicit autoref | |
| 21 | 21 | |
| 22 | 22 | &raw const (&(*ptr).field)[..l - 1] |
| 23 | //~^ WARN implicit autoref | |
| 23 | //~^ ERROR implicit autoref | |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | unsafe fn test_builtin_index(a: *mut [String]) { |
| 27 | 27 | _ = (&(*a)[0]).len(); |
| 28 | //~^ WARN implicit autoref | |
| 28 | //~^ ERROR implicit autoref | |
| 29 | 29 | |
| 30 | 30 | _ = (&(&(*a))[..1][0]).len(); |
| 31 | //~^ WARN implicit autoref | |
| 32 | //~^^ WARN implicit autoref | |
| 31 | //~^ ERROR implicit autoref | |
| 32 | //~^^ ERROR implicit autoref | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) { |
| 36 | 36 | let _ = (&(*ptr)).field; |
| 37 | //~^ WARN implicit autoref | |
| 37 | //~^ ERROR implicit autoref | |
| 38 | 38 | let _ = &raw const (&(*ptr)).field; |
| 39 | //~^ WARN implicit autoref | |
| 39 | //~^ ERROR implicit autoref | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) { |
| 43 | 43 | let _ = (&(*ptr)).field; |
| 44 | //~^ WARN implicit autoref | |
| 44 | //~^ ERROR implicit autoref | |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | unsafe fn test_double_overloaded_deref_const(ptr: *const ManuallyDrop<ManuallyDrop<Test>>) { |
| 48 | 48 | let _ = (&(*ptr)).field; |
| 49 | //~^ WARN implicit autoref | |
| 49 | //~^ ERROR implicit autoref | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | unsafe fn test_manually_overloaded_deref() { |
| ... | ... | @@ -54,52 +54,55 @@ unsafe fn test_manually_overloaded_deref() { |
| 54 | 54 | |
| 55 | 55 | impl<T> Deref for W<T> { |
| 56 | 56 | type Target = T; |
| 57 | fn deref(&self) -> &T { &self.0 } | |
| 57 | fn deref(&self) -> &T { | |
| 58 | &self.0 | |
| 59 | } | |
| 58 | 60 | } |
| 59 | 61 | |
| 60 | 62 | let w: W<i32> = W(5); |
| 61 | 63 | let w = &raw const w; |
| 62 | 64 | let _p: *const i32 = &raw const *(&**w); |
| 63 | //~^ WARN implicit autoref | |
| 65 | //~^ ERROR implicit autoref | |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | 68 | struct Test2 { |
| 67 | 69 | // Derefs to `[u8]`. |
| 68 | field: &'static [u8] | |
| 70 | field: &'static [u8], | |
| 69 | 71 | } |
| 70 | 72 | |
| 71 | 73 | fn test_more_manual_deref(ptr: *const Test2) -> usize { |
| 72 | 74 | unsafe { (&(*ptr).field).len() } |
| 73 | //~^ WARN implicit autoref | |
| 75 | //~^ ERROR implicit autoref | |
| 74 | 76 | } |
| 75 | 77 | |
| 76 | 78 | unsafe fn test_no_attr(ptr: *mut ManuallyDrop<u8>) { |
| 77 | ptr.write(ManuallyDrop::new(1)); // Should not warn, as `ManuallyDrop::write` is not | |
| 78 | // annotated with `#[rustc_no_implicit_auto_ref]` | |
| 79 | // Should not warn, as `ManuallyDrop::write` is not | |
| 80 | // annotated with `#[rustc_no_implicit_auto_ref]` | |
| 81 | ptr.write(ManuallyDrop::new(1)); | |
| 79 | 82 | } |
| 80 | 83 | |
| 81 | 84 | unsafe fn test_vec_get(ptr: *mut Vec<u8>) { |
| 82 | 85 | let _ = (&(*ptr)).get(0); |
| 83 | //~^ WARN implicit autoref | |
| 86 | //~^ ERROR implicit autoref | |
| 84 | 87 | let _ = (&(*ptr)).get_unchecked(0); |
| 85 | //~^ WARN implicit autoref | |
| 88 | //~^ ERROR implicit autoref | |
| 86 | 89 | let _ = (&mut (*ptr)).get_mut(0); |
| 87 | //~^ WARN implicit autoref | |
| 90 | //~^ ERROR implicit autoref | |
| 88 | 91 | let _ = (&mut (*ptr)).get_unchecked_mut(0); |
| 89 | //~^ WARN implicit autoref | |
| 92 | //~^ ERROR implicit autoref | |
| 90 | 93 | } |
| 91 | 94 | |
| 92 | 95 | unsafe fn test_string(ptr: *mut String) { |
| 93 | 96 | let _ = (&(*ptr)).len(); |
| 94 | //~^ WARN implicit autoref | |
| 97 | //~^ ERROR implicit autoref | |
| 95 | 98 | let _ = (&(*ptr)).is_empty(); |
| 96 | //~^ WARN implicit autoref | |
| 99 | //~^ ERROR implicit autoref | |
| 97 | 100 | } |
| 98 | 101 | |
| 99 | 102 | unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) { |
| 100 | 103 | let _ = (&(&(*slice))[..]).len(); |
| 101 | //~^ WARN implicit autoref | |
| 102 | //~^^ WARN implicit autoref | |
| 104 | //~^ ERROR implicit autoref | |
| 105 | //~^^ ERROR implicit autoref | |
| 103 | 106 | } |
| 104 | 107 | |
| 105 | 108 | fn main() {} |
tests/ui/lint/implicit_autorefs.rs+28-25| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | //@ check-pass | |
| 1 | //@ check-fail | |
| 2 | 2 | //@ run-rustfix |
| 3 | 3 | |
| 4 | 4 | #![allow(dead_code)] // For the rustfix-ed code. |
| ... | ... | @@ -8,7 +8,7 @@ use std::ops::Deref; |
| 8 | 8 | |
| 9 | 9 | unsafe fn test_const(ptr: *const [u8]) { |
| 10 | 10 | let _ = (*ptr)[..16]; |
| 11 | //~^ WARN implicit autoref | |
| 11 | //~^ ERROR implicit autoref | |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | struct Test { |
| ... | ... | @@ -17,36 +17,36 @@ struct Test { |
| 17 | 17 | |
| 18 | 18 | unsafe fn test_field(ptr: *const Test) -> *const [u8] { |
| 19 | 19 | let l = (*ptr).field.len(); |
| 20 | //~^ WARN implicit autoref | |
| 20 | //~^ ERROR implicit autoref | |
| 21 | 21 | |
| 22 | 22 | &raw const (*ptr).field[..l - 1] |
| 23 | //~^ WARN implicit autoref | |
| 23 | //~^ ERROR implicit autoref | |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | unsafe fn test_builtin_index(a: *mut [String]) { |
| 27 | 27 | _ = (*a)[0].len(); |
| 28 | //~^ WARN implicit autoref | |
| 28 | //~^ ERROR implicit autoref | |
| 29 | 29 | |
| 30 | 30 | _ = (*a)[..1][0].len(); |
| 31 | //~^ WARN implicit autoref | |
| 32 | //~^^ WARN implicit autoref | |
| 31 | //~^ ERROR implicit autoref | |
| 32 | //~^^ ERROR implicit autoref | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) { |
| 36 | 36 | let _ = (*ptr).field; |
| 37 | //~^ WARN implicit autoref | |
| 37 | //~^ ERROR implicit autoref | |
| 38 | 38 | let _ = &raw const (*ptr).field; |
| 39 | //~^ WARN implicit autoref | |
| 39 | //~^ ERROR implicit autoref | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) { |
| 43 | 43 | let _ = (*ptr).field; |
| 44 | //~^ WARN implicit autoref | |
| 44 | //~^ ERROR implicit autoref | |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | unsafe fn test_double_overloaded_deref_const(ptr: *const ManuallyDrop<ManuallyDrop<Test>>) { |
| 48 | 48 | let _ = (*ptr).field; |
| 49 | //~^ WARN implicit autoref | |
| 49 | //~^ ERROR implicit autoref | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | unsafe fn test_manually_overloaded_deref() { |
| ... | ... | @@ -54,52 +54,55 @@ unsafe fn test_manually_overloaded_deref() { |
| 54 | 54 | |
| 55 | 55 | impl<T> Deref for W<T> { |
| 56 | 56 | type Target = T; |
| 57 | fn deref(&self) -> &T { &self.0 } | |
| 57 | fn deref(&self) -> &T { | |
| 58 | &self.0 | |
| 59 | } | |
| 58 | 60 | } |
| 59 | 61 | |
| 60 | 62 | let w: W<i32> = W(5); |
| 61 | 63 | let w = &raw const w; |
| 62 | 64 | let _p: *const i32 = &raw const **w; |
| 63 | //~^ WARN implicit autoref | |
| 65 | //~^ ERROR implicit autoref | |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | 68 | struct Test2 { |
| 67 | 69 | // Derefs to `[u8]`. |
| 68 | field: &'static [u8] | |
| 70 | field: &'static [u8], | |
| 69 | 71 | } |
| 70 | 72 | |
| 71 | 73 | fn test_more_manual_deref(ptr: *const Test2) -> usize { |
| 72 | 74 | unsafe { (*ptr).field.len() } |
| 73 | //~^ WARN implicit autoref | |
| 75 | //~^ ERROR implicit autoref | |
| 74 | 76 | } |
| 75 | 77 | |
| 76 | 78 | unsafe fn test_no_attr(ptr: *mut ManuallyDrop<u8>) { |
| 77 | ptr.write(ManuallyDrop::new(1)); // Should not warn, as `ManuallyDrop::write` is not | |
| 78 | // annotated with `#[rustc_no_implicit_auto_ref]` | |
| 79 | // Should not warn, as `ManuallyDrop::write` is not | |
| 80 | // annotated with `#[rustc_no_implicit_auto_ref]` | |
| 81 | ptr.write(ManuallyDrop::new(1)); | |
| 79 | 82 | } |
| 80 | 83 | |
| 81 | 84 | unsafe fn test_vec_get(ptr: *mut Vec<u8>) { |
| 82 | 85 | let _ = (*ptr).get(0); |
| 83 | //~^ WARN implicit autoref | |
| 86 | //~^ ERROR implicit autoref | |
| 84 | 87 | let _ = (*ptr).get_unchecked(0); |
| 85 | //~^ WARN implicit autoref | |
| 88 | //~^ ERROR implicit autoref | |
| 86 | 89 | let _ = (*ptr).get_mut(0); |
| 87 | //~^ WARN implicit autoref | |
| 90 | //~^ ERROR implicit autoref | |
| 88 | 91 | let _ = (*ptr).get_unchecked_mut(0); |
| 89 | //~^ WARN implicit autoref | |
| 92 | //~^ ERROR implicit autoref | |
| 90 | 93 | } |
| 91 | 94 | |
| 92 | 95 | unsafe fn test_string(ptr: *mut String) { |
| 93 | 96 | let _ = (*ptr).len(); |
| 94 | //~^ WARN implicit autoref | |
| 97 | //~^ ERROR implicit autoref | |
| 95 | 98 | let _ = (*ptr).is_empty(); |
| 96 | //~^ WARN implicit autoref | |
| 99 | //~^ ERROR implicit autoref | |
| 97 | 100 | } |
| 98 | 101 | |
| 99 | 102 | unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) { |
| 100 | 103 | let _ = (*slice)[..].len(); |
| 101 | //~^ WARN implicit autoref | |
| 102 | //~^^ WARN implicit autoref | |
| 104 | //~^ ERROR implicit autoref | |
| 105 | //~^^ ERROR implicit autoref | |
| 103 | 106 | } |
| 104 | 107 | |
| 105 | 108 | fn main() {} |
tests/ui/lint/implicit_autorefs.stderr+42-42| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 1 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 2 | 2 | --> $DIR/implicit_autorefs.rs:10:13 |
| 3 | 3 | | |
| 4 | 4 | LL | let _ = (*ptr)[..16]; |
| ... | ... | @@ -12,13 +12,13 @@ note: autoref is being applied to this expression, resulting in: `&[u8]` |
| 12 | 12 | | |
| 13 | 13 | LL | let _ = (*ptr)[..16]; |
| 14 | 14 | | ^^^^^^ |
| 15 | = note: `#[warn(dangerous_implicit_autorefs)]` on by default | |
| 15 | = note: `#[deny(dangerous_implicit_autorefs)]` on by default | |
| 16 | 16 | help: try using a raw pointer method instead; or if this reference is intentional, make it explicit |
| 17 | 17 | | |
| 18 | 18 | LL | let _ = (&(*ptr))[..16]; |
| 19 | 19 | | ++ + |
| 20 | 20 | |
| 21 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 21 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 22 | 22 | --> $DIR/implicit_autorefs.rs:19:13 |
| 23 | 23 | | |
| 24 | 24 | LL | let l = (*ptr).field.len(); |
| ... | ... | @@ -39,7 +39,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 39 | 39 | LL | let l = (&(*ptr).field).len(); |
| 40 | 40 | | ++ + |
| 41 | 41 | |
| 42 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 42 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 43 | 43 | --> $DIR/implicit_autorefs.rs:22:16 |
| 44 | 44 | | |
| 45 | 45 | LL | &raw const (*ptr).field[..l - 1] |
| ... | ... | @@ -58,7 +58,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 58 | 58 | LL | &raw const (&(*ptr).field)[..l - 1] |
| 59 | 59 | | ++ + |
| 60 | 60 | |
| 61 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 61 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 62 | 62 | --> $DIR/implicit_autorefs.rs:27:9 |
| 63 | 63 | | |
| 64 | 64 | LL | _ = (*a)[0].len(); |
| ... | ... | @@ -79,7 +79,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 79 | 79 | LL | _ = (&(*a)[0]).len(); |
| 80 | 80 | | ++ + |
| 81 | 81 | |
| 82 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 82 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 83 | 83 | --> $DIR/implicit_autorefs.rs:30:9 |
| 84 | 84 | | |
| 85 | 85 | LL | _ = (*a)[..1][0].len(); |
| ... | ... | @@ -100,7 +100,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 100 | 100 | LL | _ = (&(*a)[..1][0]).len(); |
| 101 | 101 | | ++ + |
| 102 | 102 | |
| 103 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 103 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 104 | 104 | --> $DIR/implicit_autorefs.rs:30:9 |
| 105 | 105 | | |
| 106 | 106 | LL | _ = (*a)[..1][0].len(); |
| ... | ... | @@ -119,7 +119,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 119 | 119 | LL | _ = (&(*a))[..1][0].len(); |
| 120 | 120 | | ++ + |
| 121 | 121 | |
| 122 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 122 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 123 | 123 | --> $DIR/implicit_autorefs.rs:36:13 |
| 124 | 124 | | |
| 125 | 125 | LL | let _ = (*ptr).field; |
| ... | ... | @@ -134,7 +134,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 134 | 134 | LL | let _ = (&(*ptr)).field; |
| 135 | 135 | | ++ + |
| 136 | 136 | |
| 137 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 137 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 138 | 138 | --> $DIR/implicit_autorefs.rs:38:24 |
| 139 | 139 | | |
| 140 | 140 | LL | let _ = &raw const (*ptr).field; |
| ... | ... | @@ -149,7 +149,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 149 | 149 | LL | let _ = &raw const (&(*ptr)).field; |
| 150 | 150 | | ++ + |
| 151 | 151 | |
| 152 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 152 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 153 | 153 | --> $DIR/implicit_autorefs.rs:43:13 |
| 154 | 154 | | |
| 155 | 155 | LL | let _ = (*ptr).field; |
| ... | ... | @@ -164,7 +164,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 164 | 164 | LL | let _ = (&(*ptr)).field; |
| 165 | 165 | | ++ + |
| 166 | 166 | |
| 167 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 167 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 168 | 168 | --> $DIR/implicit_autorefs.rs:48:13 |
| 169 | 169 | | |
| 170 | 170 | LL | let _ = (*ptr).field; |
| ... | ... | @@ -179,8 +179,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 179 | 179 | LL | let _ = (&(*ptr)).field; |
| 180 | 180 | | ++ + |
| 181 | 181 | |
| 182 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 183 | --> $DIR/implicit_autorefs.rs:62:26 | |
| 182 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 183 | --> $DIR/implicit_autorefs.rs:64:26 | |
| 184 | 184 | | |
| 185 | 185 | LL | let _p: *const i32 = &raw const **w; |
| 186 | 186 | | ^^^^^^^^^^^^^- |
| ... | ... | @@ -189,7 +189,7 @@ LL | let _p: *const i32 = &raw const **w; |
| 189 | 189 | | |
| 190 | 190 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 191 | 191 | note: autoref is being applied to this expression, resulting in: `&W<i32>` |
| 192 | --> $DIR/implicit_autorefs.rs:62:38 | |
| 192 | --> $DIR/implicit_autorefs.rs:64:38 | |
| 193 | 193 | | |
| 194 | 194 | LL | let _p: *const i32 = &raw const **w; |
| 195 | 195 | | ^^ |
| ... | ... | @@ -198,8 +198,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 198 | 198 | LL | let _p: *const i32 = &raw const *(&**w); |
| 199 | 199 | | +++ + |
| 200 | 200 | |
| 201 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 202 | --> $DIR/implicit_autorefs.rs:72:14 | |
| 201 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 202 | --> $DIR/implicit_autorefs.rs:74:14 | |
| 203 | 203 | | |
| 204 | 204 | LL | unsafe { (*ptr).field.len() } |
| 205 | 205 | | ^^---^^^^^^^^^^^^^ |
| ... | ... | @@ -208,7 +208,7 @@ LL | unsafe { (*ptr).field.len() } |
| 208 | 208 | | |
| 209 | 209 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 210 | 210 | note: autoref is being applied to this expression, resulting in: `&[u8]` |
| 211 | --> $DIR/implicit_autorefs.rs:72:14 | |
| 211 | --> $DIR/implicit_autorefs.rs:74:14 | |
| 212 | 212 | | |
| 213 | 213 | LL | unsafe { (*ptr).field.len() } |
| 214 | 214 | | ^^^^^^^^^^^^ |
| ... | ... | @@ -219,8 +219,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 219 | 219 | LL | unsafe { (&(*ptr).field).len() } |
| 220 | 220 | | ++ + |
| 221 | 221 | |
| 222 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 223 | --> $DIR/implicit_autorefs.rs:82:13 | |
| 222 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 223 | --> $DIR/implicit_autorefs.rs:85:13 | |
| 224 | 224 | | |
| 225 | 225 | LL | let _ = (*ptr).get(0); |
| 226 | 226 | | ^^---^^^^^^^^ |
| ... | ... | @@ -229,7 +229,7 @@ LL | let _ = (*ptr).get(0); |
| 229 | 229 | | |
| 230 | 230 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 231 | 231 | note: autoref is being applied to this expression, resulting in: `&[u8]` |
| 232 | --> $DIR/implicit_autorefs.rs:82:13 | |
| 232 | --> $DIR/implicit_autorefs.rs:85:13 | |
| 233 | 233 | | |
| 234 | 234 | LL | let _ = (*ptr).get(0); |
| 235 | 235 | | ^^^^^^ |
| ... | ... | @@ -240,8 +240,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 240 | 240 | LL | let _ = (&(*ptr)).get(0); |
| 241 | 241 | | ++ + |
| 242 | 242 | |
| 243 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 244 | --> $DIR/implicit_autorefs.rs:84:13 | |
| 243 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 244 | --> $DIR/implicit_autorefs.rs:87:13 | |
| 245 | 245 | | |
| 246 | 246 | LL | let _ = (*ptr).get_unchecked(0); |
| 247 | 247 | | ^^---^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -250,7 +250,7 @@ LL | let _ = (*ptr).get_unchecked(0); |
| 250 | 250 | | |
| 251 | 251 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 252 | 252 | note: autoref is being applied to this expression, resulting in: `&[u8]` |
| 253 | --> $DIR/implicit_autorefs.rs:84:13 | |
| 253 | --> $DIR/implicit_autorefs.rs:87:13 | |
| 254 | 254 | | |
| 255 | 255 | LL | let _ = (*ptr).get_unchecked(0); |
| 256 | 256 | | ^^^^^^ |
| ... | ... | @@ -261,8 +261,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 261 | 261 | LL | let _ = (&(*ptr)).get_unchecked(0); |
| 262 | 262 | | ++ + |
| 263 | 263 | |
| 264 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 265 | --> $DIR/implicit_autorefs.rs:86:13 | |
| 264 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 265 | --> $DIR/implicit_autorefs.rs:89:13 | |
| 266 | 266 | | |
| 267 | 267 | LL | let _ = (*ptr).get_mut(0); |
| 268 | 268 | | ^^---^^^^^^^^^^^^ |
| ... | ... | @@ -271,7 +271,7 @@ LL | let _ = (*ptr).get_mut(0); |
| 271 | 271 | | |
| 272 | 272 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 273 | 273 | note: autoref is being applied to this expression, resulting in: `&mut [u8]` |
| 274 | --> $DIR/implicit_autorefs.rs:86:13 | |
| 274 | --> $DIR/implicit_autorefs.rs:89:13 | |
| 275 | 275 | | |
| 276 | 276 | LL | let _ = (*ptr).get_mut(0); |
| 277 | 277 | | ^^^^^^ |
| ... | ... | @@ -282,8 +282,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 282 | 282 | LL | let _ = (&mut (*ptr)).get_mut(0); |
| 283 | 283 | | +++++ + |
| 284 | 284 | |
| 285 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 286 | --> $DIR/implicit_autorefs.rs:88:13 | |
| 285 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 286 | --> $DIR/implicit_autorefs.rs:91:13 | |
| 287 | 287 | | |
| 288 | 288 | LL | let _ = (*ptr).get_unchecked_mut(0); |
| 289 | 289 | | ^^---^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -292,7 +292,7 @@ LL | let _ = (*ptr).get_unchecked_mut(0); |
| 292 | 292 | | |
| 293 | 293 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 294 | 294 | note: autoref is being applied to this expression, resulting in: `&mut [u8]` |
| 295 | --> $DIR/implicit_autorefs.rs:88:13 | |
| 295 | --> $DIR/implicit_autorefs.rs:91:13 | |
| 296 | 296 | | |
| 297 | 297 | LL | let _ = (*ptr).get_unchecked_mut(0); |
| 298 | 298 | | ^^^^^^ |
| ... | ... | @@ -303,8 +303,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 303 | 303 | LL | let _ = (&mut (*ptr)).get_unchecked_mut(0); |
| 304 | 304 | | +++++ + |
| 305 | 305 | |
| 306 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 307 | --> $DIR/implicit_autorefs.rs:93:13 | |
| 306 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 307 | --> $DIR/implicit_autorefs.rs:96:13 | |
| 308 | 308 | | |
| 309 | 309 | LL | let _ = (*ptr).len(); |
| 310 | 310 | | ^^---^^^^^^^ |
| ... | ... | @@ -313,7 +313,7 @@ LL | let _ = (*ptr).len(); |
| 313 | 313 | | |
| 314 | 314 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 315 | 315 | note: autoref is being applied to this expression, resulting in: `&String` |
| 316 | --> $DIR/implicit_autorefs.rs:93:13 | |
| 316 | --> $DIR/implicit_autorefs.rs:96:13 | |
| 317 | 317 | | |
| 318 | 318 | LL | let _ = (*ptr).len(); |
| 319 | 319 | | ^^^^^^ |
| ... | ... | @@ -324,8 +324,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 324 | 324 | LL | let _ = (&(*ptr)).len(); |
| 325 | 325 | | ++ + |
| 326 | 326 | |
| 327 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 328 | --> $DIR/implicit_autorefs.rs:95:13 | |
| 327 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 328 | --> $DIR/implicit_autorefs.rs:98:13 | |
| 329 | 329 | | |
| 330 | 330 | LL | let _ = (*ptr).is_empty(); |
| 331 | 331 | | ^^---^^^^^^^^^^^^ |
| ... | ... | @@ -334,7 +334,7 @@ LL | let _ = (*ptr).is_empty(); |
| 334 | 334 | | |
| 335 | 335 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 336 | 336 | note: autoref is being applied to this expression, resulting in: `&String` |
| 337 | --> $DIR/implicit_autorefs.rs:95:13 | |
| 337 | --> $DIR/implicit_autorefs.rs:98:13 | |
| 338 | 338 | | |
| 339 | 339 | LL | let _ = (*ptr).is_empty(); |
| 340 | 340 | | ^^^^^^ |
| ... | ... | @@ -345,8 +345,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 345 | 345 | LL | let _ = (&(*ptr)).is_empty(); |
| 346 | 346 | | ++ + |
| 347 | 347 | |
| 348 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 349 | --> $DIR/implicit_autorefs.rs:100:13 | |
| 348 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 349 | --> $DIR/implicit_autorefs.rs:103:13 | |
| 350 | 350 | | |
| 351 | 351 | LL | let _ = (*slice)[..].len(); |
| 352 | 352 | | ^^-----^^^^^^^^^^^ |
| ... | ... | @@ -355,7 +355,7 @@ LL | let _ = (*slice)[..].len(); |
| 355 | 355 | | |
| 356 | 356 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 357 | 357 | note: autoref is being applied to this expression, resulting in: `&[T]` |
| 358 | --> $DIR/implicit_autorefs.rs:100:13 | |
| 358 | --> $DIR/implicit_autorefs.rs:103:13 | |
| 359 | 359 | | |
| 360 | 360 | LL | let _ = (*slice)[..].len(); |
| 361 | 361 | | ^^^^^^^^^^^^ |
| ... | ... | @@ -366,8 +366,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 366 | 366 | LL | let _ = (&(*slice)[..]).len(); |
| 367 | 367 | | ++ + |
| 368 | 368 | |
| 369 | warning: implicit autoref creates a reference to the dereference of a raw pointer | |
| 370 | --> $DIR/implicit_autorefs.rs:100:13 | |
| 369 | error: implicit autoref creates a reference to the dereference of a raw pointer | |
| 370 | --> $DIR/implicit_autorefs.rs:103:13 | |
| 371 | 371 | | |
| 372 | 372 | LL | let _ = (*slice)[..].len(); |
| 373 | 373 | | ^^-----^^^^^ |
| ... | ... | @@ -376,7 +376,7 @@ LL | let _ = (*slice)[..].len(); |
| 376 | 376 | | |
| 377 | 377 | = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements |
| 378 | 378 | note: autoref is being applied to this expression, resulting in: `&[T]` |
| 379 | --> $DIR/implicit_autorefs.rs:100:13 | |
| 379 | --> $DIR/implicit_autorefs.rs:103:13 | |
| 380 | 380 | | |
| 381 | 381 | LL | let _ = (*slice)[..].len(); |
| 382 | 382 | | ^^^^^^^^ |
| ... | ... | @@ -385,5 +385,5 @@ help: try using a raw pointer method instead; or if this reference is intentiona |
| 385 | 385 | LL | let _ = (&(*slice))[..].len(); |
| 386 | 386 | | ++ + |
| 387 | 387 | |
| 388 | warning: 20 warnings emitted | |
| 388 | error: aborting due to 20 previous errors | |
| 389 | 389 |
tests/ui/lint/unused/useless-comment.rs+7| ... | ... | @@ -9,8 +9,13 @@ macro_rules! mac { |
| 9 | 9 | /// foo //~ ERROR unused doc comment |
| 10 | 10 | mac!(); |
| 11 | 11 | |
| 12 | /// a //~ ERROR unused doc comment | |
| 13 | #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment | |
| 14 | unsafe extern "C" { } | |
| 15 | ||
| 12 | 16 | fn foo() { |
| 13 | 17 | /// a //~ ERROR unused doc comment |
| 18 | #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment | |
| 14 | 19 | let x = 12; |
| 15 | 20 | |
| 16 | 21 | /// multi-line //~ ERROR unused doc comment |
| ... | ... | @@ -19,6 +24,7 @@ fn foo() { |
| 19 | 24 | match x { |
| 20 | 25 | /// c //~ ERROR unused doc comment |
| 21 | 26 | 1 => {}, |
| 27 | #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment | |
| 22 | 28 | _ => {} |
| 23 | 29 | } |
| 24 | 30 | |
| ... | ... | @@ -32,6 +38,7 @@ fn foo() { |
| 32 | 38 | /// bar //~ ERROR unused doc comment |
| 33 | 39 | mac!(); |
| 34 | 40 | |
| 41 | #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment | |
| 35 | 42 | let x = /** comment */ 47; //~ ERROR unused doc comment |
| 36 | 43 | |
| 37 | 44 | /// dox //~ ERROR unused doc comment |
tests/ui/lint/unused/useless-comment.stderr+63-10| ... | ... | @@ -12,7 +12,28 @@ LL | #![deny(unused_doc_comments)] |
| 12 | 12 | | ^^^^^^^^^^^^^^^^^^^ |
| 13 | 13 | |
| 14 | 14 | error: unused doc comment |
| 15 | --> $DIR/useless-comment.rs:32:5 | |
| 15 | --> $DIR/useless-comment.rs:12:1 | |
| 16 | | | |
| 17 | LL | /// a | |
| 18 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 19 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 20 | LL | unsafe extern "C" { } | |
| 21 | | --------------------- rustdoc does not generate documentation for extern blocks | |
| 22 | | | |
| 23 | = help: use `//` for a plain comment | |
| 24 | ||
| 25 | error: unused doc comment | |
| 26 | --> $DIR/useless-comment.rs:13:1 | |
| 27 | | | |
| 28 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 30 | LL | unsafe extern "C" { } | |
| 31 | | --------------------- rustdoc does not generate documentation for extern blocks | |
| 32 | | | |
| 33 | = help: use `//` for a plain comment | |
| 34 | ||
| 35 | error: unused doc comment | |
| 36 | --> $DIR/useless-comment.rs:38:5 | |
| 16 | 37 | | |
| 17 | 38 | LL | /// bar |
| 18 | 39 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations |
| ... | ... | @@ -20,17 +41,28 @@ LL | /// bar |
| 20 | 41 | = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion |
| 21 | 42 | |
| 22 | 43 | error: unused doc comment |
| 23 | --> $DIR/useless-comment.rs:13:5 | |
| 44 | --> $DIR/useless-comment.rs:17:5 | |
| 24 | 45 | | |
| 25 | 46 | LL | /// a |
| 26 | 47 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 48 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 27 | 49 | LL | let x = 12; |
| 28 | 50 | | ----------- rustdoc does not generate documentation for statements |
| 29 | 51 | | |
| 30 | 52 | = help: use `//` for a plain comment |
| 31 | 53 | |
| 32 | 54 | error: unused doc comment |
| 33 | --> $DIR/useless-comment.rs:16:5 | |
| 55 | --> $DIR/useless-comment.rs:18:5 | |
| 56 | | | |
| 57 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 58 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 59 | LL | let x = 12; | |
| 60 | | ----------- rustdoc does not generate documentation for statements | |
| 61 | | | |
| 62 | = help: use `//` for a plain comment | |
| 63 | ||
| 64 | error: unused doc comment | |
| 65 | --> $DIR/useless-comment.rs:21:5 | |
| 34 | 66 | | |
| 35 | 67 | LL | / /// multi-line |
| 36 | 68 | LL | | /// doc comment |
| ... | ... | @@ -39,6 +71,7 @@ LL | | /// that is unused |
| 39 | 71 | LL | / match x { |
| 40 | 72 | LL | | /// c |
| 41 | 73 | LL | | 1 => {}, |
| 74 | LL | | #[doc(test(attr(allow(dead_code))))] | |
| 42 | 75 | LL | | _ => {} |
| 43 | 76 | LL | | } |
| 44 | 77 | | |_____- rustdoc does not generate documentation for expressions |
| ... | ... | @@ -46,7 +79,7 @@ LL | | } |
| 46 | 79 | = help: use `//` for a plain comment |
| 47 | 80 | |
| 48 | 81 | error: unused doc comment |
| 49 | --> $DIR/useless-comment.rs:20:9 | |
| 82 | --> $DIR/useless-comment.rs:25:9 | |
| 50 | 83 | | |
| 51 | 84 | LL | /// c |
| 52 | 85 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -56,7 +89,17 @@ LL | 1 => {}, |
| 56 | 89 | = help: use `//` for a plain comment |
| 57 | 90 | |
| 58 | 91 | error: unused doc comment |
| 59 | --> $DIR/useless-comment.rs:25:5 | |
| 92 | --> $DIR/useless-comment.rs:27:9 | |
| 93 | | | |
| 94 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 95 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 96 | LL | _ => {} | |
| 97 | | ------- rustdoc does not generate documentation for match arms | |
| 98 | | | |
| 99 | = help: use `//` for a plain comment | |
| 100 | ||
| 101 | error: unused doc comment | |
| 102 | --> $DIR/useless-comment.rs:31:5 | |
| 60 | 103 | | |
| 61 | 104 | LL | /// foo |
| 62 | 105 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -66,7 +109,7 @@ LL | unsafe {} |
| 66 | 109 | = help: use `//` for a plain comment |
| 67 | 110 | |
| 68 | 111 | error: unused doc comment |
| 69 | --> $DIR/useless-comment.rs:28:5 | |
| 112 | --> $DIR/useless-comment.rs:34:5 | |
| 70 | 113 | | |
| 71 | 114 | LL | #[doc = "foo"] |
| 72 | 115 | | ^^^^^^^^^^^^^^ |
| ... | ... | @@ -77,7 +120,7 @@ LL | 3; |
| 77 | 120 | = help: use `//` for a plain comment |
| 78 | 121 | |
| 79 | 122 | error: unused doc comment |
| 80 | --> $DIR/useless-comment.rs:29:5 | |
| 123 | --> $DIR/useless-comment.rs:35:5 | |
| 81 | 124 | | |
| 82 | 125 | LL | #[doc = "bar"] |
| 83 | 126 | | ^^^^^^^^^^^^^^ |
| ... | ... | @@ -87,7 +130,17 @@ LL | 3; |
| 87 | 130 | = help: use `//` for a plain comment |
| 88 | 131 | |
| 89 | 132 | error: unused doc comment |
| 90 | --> $DIR/useless-comment.rs:35:13 | |
| 133 | --> $DIR/useless-comment.rs:41:5 | |
| 134 | | | |
| 135 | LL | #[doc(test(attr(allow(dead_code))))] | |
| 136 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 137 | LL | let x = /** comment */ 47; | |
| 138 | | -------------------------- rustdoc does not generate documentation for statements | |
| 139 | | | |
| 140 | = help: use `//` for a plain comment | |
| 141 | ||
| 142 | error: unused doc comment | |
| 143 | --> $DIR/useless-comment.rs:42:13 | |
| 91 | 144 | | |
| 92 | 145 | LL | let x = /** comment */ 47; |
| 93 | 146 | | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions |
| ... | ... | @@ -95,7 +148,7 @@ LL | let x = /** comment */ 47; |
| 95 | 148 | = help: use `/* */` for a plain comment |
| 96 | 149 | |
| 97 | 150 | error: unused doc comment |
| 98 | --> $DIR/useless-comment.rs:37:5 | |
| 151 | --> $DIR/useless-comment.rs:44:5 | |
| 99 | 152 | | |
| 100 | 153 | LL | /// dox |
| 101 | 154 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -106,5 +159,5 @@ LL | | } |
| 106 | 159 | | |
| 107 | 160 | = help: use `//` for a plain comment |
| 108 | 161 | |
| 109 | error: aborting due to 10 previous errors | |
| 162 | error: aborting due to 15 previous errors | |
| 110 | 163 |
tests/ui/rustdoc/doc-test-attr-pass.rs+42| ... | ... | @@ -6,4 +6,46 @@ |
| 6 | 6 | #![doc(test(attr(deny(warnings))))] |
| 7 | 7 | #![doc(test())] |
| 8 | 8 | |
| 9 | mod test { | |
| 10 | #![doc(test(attr(allow(warnings))))] | |
| 11 | } | |
| 12 | ||
| 13 | #[doc(test(attr(allow(dead_code))))] | |
| 14 | static S: u32 = 5; | |
| 15 | ||
| 16 | #[doc(test(attr(allow(dead_code))))] | |
| 17 | const C: u32 = 5; | |
| 18 | ||
| 19 | #[doc(test(attr(deny(dead_code))))] | |
| 20 | struct A { | |
| 21 | #[doc(test(attr(allow(dead_code))))] | |
| 22 | field: u32 | |
| 23 | } | |
| 24 | ||
| 25 | #[doc(test(attr(deny(dead_code))))] | |
| 26 | union U { | |
| 27 | #[doc(test(attr(allow(dead_code))))] | |
| 28 | field: u32, | |
| 29 | field2: u64, | |
| 30 | } | |
| 31 | ||
| 32 | #[doc(test(attr(deny(dead_code))))] | |
| 33 | enum Enum { | |
| 34 | #[doc(test(attr(allow(dead_code))))] | |
| 35 | Variant1, | |
| 36 | } | |
| 37 | ||
| 38 | #[doc(test(attr(deny(dead_code))))] | |
| 39 | impl A { | |
| 40 | #[doc(test(attr(deny(dead_code))))] | |
| 41 | fn method() {} | |
| 42 | } | |
| 43 | ||
| 44 | #[doc(test(attr(deny(dead_code))))] | |
| 45 | trait MyTrait { | |
| 46 | #[doc(test(attr(deny(dead_code))))] | |
| 47 | fn my_trait_fn(); | |
| 48 | } | |
| 49 | ||
| 50 | #[doc(test(attr(deny(dead_code))))] | |
| 9 | 51 | pub fn foo() {} |
tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | // Regression test for #140571. The compiler used to ICE | |
| 2 | ||
| 3 | #![feature(associated_const_equality, specialization)] | |
| 4 | //~^ WARN the feature `specialization` is incomplete | |
| 5 | ||
| 6 | pub trait IsVoid { | |
| 7 | const IS_VOID: bool; | |
| 8 | } | |
| 9 | impl<T> IsVoid for T { | |
| 10 | default const IS_VOID: bool = false; | |
| 11 | } | |
| 12 | ||
| 13 | pub trait NotVoid {} | |
| 14 | impl<T> NotVoid for T where T: IsVoid<IS_VOID = false> + ?Sized {} | |
| 15 | ||
| 16 | pub trait Maybe<T> {} | |
| 17 | impl<T> Maybe<T> for T {} | |
| 18 | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {} | |
| 19 | //~^ ERROR conflicting implementations of trait `Maybe<()>` for type `()` | |
| 20 | ||
| 21 | fn main() {} |
tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes | |
| 2 | --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39 | |
| 3 | | | |
| 4 | LL | #![feature(associated_const_equality, specialization)] | |
| 5 | | ^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information | |
| 8 | = help: consider using `min_specialization` instead, which is more stable and complete | |
| 9 | = note: `#[warn(incomplete_features)]` on by default | |
| 10 | ||
| 11 | error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()` | |
| 12 | --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:18:1 | |
| 13 | | | |
| 14 | LL | impl<T> Maybe<T> for T {} | |
| 15 | | ---------------------- first implementation here | |
| 16 | LL | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {} | |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` | |
| 18 | ||
| 19 | error: aborting due to 1 previous error; 1 warning emitted | |
| 20 | ||
| 21 | For more information about this error, try `rustc --explain E0119`. |