| author | bors <bors@rust-lang.org> 2026-03-03 07:00:49 UTC |
| committer | bors <bors@rust-lang.org> 2026-03-03 07:00:49 UTC |
| log | 1b7d722f429f09c87b08b757d89c689c6cf7f6e7 |
| tree | 704d494d3e970dcbc3fbd86ea2970a88b25b4e2b |
| parent | d3877ec33269edb7355ef8538d1cc5d157aa1ace |
| parent | cec85ce7321988ca80079947df225f8999de62a6 |
Rollup of 12 pull requests
Successful merges:
- rust-lang/rust#152941 (prefer actual ABI-controling fields over target.abi when making ABI decisions)
- rust-lang/rust#153227 (Don’t report missing fields in struct exprs with syntax errors.)
- rust-lang/rust#153265 (Clarified doc comments + added tests confirming current behavior for intersperse/intersperse_with)
- rust-lang/rust#152966 (Migrate 11 tests from tests/ui/issues to specific directories)
- rust-lang/rust#153003 (rustdoc: make `--emit` and `--out-dir` mimic rustc)
- rust-lang/rust#153034 (Remove unhelpful hint from trivial bound errors)
- rust-lang/rust#153152 (Migration of LintDiagnostic - part 5)
- rust-lang/rust#153177 (disable the ptr_fragment_in_final test on s390x)
- rust-lang/rust#153221 (Add release notes for 1.94.0)
- rust-lang/rust#153279 (feat: Provide an '.item_kind()' method on ItemEnum)
- rust-lang/rust#153297 (Update the name of the Hermit operating system)
- rust-lang/rust#153309 (Cleanup of c-variadic link test)113 files changed, 1743 insertions(+), 1213 deletions(-)
RELEASES.md+115| ... | ... | @@ -1,3 +1,118 @@ |
| 1 | Version 1.94.0 (2026-03-05) | |
| 2 | ========================== | |
| 3 | ||
| 4 | <a id="1.94.0-Language"></a> | |
| 5 | ||
| 6 | Language | |
| 7 | -------- | |
| 8 | - [Impls and impl items inherit `dead_code` lint level of the corresponding traits and trait items](https://github.com/rust-lang/rust/pull/144113) | |
| 9 | - [Stabilize additional 29 RISC-V target features including large portions of the RVA22U64 / RVA23U64 profiles](https://github.com/rust-lang/rust/pull/145948) | |
| 10 | - [Add warn-by-default `unused_visibilities` lint for visibility on `const _` declarations](https://github.com/rust-lang/rust/pull/147136) | |
| 11 | - [Update to Unicode 17](https://github.com/rust-lang/rust/pull/148321) | |
| 12 | - [Avoid incorrect lifetime errors for closures](https://github.com/rust-lang/rust/pull/148329) | |
| 13 | ||
| 14 | <a id="1.94.0-Platform-Support"></a> | |
| 15 | ||
| 16 | Platform Support | |
| 17 | ---------------- | |
| 18 | ||
| 19 | - [Add `riscv64im-unknown-none-elf` as a tier 3 target](https://github.com/rust-lang/rust/pull/148790) | |
| 20 | ||
| 21 | Refer to Rust's [platform support page][platform-support-doc] | |
| 22 | for more information on Rust's tiered platform support. | |
| 23 | ||
| 24 | [platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html | |
| 25 | ||
| 26 | <a id="1.94.0-Libraries"></a> | |
| 27 | ||
| 28 | Libraries | |
| 29 | --------- | |
| 30 | ||
| 31 | - [Relax `T: Ord` bound for some `BinaryHeap<T>` methods.](https://github.com/rust-lang/rust/pull/149408) | |
| 32 | ||
| 33 | <a id="1.94.0-Stabilized-APIs"></a> | |
| 34 | ||
| 35 | Stabilized APIs | |
| 36 | --------------- | |
| 37 | ||
| 38 | - [`<[T]>::array_windows`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.array_windows) | |
| 39 | - [`<[T]>::element_offset`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.element_offset) | |
| 40 | - [`LazyCell::get`](https://doc.rust-lang.org/stable/std/cell/struct.LazyCell.html#method.get) | |
| 41 | - [`LazyCell::get_mut`](https://doc.rust-lang.org/stable/std/cell/struct.LazyCell.html#method.get_mut) | |
| 42 | - [`LazyCell::force_mut`](https://doc.rust-lang.org/stable/std/cell/struct.LazyCell.html#method.force_mut) | |
| 43 | - [`LazyLock::get`](https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html#method.get) | |
| 44 | - [`LazyLock::get_mut`](https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html#method.get_mut) | |
| 45 | - [`LazyLock::force_mut`](https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html#method.force_mut) | |
| 46 | - [`impl TryFrom<char> for usize`](https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html#impl-TryFrom%3Cchar%3E-for-usize) | |
| 47 | - [`std::iter::Peekable::next_if_map`](https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_map) | |
| 48 | - [`std::iter::Peekable::next_if_map_mut`](https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_map_mut) | |
| 49 | - [x86 `avx512fp16` intrinsics](https://github.com/rust-lang/rust/issues/127213) | |
| 50 | (excluding those that depend directly on the unstable `f16` type) | |
| 51 | - [AArch64 NEON fp16 intrinsics](https://github.com/rust-lang/rust/issues/136306) | |
| 52 | (excluding those that depend directly on the unstable `f16` type) | |
| 53 | - [`f32::consts::EULER_GAMMA`](https://doc.rust-lang.org/stable/std/f32/consts/constant.EULER_GAMMA.html) | |
| 54 | - [`f64::consts::EULER_GAMMA`](https://doc.rust-lang.org/stable/std/f64/consts/constant.EULER_GAMMA.html) | |
| 55 | - [`f32::consts::GOLDEN_RATIO`](https://doc.rust-lang.org/stable/std/f32/consts/constant.GOLDEN_RATIO.html) | |
| 56 | - [`f64::consts::GOLDEN_RATIO`](https://doc.rust-lang.org/stable/std/f64/consts/constant.GOLDEN_RATIO.html) | |
| 57 | ||
| 58 | ||
| 59 | These previously stable APIs are now stable in const contexts: | |
| 60 | ||
| 61 | - [`f32::mul_add`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.mul_add) | |
| 62 | - [`f64::mul_add`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.mul_add) | |
| 63 | ||
| 64 | ||
| 65 | <a id="1.94.0-Cargo"></a> | |
| 66 | ||
| 67 | Cargo | |
| 68 | ----- | |
| 69 | ||
| 70 | - Stabilize the config include key. The top-level include config key allows loading additional config files, enabling better organization, sharing, and management of Cargo configurations across projects and environments. [docs](https://doc.rust-lang.org/nightly/cargo/reference/config.html#including-extra-configuration-files) [#16284](https://github.com/rust-lang/cargo/pull/16284) | |
| 71 | - Stabilize the pubtime field in registry index. This records when a crate version was published and enables time-based dependency resolution in the future. Note that crates.io will gradually backfill existing packages when a new version is published. Not all crates have pubtime yet. [#16369](https://github.com/rust-lang/cargo/pull/16369) [#16372](https://github.com/rust-lang/cargo/pull/16372) | |
| 72 | - Cargo now parses [TOML v1.1](https://toml.io/en/v1.1.0) for manifests and configuration files. Note that using these features in Cargo.toml will raise your development MSRV, but the published manifest remains compatible with older parsers. [#16415](https://github.com/rust-lang/cargo/pull/16415) | |
| 73 | - [Make `CARGO_BIN_EXE_<crate>` available at runtime ](https://github.com/rust-lang/cargo/pull/16421/) | |
| 74 | ||
| 75 | <a id="1.94.0-Compatibility-Notes"></a> | |
| 76 | ||
| 77 | Compatibility Notes | |
| 78 | ------------------- | |
| 79 | - [Forbid freely casting lifetime bounds of `dyn`-types](https://github.com/rust-lang/rust/pull/136776) | |
| 80 | - [Make closure capturing have consistent and correct behaviour around patterns](https://github.com/rust-lang/rust/pull/138961) | |
| 81 | Some finer details of how precise closure captures get affected by pattern matching have been changed. In some cases, this can cause a non-move closure that was previously capturing an entire variable by move, to now capture only part of that variable by move, and other parts by borrow. This can cause the borrow checker to complain where it previously didn't, or cause `Drop` to run at a different point in time. | |
| 82 | - [Standard library macros are now imported via prelude, not via injected `#[macro_use]`](https://github.com/rust-lang/rust/pull/139493) | |
| 83 | This will raise an error if macros of the same name are glob imported. | |
| 84 | For example if a crate defines their own `matches` macro and then glob imports that, | |
| 85 | it's now ambiguous whether the custom or standard library `matches` is meant and | |
| 86 | an explicit import of the name is required to resolve the ambiguity. | |
| 87 | One exception is `core::panic` and `std::panic`, if their import is ambiguous | |
| 88 | a new warning ([`ambiguous_panic_imports`](https://github.com/rust-lang/rust/issues/147319)) is raised. | |
| 89 | This may raise a new warning ([`ambiguous_panic_imports`](https://github.com/rust-lang/rust/issues/147319)) on `#![no_std]` code glob importing the std crate. | |
| 90 | Both `core::panic!` and `std::panic!` are then in scope and which is used is ambiguous. | |
| 91 | - [Don't strip shebang in expression-context `include!(…)`s](https://github.com/rust-lang/rust/pull/146377) | |
| 92 | This can cause previously working includes to no longer compile if they included files which started with a shebang. | |
| 93 | - [Ambiguous glob reexports are now also visible cross-crate](https://github.com/rust-lang/rust/pull/147984) | |
| 94 | This unifies behavior between local and cross-crate errors on these exports, which may introduce new ambiguity errors. | |
| 95 | - [Don't normalize where-clauses before checking well-formedness](https://github.com/rust-lang/rust/pull/148477) | |
| 96 | - [Introduce a future compatibility warning on codegen attributes on body-free trait methods](https://github.com/rust-lang/rust/pull/148756) | |
| 97 | These attributes currently have no effect in this position. | |
| 98 | - [On Windows `std::time::SystemTime::checked_sub_duration` will return `None` for times before the Windows epoch (1/1/1601)](https://github.com/rust-lang/rust/pull/148825) | |
| 99 | - [Lifetime identifiers such as `'a` are now NFC normalized](https://github.com/rust-lang/rust/pull/149192). | |
| 100 | - [Overhaul filename handling for cross-compiler consistency](https://github.com/rust-lang/rust/pull/149709) | |
| 101 | Any paths emitted by compiler now always respect the relative-ness of the paths and `--remap-path-prefix` given originally. | |
| 102 | One side-effect of this change is that paths emitted for local crates in Cargo (path dependencies and workspace members) are no longer absolute but relative when emitted as part of a diagnostic in a downstream crate. | |
| 103 | ||
| 104 | <a id="1.94.0-Internal-Changes"></a> | |
| 105 | ||
| 106 | Internal Changes | |
| 107 | ---------------- | |
| 108 | ||
| 109 | These changes do not affect any public interfaces of Rust, but they represent | |
| 110 | significant improvements to the performance or internals of rustc and related | |
| 111 | tools. | |
| 112 | ||
| 113 | - [Switch to `annotate-snippets` for error emission](https://github.com/rust-lang/rust/pull/150032) | |
| 114 | This should preserve mostly the same outputs in rustc error messages. | |
| 115 | ||
| 1 | 116 | Version 1.93.1 (2026-02-12) |
| 2 | 117 | =========================== |
| 3 | 118 |
compiler/rustc_ast/src/ast.rs+6| ... | ... | @@ -1724,6 +1724,12 @@ pub enum StructRest { |
| 1724 | 1724 | Rest(Span), |
| 1725 | 1725 | /// No trailing `..` or expression. |
| 1726 | 1726 | None, |
| 1727 | /// No trailing `..` or expression, and also, a parse error occurred inside the struct braces. | |
| 1728 | /// | |
| 1729 | /// This struct should be treated similarly to as if it had an `..` in it, | |
| 1730 | /// in particular rather than reporting missing fields, because the parse error | |
| 1731 | /// makes which fields the struct was intended to have not fully known. | |
| 1732 | NoneWithError(ErrorGuaranteed), | |
| 1727 | 1733 | } |
| 1728 | 1734 | |
| 1729 | 1735 | #[derive(Clone, Encodable, Decodable, Debug, Walkable)] |
compiler/rustc_ast_lowering/src/expr.rs+5-4| ... | ... | @@ -340,12 +340,13 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 340 | 340 | self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))), |
| 341 | 341 | ), |
| 342 | 342 | ExprKind::Struct(se) => { |
| 343 | let rest = match &se.rest { | |
| 344 | StructRest::Base(e) => hir::StructTailExpr::Base(self.lower_expr(e)), | |
| 343 | let rest = match se.rest { | |
| 344 | StructRest::Base(ref e) => hir::StructTailExpr::Base(self.lower_expr(e)), | |
| 345 | 345 | StructRest::Rest(sp) => { |
| 346 | hir::StructTailExpr::DefaultFields(self.lower_span(*sp)) | |
| 346 | hir::StructTailExpr::DefaultFields(self.lower_span(sp)) | |
| 347 | 347 | } |
| 348 | 348 | StructRest::None => hir::StructTailExpr::None, |
| 349 | StructRest::NoneWithError(guar) => hir::StructTailExpr::NoneWithError(guar), | |
| 349 | 350 | }; |
| 350 | 351 | hir::ExprKind::Struct( |
| 351 | 352 | self.arena.alloc(self.lower_qpath( |
| ... | ... | @@ -1435,7 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1435 | 1436 | Some(self.lower_span(e.span)) |
| 1436 | 1437 | } |
| 1437 | 1438 | StructRest::Rest(span) => Some(self.lower_span(*span)), |
| 1438 | StructRest::None => None, | |
| 1439 | StructRest::None | StructRest::NoneWithError(_) => None, | |
| 1439 | 1440 | }; |
| 1440 | 1441 | let struct_pat = hir::PatKind::Struct(qpath, field_pats, fields_omitted); |
| 1441 | 1442 | return self.pat_without_dbm(lhs.span, struct_pat); |
compiler/rustc_ast_pretty/src/pprust/state/expr.rs+1-1| ... | ... | @@ -162,7 +162,7 @@ impl<'a> State<'a> { |
| 162 | 162 | self.word("{"); |
| 163 | 163 | let has_rest = match rest { |
| 164 | 164 | ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true, |
| 165 | ast::StructRest::None => false, | |
| 165 | ast::StructRest::None | ast::StructRest::NoneWithError(_) => false, | |
| 166 | 166 | }; |
| 167 | 167 | if fields.is_empty() && !has_rest { |
| 168 | 168 | self.word("}"); |
compiler/rustc_codegen_llvm/src/va_arg.rs+3-3| ... | ... | @@ -8,7 +8,7 @@ use rustc_codegen_ssa::traits::{ |
| 8 | 8 | use rustc_middle::bug; |
| 9 | 9 | use rustc_middle::ty::Ty; |
| 10 | 10 | use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; |
| 11 | use rustc_target::spec::{Abi, Arch, Env}; | |
| 11 | use rustc_target::spec::{Arch, Env, RustcAbi}; | |
| 12 | 12 | |
| 13 | 13 | use crate::builder::Builder; |
| 14 | 14 | use crate::llvm::{Type, Value}; |
| ... | ... | @@ -272,7 +272,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( |
| 272 | 272 | |
| 273 | 273 | // Rust does not currently support any powerpc softfloat targets. |
| 274 | 274 | let target = &bx.cx.tcx.sess.target; |
| 275 | let is_soft_float_abi = target.abi == Abi::SoftFloat; | |
| 275 | let is_soft_float_abi = target.rustc_abi == Some(RustcAbi::Softfloat); | |
| 276 | 276 | assert!(!is_soft_float_abi); |
| 277 | 277 | |
| 278 | 278 | // All instances of VaArgSafe are passed directly. |
| ... | ... | @@ -1077,7 +1077,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( |
| 1077 | 1077 | AllowHigherAlign::Yes, |
| 1078 | 1078 | ForceRightAdjust::Yes, |
| 1079 | 1079 | ), |
| 1080 | Arch::RiscV32 if target.abi == Abi::Ilp32e => { | |
| 1080 | Arch::RiscV32 if target.llvm_abiname == "ilp32e" => { | |
| 1081 | 1081 | // FIXME: clang manually adjusts the alignment for this ABI. It notes: |
| 1082 | 1082 | // |
| 1083 | 1083 | // > To be compatible with GCC's behaviors, we force arguments with |
compiler/rustc_hir/src/hir.rs+9-1| ... | ... | @@ -2662,7 +2662,9 @@ impl Expr<'_> { |
| 2662 | 2662 | ExprKind::Struct(_, fields, init) => { |
| 2663 | 2663 | let init_side_effects = match init { |
| 2664 | 2664 | StructTailExpr::Base(init) => init.can_have_side_effects(), |
| 2665 | StructTailExpr::DefaultFields(_) | StructTailExpr::None => false, | |
| 2665 | StructTailExpr::DefaultFields(_) | |
| 2666 | | StructTailExpr::None | |
| 2667 | | StructTailExpr::NoneWithError(_) => false, | |
| 2666 | 2668 | }; |
| 2667 | 2669 | fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects()) |
| 2668 | 2670 | || init_side_effects |
| ... | ... | @@ -2954,6 +2956,12 @@ pub enum StructTailExpr<'hir> { |
| 2954 | 2956 | /// fields' default values will be used to populate any fields not explicitly mentioned: |
| 2955 | 2957 | /// `Foo { .. }`. |
| 2956 | 2958 | DefaultFields(Span), |
| 2959 | /// No trailing `..` was written, and also, a parse error occurred inside the struct braces. | |
| 2960 | /// | |
| 2961 | /// This struct should be treated similarly to as if it had an `..` in it, | |
| 2962 | /// in particular rather than reporting missing fields, because the parse error | |
| 2963 | /// makes which fields the struct was intended to have not fully known. | |
| 2964 | NoneWithError(ErrorGuaranteed), | |
| 2957 | 2965 | } |
| 2958 | 2966 | |
| 2959 | 2967 | /// Represents an optionally `Self`-qualified value/type path or associated extension. |
compiler/rustc_hir/src/intravisit.rs+3-1| ... | ... | @@ -830,7 +830,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) |
| 830 | 830 | walk_list!(visitor, visit_expr_field, fields); |
| 831 | 831 | match optional_base { |
| 832 | 832 | StructTailExpr::Base(base) => try_visit!(visitor.visit_expr(base)), |
| 833 | StructTailExpr::None | StructTailExpr::DefaultFields(_) => {} | |
| 833 | StructTailExpr::None | |
| 834 | | StructTailExpr::NoneWithError(_) | |
| 835 | | StructTailExpr::DefaultFields(_) => {} | |
| 834 | 836 | } |
| 835 | 837 | } |
| 836 | 838 | ExprKind::Tup(subexpressions) => { |
compiler/rustc_hir_analysis/src/lib.rs+7-9| ... | ... | @@ -88,6 +88,7 @@ use rustc_abi::{CVariadicStatus, ExternAbi}; |
| 88 | 88 | use rustc_hir as hir; |
| 89 | 89 | use rustc_hir::def::DefKind; |
| 90 | 90 | use rustc_hir::lints::DelayedLint; |
| 91 | use rustc_lint::DecorateAttrLint; | |
| 91 | 92 | use rustc_middle::mir::interpret::GlobalId; |
| 92 | 93 | use rustc_middle::query::Providers; |
| 93 | 94 | use rustc_middle::ty::{Const, Ty, TyCtxt}; |
| ... | ... | @@ -148,20 +149,17 @@ pub fn provide(providers: &mut Providers) { |
| 148 | 149 | }; |
| 149 | 150 | } |
| 150 | 151 | |
| 151 | fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { | |
| 152 | pub fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { | |
| 152 | 153 | match lint { |
| 153 | 154 | DelayedLint::AttributeParsing(attribute_lint) => { |
| 154 | tcx.node_span_lint( | |
| 155 | tcx.emit_node_span_lint( | |
| 155 | 156 | attribute_lint.lint_id.lint, |
| 156 | 157 | attribute_lint.id, |
| 157 | 158 | attribute_lint.span, |
| 158 | |diag| { | |
| 159 | rustc_lint::decorate_attribute_lint( | |
| 160 | tcx.sess, | |
| 161 | Some(tcx), | |
| 162 | &attribute_lint.kind, | |
| 163 | diag, | |
| 164 | ); | |
| 159 | DecorateAttrLint { | |
| 160 | sess: tcx.sess, | |
| 161 | tcx: Some(tcx), | |
| 162 | diagnostic: &attribute_lint.kind, | |
| 165 | 163 | }, |
| 166 | 164 | ); |
| 167 | 165 | } |
compiler/rustc_hir_pretty/src/lib.rs+1| ... | ... | @@ -1314,6 +1314,7 @@ impl<'a> State<'a> { |
| 1314 | 1314 | self.end(ib); |
| 1315 | 1315 | } |
| 1316 | 1316 | hir::StructTailExpr::None => {} |
| 1317 | hir::StructTailExpr::NoneWithError(_) => {} | |
| 1317 | 1318 | } |
| 1318 | 1319 | self.space(); |
| 1319 | 1320 | self.word("}"); |
compiler/rustc_hir_typeck/src/expr.rs+232-205| ... | ... | @@ -2000,229 +2000,256 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2000 | 2000 | return; |
| 2001 | 2001 | } |
| 2002 | 2002 | |
| 2003 | if let hir::StructTailExpr::DefaultFields(span) = *base_expr { | |
| 2004 | let mut missing_mandatory_fields = Vec::new(); | |
| 2005 | let mut missing_optional_fields = Vec::new(); | |
| 2006 | for f in &variant.fields { | |
| 2007 | let ident = self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); | |
| 2008 | if let Some(_) = remaining_fields.remove(&ident) { | |
| 2009 | if f.value.is_none() { | |
| 2010 | missing_mandatory_fields.push(ident); | |
| 2011 | } else { | |
| 2012 | missing_optional_fields.push(ident); | |
| 2003 | match *base_expr { | |
| 2004 | hir::StructTailExpr::DefaultFields(span) => { | |
| 2005 | let mut missing_mandatory_fields = Vec::new(); | |
| 2006 | let mut missing_optional_fields = Vec::new(); | |
| 2007 | for f in &variant.fields { | |
| 2008 | let ident = self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); | |
| 2009 | if let Some(_) = remaining_fields.remove(&ident) { | |
| 2010 | if f.value.is_none() { | |
| 2011 | missing_mandatory_fields.push(ident); | |
| 2012 | } else { | |
| 2013 | missing_optional_fields.push(ident); | |
| 2014 | } | |
| 2013 | 2015 | } |
| 2014 | 2016 | } |
| 2015 | } | |
| 2016 | if !self.tcx.features().default_field_values() { | |
| 2017 | let sugg = self.tcx.crate_level_attribute_injection_span(); | |
| 2018 | self.dcx().emit_err(BaseExpressionDoubleDot { | |
| 2019 | span: span.shrink_to_hi(), | |
| 2020 | // We only mention enabling the feature if this is a nightly rustc *and* the | |
| 2021 | // expression would make sense with the feature enabled. | |
| 2022 | default_field_values_suggestion: if self.tcx.sess.is_nightly_build() | |
| 2023 | && missing_mandatory_fields.is_empty() | |
| 2024 | && !missing_optional_fields.is_empty() | |
| 2025 | { | |
| 2026 | Some(sugg) | |
| 2027 | } else { | |
| 2028 | None | |
| 2029 | }, | |
| 2030 | add_expr: if !missing_mandatory_fields.is_empty() | |
| 2031 | || !missing_optional_fields.is_empty() | |
| 2032 | { | |
| 2033 | Some(BaseExpressionDoubleDotAddExpr { span: span.shrink_to_hi() }) | |
| 2034 | } else { | |
| 2035 | None | |
| 2036 | }, | |
| 2037 | remove_dots: if missing_mandatory_fields.is_empty() | |
| 2038 | && missing_optional_fields.is_empty() | |
| 2039 | { | |
| 2040 | Some(BaseExpressionDoubleDotRemove { span }) | |
| 2041 | } else { | |
| 2042 | None | |
| 2043 | }, | |
| 2044 | }); | |
| 2045 | return; | |
| 2046 | } | |
| 2047 | if variant.fields.is_empty() { | |
| 2048 | let mut err = self.dcx().struct_span_err( | |
| 2049 | span, | |
| 2050 | format!( | |
| 2051 | "`{adt_ty}` has no fields, `..` needs at least one default field in the \ | |
| 2052 | struct definition", | |
| 2053 | ), | |
| 2054 | ); | |
| 2055 | err.span_label(path_span, "this type has no fields"); | |
| 2056 | err.emit(); | |
| 2057 | } | |
| 2058 | if !missing_mandatory_fields.is_empty() { | |
| 2059 | let s = pluralize!(missing_mandatory_fields.len()); | |
| 2060 | let fields = listify(&missing_mandatory_fields, |f| format!("`{f}`")).unwrap(); | |
| 2061 | self.dcx() | |
| 2062 | .struct_span_err( | |
| 2063 | span.shrink_to_lo(), | |
| 2064 | format!("missing field{s} {fields} in initializer"), | |
| 2065 | ) | |
| 2066 | .with_span_label( | |
| 2067 | span.shrink_to_lo(), | |
| 2068 | "fields that do not have a defaulted value must be provided explicitly", | |
| 2069 | ) | |
| 2070 | .emit(); | |
| 2071 | return; | |
| 2072 | } | |
| 2073 | let fru_tys = match adt_ty.kind() { | |
| 2074 | ty::Adt(adt, args) if adt.is_struct() => variant | |
| 2075 | .fields | |
| 2076 | .iter() | |
| 2077 | .map(|f| self.normalize(span, f.ty(self.tcx, args))) | |
| 2078 | .collect(), | |
| 2079 | ty::Adt(adt, args) if adt.is_enum() => variant | |
| 2080 | .fields | |
| 2081 | .iter() | |
| 2082 | .map(|f| self.normalize(span, f.ty(self.tcx, args))) | |
| 2083 | .collect(), | |
| 2084 | _ => { | |
| 2085 | self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span }); | |
| 2017 | if !self.tcx.features().default_field_values() { | |
| 2018 | let sugg = self.tcx.crate_level_attribute_injection_span(); | |
| 2019 | self.dcx().emit_err(BaseExpressionDoubleDot { | |
| 2020 | span: span.shrink_to_hi(), | |
| 2021 | // We only mention enabling the feature if this is a nightly rustc *and* the | |
| 2022 | // expression would make sense with the feature enabled. | |
| 2023 | default_field_values_suggestion: if self.tcx.sess.is_nightly_build() | |
| 2024 | && missing_mandatory_fields.is_empty() | |
| 2025 | && !missing_optional_fields.is_empty() | |
| 2026 | { | |
| 2027 | Some(sugg) | |
| 2028 | } else { | |
| 2029 | None | |
| 2030 | }, | |
| 2031 | add_expr: if !missing_mandatory_fields.is_empty() | |
| 2032 | || !missing_optional_fields.is_empty() | |
| 2033 | { | |
| 2034 | Some(BaseExpressionDoubleDotAddExpr { span: span.shrink_to_hi() }) | |
| 2035 | } else { | |
| 2036 | None | |
| 2037 | }, | |
| 2038 | remove_dots: if missing_mandatory_fields.is_empty() | |
| 2039 | && missing_optional_fields.is_empty() | |
| 2040 | { | |
| 2041 | Some(BaseExpressionDoubleDotRemove { span }) | |
| 2042 | } else { | |
| 2043 | None | |
| 2044 | }, | |
| 2045 | }); | |
| 2086 | 2046 | return; |
| 2087 | 2047 | } |
| 2088 | }; | |
| 2089 | self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); | |
| 2090 | } else if let hir::StructTailExpr::Base(base_expr) = base_expr { | |
| 2091 | // FIXME: We are currently creating two branches here in order to maintain | |
| 2092 | // consistency. But they should be merged as much as possible. | |
| 2093 | let fru_tys = if self.tcx.features().type_changing_struct_update() { | |
| 2094 | if adt.is_struct() { | |
| 2095 | // Make some fresh generic parameters for our ADT type. | |
| 2096 | let fresh_args = self.fresh_args_for_item(base_expr.span, adt.did()); | |
| 2097 | // We do subtyping on the FRU fields first, so we can | |
| 2098 | // learn exactly what types we expect the base expr | |
| 2099 | // needs constrained to be compatible with the struct | |
| 2100 | // type we expect from the expectation value. | |
| 2101 | let fru_tys = variant | |
| 2102 | .fields | |
| 2103 | .iter() | |
| 2104 | .map(|f| { | |
| 2105 | let fru_ty = self | |
| 2106 | .normalize(expr.span, self.field_ty(base_expr.span, f, fresh_args)); | |
| 2107 | let ident = self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); | |
| 2108 | if let Some(_) = remaining_fields.remove(&ident) { | |
| 2109 | let target_ty = self.field_ty(base_expr.span, f, args); | |
| 2110 | let cause = self.misc(base_expr.span); | |
| 2111 | match self.at(&cause, self.param_env).sup( | |
| 2112 | // We're already using inference variables for any params, and don't allow converting | |
| 2113 | // between different structs, so there is no way this ever actually defines an opaque type. | |
| 2114 | // Thus choosing `Yes` is fine. | |
| 2115 | DefineOpaqueTypes::Yes, | |
| 2116 | target_ty, | |
| 2117 | fru_ty, | |
| 2118 | ) { | |
| 2119 | Ok(InferOk { obligations, value: () }) => { | |
| 2120 | self.register_predicates(obligations) | |
| 2121 | } | |
| 2122 | Err(_) => { | |
| 2123 | span_bug!( | |
| 2124 | cause.span, | |
| 2125 | "subtyping remaining fields of type changing FRU failed: {target_ty} != {fru_ty}: {}::{}", | |
| 2126 | variant.name, | |
| 2127 | ident.name, | |
| 2128 | ); | |
| 2129 | } | |
| 2130 | } | |
| 2131 | } | |
| 2132 | self.resolve_vars_if_possible(fru_ty) | |
| 2133 | }) | |
| 2134 | .collect(); | |
| 2135 | // The use of fresh args that we have subtyped against | |
| 2136 | // our base ADT type's fields allows us to guide inference | |
| 2137 | // along so that, e.g. | |
| 2138 | // ``` | |
| 2139 | // MyStruct<'a, F1, F2, const C: usize> { | |
| 2140 | // f: F1, | |
| 2141 | // // Other fields that reference `'a`, `F2`, and `C` | |
| 2142 | // } | |
| 2143 | // | |
| 2144 | // let x = MyStruct { | |
| 2145 | // f: 1usize, | |
| 2146 | // ..other_struct | |
| 2147 | // }; | |
| 2148 | // ``` | |
| 2149 | // will have the `other_struct` expression constrained to | |
| 2150 | // `MyStruct<'a, _, F2, C>`, as opposed to just `_`... | |
| 2151 | // This is important to allow coercions to happen in | |
| 2152 | // `other_struct` itself. See `coerce-in-base-expr.rs`. | |
| 2153 | let fresh_base_ty = Ty::new_adt(self.tcx, *adt, fresh_args); | |
| 2154 | self.check_expr_has_type_or_error( | |
| 2155 | base_expr, | |
| 2156 | self.resolve_vars_if_possible(fresh_base_ty), | |
| 2157 | |_| {}, | |
| 2048 | if variant.fields.is_empty() { | |
| 2049 | let mut err = self.dcx().struct_span_err( | |
| 2050 | span, | |
| 2051 | format!( | |
| 2052 | "`{adt_ty}` has no fields, `..` needs at least one default field in \ | |
| 2053 | the struct definition", | |
| 2054 | ), | |
| 2158 | 2055 | ); |
| 2159 | fru_tys | |
| 2160 | } else { | |
| 2161 | // Check the base_expr, regardless of a bad expected adt_ty, so we can get | |
| 2162 | // type errors on that expression, too. | |
| 2163 | self.check_expr(base_expr); | |
| 2164 | self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span }); | |
| 2165 | return; | |
| 2056 | err.span_label(path_span, "this type has no fields"); | |
| 2057 | err.emit(); | |
| 2166 | 2058 | } |
| 2167 | } else { | |
| 2168 | self.check_expr_has_type_or_error(base_expr, adt_ty, |_| { | |
| 2169 | let base_ty = self.typeck_results.borrow().expr_ty(*base_expr); | |
| 2170 | let same_adt = matches!((adt_ty.kind(), base_ty.kind()), | |
| 2171 | (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt); | |
| 2172 | if self.tcx.sess.is_nightly_build() && same_adt { | |
| 2173 | feature_err( | |
| 2174 | &self.tcx.sess, | |
| 2175 | sym::type_changing_struct_update, | |
| 2176 | base_expr.span, | |
| 2177 | "type changing struct updating is experimental", | |
| 2059 | if !missing_mandatory_fields.is_empty() { | |
| 2060 | let s = pluralize!(missing_mandatory_fields.len()); | |
| 2061 | let fields = listify(&missing_mandatory_fields, |f| format!("`{f}`")).unwrap(); | |
| 2062 | self.dcx() | |
| 2063 | .struct_span_err( | |
| 2064 | span.shrink_to_lo(), | |
| 2065 | format!("missing field{s} {fields} in initializer"), | |
| 2066 | ) | |
| 2067 | .with_span_label( | |
| 2068 | span.shrink_to_lo(), | |
| 2069 | "fields that do not have a defaulted value must be provided explicitly", | |
| 2178 | 2070 | ) |
| 2179 | 2071 | .emit(); |
| 2180 | } | |
| 2181 | }); | |
| 2182 | match adt_ty.kind() { | |
| 2072 | return; | |
| 2073 | } | |
| 2074 | let fru_tys = match adt_ty.kind() { | |
| 2183 | 2075 | ty::Adt(adt, args) if adt.is_struct() => variant |
| 2184 | 2076 | .fields |
| 2185 | 2077 | .iter() |
| 2186 | .map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) | |
| 2078 | .map(|f| self.normalize(span, f.ty(self.tcx, args))) | |
| 2079 | .collect(), | |
| 2080 | ty::Adt(adt, args) if adt.is_enum() => variant | |
| 2081 | .fields | |
| 2082 | .iter() | |
| 2083 | .map(|f| self.normalize(span, f.ty(self.tcx, args))) | |
| 2187 | 2084 | .collect(), |
| 2188 | 2085 | _ => { |
| 2086 | self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span }); | |
| 2087 | return; | |
| 2088 | } | |
| 2089 | }; | |
| 2090 | self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); | |
| 2091 | } | |
| 2092 | hir::StructTailExpr::Base(base_expr) => { | |
| 2093 | // FIXME: We are currently creating two branches here in order to maintain | |
| 2094 | // consistency. But they should be merged as much as possible. | |
| 2095 | let fru_tys = if self.tcx.features().type_changing_struct_update() { | |
| 2096 | if adt.is_struct() { | |
| 2097 | // Make some fresh generic parameters for our ADT type. | |
| 2098 | let fresh_args = self.fresh_args_for_item(base_expr.span, adt.did()); | |
| 2099 | // We do subtyping on the FRU fields first, so we can | |
| 2100 | // learn exactly what types we expect the base expr | |
| 2101 | // needs constrained to be compatible with the struct | |
| 2102 | // type we expect from the expectation value. | |
| 2103 | let fru_tys = variant | |
| 2104 | .fields | |
| 2105 | .iter() | |
| 2106 | .map(|f| { | |
| 2107 | let fru_ty = self.normalize( | |
| 2108 | expr.span, | |
| 2109 | self.field_ty(base_expr.span, f, fresh_args), | |
| 2110 | ); | |
| 2111 | let ident = | |
| 2112 | self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); | |
| 2113 | if let Some(_) = remaining_fields.remove(&ident) { | |
| 2114 | let target_ty = self.field_ty(base_expr.span, f, args); | |
| 2115 | let cause = self.misc(base_expr.span); | |
| 2116 | match self.at(&cause, self.param_env).sup( | |
| 2117 | // We're already using inference variables for any params, | |
| 2118 | // and don't allow converting between different structs, | |
| 2119 | // so there is no way this ever actually defines an opaque | |
| 2120 | // type. Thus choosing `Yes` is fine. | |
| 2121 | DefineOpaqueTypes::Yes, | |
| 2122 | target_ty, | |
| 2123 | fru_ty, | |
| 2124 | ) { | |
| 2125 | Ok(InferOk { obligations, value: () }) => { | |
| 2126 | self.register_predicates(obligations) | |
| 2127 | } | |
| 2128 | Err(_) => { | |
| 2129 | span_bug!( | |
| 2130 | cause.span, | |
| 2131 | "subtyping remaining fields of type changing FRU \ | |
| 2132 | failed: {target_ty} != {fru_ty}: {}::{}", | |
| 2133 | variant.name, | |
| 2134 | ident.name, | |
| 2135 | ); | |
| 2136 | } | |
| 2137 | } | |
| 2138 | } | |
| 2139 | self.resolve_vars_if_possible(fru_ty) | |
| 2140 | }) | |
| 2141 | .collect(); | |
| 2142 | // The use of fresh args that we have subtyped against | |
| 2143 | // our base ADT type's fields allows us to guide inference | |
| 2144 | // along so that, e.g. | |
| 2145 | // ``` | |
| 2146 | // MyStruct<'a, F1, F2, const C: usize> { | |
| 2147 | // f: F1, | |
| 2148 | // // Other fields that reference `'a`, `F2`, and `C` | |
| 2149 | // } | |
| 2150 | // | |
| 2151 | // let x = MyStruct { | |
| 2152 | // f: 1usize, | |
| 2153 | // ..other_struct | |
| 2154 | // }; | |
| 2155 | // ``` | |
| 2156 | // will have the `other_struct` expression constrained to | |
| 2157 | // `MyStruct<'a, _, F2, C>`, as opposed to just `_`... | |
| 2158 | // This is important to allow coercions to happen in | |
| 2159 | // `other_struct` itself. See `coerce-in-base-expr.rs`. | |
| 2160 | let fresh_base_ty = Ty::new_adt(self.tcx, *adt, fresh_args); | |
| 2161 | self.check_expr_has_type_or_error( | |
| 2162 | base_expr, | |
| 2163 | self.resolve_vars_if_possible(fresh_base_ty), | |
| 2164 | |_| {}, | |
| 2165 | ); | |
| 2166 | fru_tys | |
| 2167 | } else { | |
| 2168 | // Check the base_expr, regardless of a bad expected adt_ty, so we can get | |
| 2169 | // type errors on that expression, too. | |
| 2170 | self.check_expr(base_expr); | |
| 2189 | 2171 | self.dcx() |
| 2190 | 2172 | .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span }); |
| 2191 | 2173 | return; |
| 2192 | 2174 | } |
| 2175 | } else { | |
| 2176 | self.check_expr_has_type_or_error(base_expr, adt_ty, |_| { | |
| 2177 | let base_ty = self.typeck_results.borrow().expr_ty(base_expr); | |
| 2178 | let same_adt = matches!((adt_ty.kind(), base_ty.kind()), | |
| 2179 | (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt); | |
| 2180 | if self.tcx.sess.is_nightly_build() && same_adt { | |
| 2181 | feature_err( | |
| 2182 | &self.tcx.sess, | |
| 2183 | sym::type_changing_struct_update, | |
| 2184 | base_expr.span, | |
| 2185 | "type changing struct updating is experimental", | |
| 2186 | ) | |
| 2187 | .emit(); | |
| 2188 | } | |
| 2189 | }); | |
| 2190 | match adt_ty.kind() { | |
| 2191 | ty::Adt(adt, args) if adt.is_struct() => variant | |
| 2192 | .fields | |
| 2193 | .iter() | |
| 2194 | .map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) | |
| 2195 | .collect(), | |
| 2196 | _ => { | |
| 2197 | self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { | |
| 2198 | span: base_expr.span, | |
| 2199 | }); | |
| 2200 | return; | |
| 2201 | } | |
| 2202 | } | |
| 2203 | }; | |
| 2204 | self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); | |
| 2205 | } | |
| 2206 | rustc_hir::StructTailExpr::NoneWithError(ErrorGuaranteed { .. }) => { | |
| 2207 | // If parsing the struct recovered from a syntax error, do not report missing | |
| 2208 | // fields. This prevents spurious errors when a field is intended to be present | |
| 2209 | // but a preceding syntax error caused it not to be parsed. For example, if a | |
| 2210 | // struct type `StructName` has fields `foo` and `bar`, then | |
| 2211 | // StructName { foo(), bar: 2 } | |
| 2212 | // will not successfully parse a field `foo`, but we will not mention that, | |
| 2213 | // since the syntax error has already been reported. | |
| 2214 | } | |
| 2215 | rustc_hir::StructTailExpr::None => { | |
| 2216 | if adt_kind != AdtKind::Union | |
| 2217 | && !remaining_fields.is_empty() | |
| 2218 | //~ non_exhaustive already reported, which will only happen for extern modules | |
| 2219 | && !variant.field_list_has_applicable_non_exhaustive() | |
| 2220 | { | |
| 2221 | debug!(?remaining_fields); | |
| 2222 | ||
| 2223 | // Report missing fields. | |
| 2224 | ||
| 2225 | let private_fields: Vec<&ty::FieldDef> = variant | |
| 2226 | .fields | |
| 2227 | .iter() | |
| 2228 | .filter(|field| { | |
| 2229 | !field.vis.is_accessible_from(tcx.parent_module(expr.hir_id), tcx) | |
| 2230 | }) | |
| 2231 | .collect(); | |
| 2232 | ||
| 2233 | if !private_fields.is_empty() { | |
| 2234 | self.report_private_fields( | |
| 2235 | adt_ty, | |
| 2236 | path_span, | |
| 2237 | expr.span, | |
| 2238 | private_fields, | |
| 2239 | hir_fields, | |
| 2240 | ); | |
| 2241 | } else { | |
| 2242 | self.report_missing_fields( | |
| 2243 | adt_ty, | |
| 2244 | path_span, | |
| 2245 | expr.span, | |
| 2246 | remaining_fields, | |
| 2247 | variant, | |
| 2248 | hir_fields, | |
| 2249 | args, | |
| 2250 | ); | |
| 2251 | } | |
| 2193 | 2252 | } |
| 2194 | }; | |
| 2195 | self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); | |
| 2196 | } else if adt_kind != AdtKind::Union | |
| 2197 | && !remaining_fields.is_empty() | |
| 2198 | //~ non_exhaustive already reported, which will only happen for extern modules | |
| 2199 | && !variant.field_list_has_applicable_non_exhaustive() | |
| 2200 | { | |
| 2201 | debug!(?remaining_fields); | |
| 2202 | let private_fields: Vec<&ty::FieldDef> = variant | |
| 2203 | .fields | |
| 2204 | .iter() | |
| 2205 | .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr.hir_id), tcx)) | |
| 2206 | .collect(); | |
| 2207 | ||
| 2208 | if !private_fields.is_empty() { | |
| 2209 | self.report_private_fields( | |
| 2210 | adt_ty, | |
| 2211 | path_span, | |
| 2212 | expr.span, | |
| 2213 | private_fields, | |
| 2214 | hir_fields, | |
| 2215 | ); | |
| 2216 | } else { | |
| 2217 | self.report_missing_fields( | |
| 2218 | adt_ty, | |
| 2219 | path_span, | |
| 2220 | expr.span, | |
| 2221 | remaining_fields, | |
| 2222 | variant, | |
| 2223 | hir_fields, | |
| 2224 | args, | |
| 2225 | ); | |
| 2226 | 2253 | } |
| 2227 | 2254 | } |
| 2228 | 2255 | } |
compiler/rustc_hir_typeck/src/expr_use_visitor.rs+3-1| ... | ... | @@ -673,7 +673,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx |
| 673 | 673 | |
| 674 | 674 | let with_expr = match *opt_with { |
| 675 | 675 | hir::StructTailExpr::Base(w) => &*w, |
| 676 | hir::StructTailExpr::DefaultFields(_) | hir::StructTailExpr::None => { | |
| 676 | hir::StructTailExpr::DefaultFields(_) | |
| 677 | | hir::StructTailExpr::None | |
| 678 | | hir::StructTailExpr::NoneWithError(_) => { | |
| 677 | 679 | return Ok(()); |
| 678 | 680 | } |
| 679 | 681 | }; |
compiler/rustc_lint/src/context.rs+5-27| ... | ... | @@ -11,7 +11,7 @@ use rustc_ast::util::parser::ExprPrecedence; |
| 11 | 11 | use rustc_data_structures::fx::FxIndexMap; |
| 12 | 12 | use rustc_data_structures::sync; |
| 13 | 13 | use rustc_data_structures::unord::UnordMap; |
| 14 | use rustc_errors::{Diag, Diagnostic, LintBuffer, LintDiagnostic, MultiSpan}; | |
| 14 | use rustc_errors::{Diag, Diagnostic, LintBuffer, MultiSpan}; | |
| 15 | 15 | use rustc_feature::Features; |
| 16 | 16 | use rustc_hir::def::Res; |
| 17 | 17 | use rustc_hir::def_id::{CrateNum, DefId}; |
| ... | ... | @@ -535,8 +535,8 @@ pub trait LintContext { |
| 535 | 535 | decorate: impl for<'a> Diagnostic<'a, ()>, |
| 536 | 536 | ); |
| 537 | 537 | |
| 538 | /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`, | |
| 539 | /// typically generated by `#[derive(LintDiagnostic)]`). | |
| 538 | /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`, | |
| 539 | /// typically generated by `#[derive(Diagnostic)]`). | |
| 540 | 540 | fn emit_span_lint<S: Into<MultiSpan>>( |
| 541 | 541 | &self, |
| 542 | 542 | lint: &'static Lint, |
| ... | ... | @@ -546,20 +546,6 @@ pub trait LintContext { |
| 546 | 546 | self.opt_span_diag_lint(lint, Some(span), decorator); |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | /// Emit a lint at `span` from a lazily-constructed lint struct (some type that implements | |
| 550 | /// `LintDiagnostic`, typically generated by `#[derive(LintDiagnostic)]`). | |
| 551 | fn emit_span_lint_lazy<S: Into<MultiSpan>, L: for<'a> LintDiagnostic<'a, ()>>( | |
| 552 | &self, | |
| 553 | lint: &'static Lint, | |
| 554 | span: S, | |
| 555 | decorator: impl FnOnce() -> L, | |
| 556 | ) { | |
| 557 | self.opt_span_lint(lint, Some(span), |lint| { | |
| 558 | let decorator = decorator(); | |
| 559 | decorator.decorate_lint(lint); | |
| 560 | }); | |
| 561 | } | |
| 562 | ||
| 563 | 549 | /// Emit a lint at the appropriate level, with an associated span. |
| 564 | 550 | /// |
| 565 | 551 | /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature |
| ... | ... | @@ -573,16 +559,8 @@ pub trait LintContext { |
| 573 | 559 | self.opt_span_lint(lint, Some(span), decorate); |
| 574 | 560 | } |
| 575 | 561 | |
| 576 | /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically | |
| 577 | /// generated by `#[derive(LintDiagnostic)]`). | |
| 578 | fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) { | |
| 579 | self.opt_span_lint(lint, None as Option<Span>, |lint| { | |
| 580 | decorator.decorate_lint(lint); | |
| 581 | }); | |
| 582 | } | |
| 583 | ||
| 584 | /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically | |
| 585 | /// generated by `#[derive(LintDiagnostic)]`). | |
| 562 | /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically | |
| 563 | /// generated by `#[derive(Diagnostic)]`). | |
| 586 | 564 | fn emit_diag_lint(&self, lint: &'static Lint, decorator: impl for<'a> Diagnostic<'a, ()>) { |
| 587 | 565 | self.opt_span_diag_lint(lint, None as Option<Span>, decorator); |
| 588 | 566 | } |
compiler/rustc_lint/src/early.rs+16-4| ... | ... | @@ -15,6 +15,7 @@ use rustc_session::lint::LintPass; |
| 15 | 15 | use rustc_span::{Ident, Span}; |
| 16 | 16 | use tracing::debug; |
| 17 | 17 | |
| 18 | use crate::DecorateBuiltinLint; | |
| 18 | 19 | use crate::context::{EarlyContext, LintContext, LintStore}; |
| 19 | 20 | use crate::passes::{EarlyLintPass, EarlyLintPassObject}; |
| 20 | 21 | |
| ... | ... | @@ -36,12 +37,23 @@ impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> { |
| 36 | 37 | fn check_id(&mut self, id: ast::NodeId) { |
| 37 | 38 | for early_lint in self.context.buffered.take(id) { |
| 38 | 39 | let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint; |
| 39 | self.context.opt_span_lint(lint_id.lint, span, |diag| match diagnostic { | |
| 40 | match diagnostic { | |
| 40 | 41 | DecorateDiagCompat::Builtin(b) => { |
| 41 | diagnostics::decorate_builtin_lint(self.context.sess(), self.tcx, b, diag); | |
| 42 | self.context.opt_span_diag_lint( | |
| 43 | lint_id.lint, | |
| 44 | span, | |
| 45 | DecorateBuiltinLint { | |
| 46 | sess: self.context.sess(), | |
| 47 | tcx: self.tcx, | |
| 48 | diagnostic: b, | |
| 49 | }, | |
| 50 | ); | |
| 42 | 51 | } |
| 43 | DecorateDiagCompat::Dynamic(d) => d.decorate_lint_box(diag), | |
| 44 | }); | |
| 52 | DecorateDiagCompat::Dynamic(d) => { | |
| 53 | self.context | |
| 54 | .opt_span_lint(lint_id.lint, span, |diag| d.decorate_lint_box(diag)); | |
| 55 | } | |
| 56 | } | |
| 45 | 57 | } |
| 46 | 58 | } |
| 47 | 59 |
compiler/rustc_lint/src/early/diagnostics.rs+403-375| ... | ... | @@ -2,7 +2,8 @@ use std::borrow::Cow; |
| 2 | 2 | |
| 3 | 3 | use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; |
| 4 | 4 | use rustc_errors::{ |
| 5 | Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion, | |
| 5 | Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, Level, | |
| 6 | elided_lifetime_in_path_suggestion, | |
| 6 | 7 | }; |
| 7 | 8 | use rustc_hir::lints::{AttributeLintKind, FormatWarning}; |
| 8 | 9 | use rustc_middle::middle::stability; |
| ... | ... | @@ -16,460 +17,487 @@ use crate::lints; |
| 16 | 17 | |
| 17 | 18 | mod check_cfg; |
| 18 | 19 | |
| 19 | pub fn decorate_builtin_lint( | |
| 20 | sess: &Session, | |
| 21 | tcx: Option<TyCtxt<'_>>, | |
| 22 | diagnostic: BuiltinLintDiag, | |
| 23 | diag: &mut Diag<'_, ()>, | |
| 24 | ) { | |
| 25 | match diagnostic { | |
| 26 | BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { | |
| 27 | let spans: Vec<_> = content | |
| 28 | .char_indices() | |
| 29 | .filter_map(|(i, c)| { | |
| 30 | TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| { | |
| 31 | let lo = comment_span.lo() + BytePos(2 + i as u32); | |
| 32 | (c, comment_span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32))) | |
| 20 | /// This is a diagnostic struct that will decorate a `BuiltinLintDiag` | |
| 21 | /// Directly creating the lint structs is expensive, using this will only decorate the lint structs when needed. | |
| 22 | pub struct DecorateBuiltinLint<'sess, 'tcx> { | |
| 23 | pub sess: &'sess Session, | |
| 24 | pub tcx: Option<TyCtxt<'tcx>>, | |
| 25 | pub diagnostic: BuiltinLintDiag, | |
| 26 | } | |
| 27 | ||
| 28 | impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> { | |
| 29 | fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { | |
| 30 | match self.diagnostic { | |
| 31 | BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { | |
| 32 | let spans: Vec<_> = content | |
| 33 | .char_indices() | |
| 34 | .filter_map(|(i, c)| { | |
| 35 | TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| { | |
| 36 | let lo = comment_span.lo() + BytePos(2 + i as u32); | |
| 37 | (c, comment_span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32))) | |
| 38 | }) | |
| 33 | 39 | }) |
| 34 | }) | |
| 35 | .collect(); | |
| 36 | let characters = spans | |
| 37 | .iter() | |
| 38 | .map(|&(c, span)| lints::UnicodeCharNoteSub { span, c_debug: format!("{c:?}") }) | |
| 39 | .collect(); | |
| 40 | let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { | |
| 41 | spans: spans.iter().map(|(_c, span)| *span).collect(), | |
| 42 | }); | |
| 43 | ||
| 44 | lints::UnicodeTextFlow { | |
| 45 | comment_span, | |
| 46 | characters, | |
| 47 | suggestions, | |
| 48 | num_codepoints: spans.len(), | |
| 49 | } | |
| 50 | .decorate_lint(diag); | |
| 51 | } | |
| 52 | BuiltinLintDiag::AbsPathWithModule(mod_span) => { | |
| 53 | let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { | |
| 54 | Ok(ref s) => { | |
| 55 | // FIXME(Manishearth) ideally the emitting code | |
| 56 | // can tell us whether or not this is global | |
| 57 | let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; | |
| 58 | ||
| 59 | (format!("crate{opt_colon}{s}"), Applicability::MachineApplicable) | |
| 40 | .collect(); | |
| 41 | let characters = spans | |
| 42 | .iter() | |
| 43 | .map(|&(c, span)| lints::UnicodeCharNoteSub { span, c_debug: format!("{c:?}") }) | |
| 44 | .collect(); | |
| 45 | let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { | |
| 46 | spans: spans.iter().map(|(_c, span)| *span).collect(), | |
| 47 | }); | |
| 48 | ||
| 49 | lints::UnicodeTextFlow { | |
| 50 | comment_span, | |
| 51 | characters, | |
| 52 | suggestions, | |
| 53 | num_codepoints: spans.len(), | |
| 60 | 54 | } |
| 61 | Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders), | |
| 62 | }; | |
| 63 | lints::AbsPathWithModule { | |
| 64 | sugg: lints::AbsPathWithModuleSugg { span: mod_span, applicability, replacement }, | |
| 55 | .into_diag(dcx, level) | |
| 65 | 56 | } |
| 66 | .decorate_lint(diag); | |
| 67 | } | |
| 68 | BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { | |
| 69 | lints::ElidedLifetimesInPaths { | |
| 57 | BuiltinLintDiag::AbsPathWithModule(mod_span) => { | |
| 58 | let (replacement, applicability) = | |
| 59 | match self.sess.source_map().span_to_snippet(mod_span) { | |
| 60 | Ok(ref s) => { | |
| 61 | // FIXME(Manishearth) ideally the emitting code | |
| 62 | // can tell us whether or not this is global | |
| 63 | let opt_colon = | |
| 64 | if s.trim_start().starts_with("::") { "" } else { "::" }; | |
| 65 | ||
| 66 | (format!("crate{opt_colon}{s}"), Applicability::MachineApplicable) | |
| 67 | } | |
| 68 | Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders), | |
| 69 | }; | |
| 70 | lints::AbsPathWithModule { | |
| 71 | sugg: lints::AbsPathWithModuleSugg { | |
| 72 | span: mod_span, | |
| 73 | applicability, | |
| 74 | replacement, | |
| 75 | }, | |
| 76 | } | |
| 77 | .into_diag(dcx, level) | |
| 78 | } | |
| 79 | BuiltinLintDiag::ElidedLifetimesInPaths( | |
| 80 | n, | |
| 81 | path_span, | |
| 82 | incl_angl_brckt, | |
| 83 | insertion_span, | |
| 84 | ) => lints::ElidedLifetimesInPaths { | |
| 70 | 85 | subdiag: elided_lifetime_in_path_suggestion( |
| 71 | sess.source_map(), | |
| 86 | self.sess.source_map(), | |
| 72 | 87 | n, |
| 73 | 88 | path_span, |
| 74 | 89 | incl_angl_brckt, |
| 75 | 90 | insertion_span, |
| 76 | 91 | ), |
| 77 | 92 | } |
| 78 | .decorate_lint(diag); | |
| 79 | } | |
| 80 | BuiltinLintDiag::UnusedImports { | |
| 81 | remove_whole_use, | |
| 82 | num_to_remove, | |
| 83 | remove_spans, | |
| 84 | test_module_span, | |
| 85 | span_snippets, | |
| 86 | } => { | |
| 87 | let sugg = if remove_whole_use { | |
| 88 | lints::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } | |
| 89 | } else { | |
| 90 | lints::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } | |
| 91 | }; | |
| 92 | let test_module_span = | |
| 93 | test_module_span.map(|span| sess.source_map().guess_head_span(span)); | |
| 94 | ||
| 95 | lints::UnusedImports { | |
| 96 | sugg, | |
| 93 | .into_diag(dcx, level), | |
| 94 | BuiltinLintDiag::UnusedImports { | |
| 95 | remove_whole_use, | |
| 96 | num_to_remove, | |
| 97 | remove_spans, | |
| 97 | 98 | test_module_span, |
| 98 | num_snippets: span_snippets.len(), | |
| 99 | span_snippets: DiagArgValue::StrListSepByAnd( | |
| 100 | span_snippets.into_iter().map(Cow::Owned).collect(), | |
| 101 | ), | |
| 99 | span_snippets, | |
| 100 | } => { | |
| 101 | let sugg = if remove_whole_use { | |
| 102 | lints::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } | |
| 103 | } else { | |
| 104 | lints::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } | |
| 105 | }; | |
| 106 | let test_module_span = | |
| 107 | test_module_span.map(|span| self.sess.source_map().guess_head_span(span)); | |
| 108 | ||
| 109 | lints::UnusedImports { | |
| 110 | sugg, | |
| 111 | test_module_span, | |
| 112 | num_snippets: span_snippets.len(), | |
| 113 | span_snippets: DiagArgValue::StrListSepByAnd( | |
| 114 | span_snippets.into_iter().map(Cow::Owned).collect(), | |
| 115 | ), | |
| 116 | } | |
| 117 | .into_diag(dcx, level) | |
| 102 | 118 | } |
| 103 | .decorate_lint(diag); | |
| 104 | } | |
| 105 | BuiltinLintDiag::RedundantImport(spans, ident) => { | |
| 106 | let subs = spans | |
| 107 | .into_iter() | |
| 108 | .map(|(span, is_imported)| match (span.is_dummy(), is_imported) { | |
| 109 | (false, true) => lints::RedundantImportSub::ImportedHere { span, ident }, | |
| 110 | (false, false) => lints::RedundantImportSub::DefinedHere { span, ident }, | |
| 111 | (true, true) => lints::RedundantImportSub::ImportedPrelude { span, ident }, | |
| 112 | (true, false) => lints::RedundantImportSub::DefinedPrelude { span, ident }, | |
| 113 | }) | |
| 114 | .collect(); | |
| 115 | lints::RedundantImport { subs, ident }.decorate_lint(diag); | |
| 116 | } | |
| 117 | BuiltinLintDiag::DeprecatedMacro { | |
| 118 | suggestion, | |
| 119 | suggestion_span, | |
| 120 | note, | |
| 121 | path, | |
| 122 | since_kind, | |
| 123 | } => { | |
| 124 | let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion { | |
| 125 | span: suggestion_span, | |
| 126 | kind: "macro".to_owned(), | |
| 119 | BuiltinLintDiag::RedundantImport(spans, ident) => { | |
| 120 | let subs = spans | |
| 121 | .into_iter() | |
| 122 | .map(|(span, is_imported)| match (span.is_dummy(), is_imported) { | |
| 123 | (false, true) => lints::RedundantImportSub::ImportedHere { span, ident }, | |
| 124 | (false, false) => lints::RedundantImportSub::DefinedHere { span, ident }, | |
| 125 | (true, true) => lints::RedundantImportSub::ImportedPrelude { span, ident }, | |
| 126 | (true, false) => lints::RedundantImportSub::DefinedPrelude { span, ident }, | |
| 127 | }) | |
| 128 | .collect(); | |
| 129 | lints::RedundantImport { subs, ident }.into_diag(dcx, level) | |
| 130 | } | |
| 131 | BuiltinLintDiag::DeprecatedMacro { | |
| 127 | 132 | suggestion, |
| 128 | }); | |
| 129 | ||
| 130 | stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } | |
| 131 | .decorate_lint(diag); | |
| 132 | } | |
| 133 | BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { | |
| 134 | let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; | |
| 135 | if is_foreign { | |
| 136 | lints::PatternsInFnsWithoutBody::Foreign { sub } | |
| 137 | } else { | |
| 138 | lints::PatternsInFnsWithoutBody::Bodiless { sub } | |
| 139 | } | |
| 140 | .decorate_lint(diag); | |
| 141 | } | |
| 142 | BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { | |
| 143 | lints::ReservedPrefix { | |
| 133 | suggestion_span, | |
| 134 | note, | |
| 135 | path, | |
| 136 | since_kind, | |
| 137 | } => { | |
| 138 | let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion { | |
| 139 | span: suggestion_span, | |
| 140 | kind: "macro".to_owned(), | |
| 141 | suggestion, | |
| 142 | }); | |
| 143 | ||
| 144 | stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } | |
| 145 | .into_diag(dcx, level) | |
| 146 | } | |
| 147 | BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { | |
| 148 | let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; | |
| 149 | if is_foreign { | |
| 150 | lints::PatternsInFnsWithoutBody::Foreign { sub } | |
| 151 | } else { | |
| 152 | lints::PatternsInFnsWithoutBody::Bodiless { sub } | |
| 153 | } | |
| 154 | .into_diag(dcx, level) | |
| 155 | } | |
| 156 | BuiltinLintDiag::ReservedPrefix(label_span, prefix) => lints::ReservedPrefix { | |
| 144 | 157 | label: label_span, |
| 145 | 158 | suggestion: label_span.shrink_to_hi(), |
| 146 | 159 | prefix, |
| 147 | 160 | } |
| 148 | .decorate_lint(diag); | |
| 149 | } | |
| 150 | BuiltinLintDiag::RawPrefix(label_span) => { | |
| 151 | lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() } | |
| 152 | .decorate_lint(diag); | |
| 153 | } | |
| 154 | BuiltinLintDiag::ReservedString { is_string, suggestion } => { | |
| 155 | if is_string { | |
| 156 | lints::ReservedString { suggestion }.decorate_lint(diag); | |
| 157 | } else { | |
| 158 | lints::ReservedMultihash { suggestion }.decorate_lint(diag); | |
| 161 | .into_diag(dcx, level), | |
| 162 | BuiltinLintDiag::RawPrefix(label_span) => { | |
| 163 | lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() } | |
| 164 | .into_diag(dcx, level) | |
| 159 | 165 | } |
| 160 | } | |
| 161 | BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { | |
| 162 | lints::BreakWithLabelAndLoop { | |
| 166 | BuiltinLintDiag::ReservedString { is_string, suggestion } => { | |
| 167 | if is_string { | |
| 168 | lints::ReservedString { suggestion }.into_diag(dcx, level) | |
| 169 | } else { | |
| 170 | lints::ReservedMultihash { suggestion }.into_diag(dcx, level) | |
| 171 | } | |
| 172 | } | |
| 173 | BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => lints::BreakWithLabelAndLoop { | |
| 163 | 174 | sub: lints::BreakWithLabelAndLoopSub { |
| 164 | 175 | left: sugg_span.shrink_to_lo(), |
| 165 | 176 | right: sugg_span.shrink_to_hi(), |
| 166 | 177 | }, |
| 167 | 178 | } |
| 168 | .decorate_lint(diag); | |
| 169 | } | |
| 170 | BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { | |
| 171 | let suggestion = match sugg { | |
| 172 | Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { | |
| 173 | left: left_sp, | |
| 174 | right: right_sp, | |
| 175 | sugg, | |
| 176 | }, | |
| 177 | None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, | |
| 178 | }; | |
| 179 | lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); | |
| 180 | } | |
| 181 | BuiltinLintDiag::SingleUseLifetime { | |
| 182 | param_span, | |
| 183 | use_span: Some((use_span, elide)), | |
| 184 | deletion_span, | |
| 185 | ident, | |
| 186 | } => { | |
| 187 | debug!(?param_span, ?use_span, ?deletion_span); | |
| 188 | let suggestion = if let Some(deletion_span) = deletion_span { | |
| 189 | let (use_span, replace_lt) = if elide { | |
| 190 | let use_span = sess.source_map().span_extend_while_whitespace(use_span); | |
| 191 | (use_span, String::new()) | |
| 192 | } else { | |
| 193 | (use_span, "'_".to_owned()) | |
| 194 | }; | |
| 195 | debug!(?deletion_span, ?use_span); | |
| 196 | ||
| 197 | // issue 107998 for the case such as a wrong function pointer type | |
| 198 | // `deletion_span` is empty and there is no need to report lifetime uses here | |
| 199 | let deletion_span = | |
| 200 | if deletion_span.is_empty() { None } else { Some(deletion_span) }; | |
| 201 | Some(lints::SingleUseLifetimeSugg { deletion_span, use_span, replace_lt }) | |
| 202 | } else { | |
| 203 | None | |
| 204 | }; | |
| 205 | ||
| 206 | lints::SingleUseLifetime { suggestion, param_span, use_span, ident } | |
| 207 | .decorate_lint(diag); | |
| 208 | } | |
| 209 | BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { | |
| 210 | lints::UnusedLifetime { deletion_span, ident }.decorate_lint(diag); | |
| 211 | } | |
| 212 | BuiltinLintDiag::NamedArgumentUsedPositionally { | |
| 213 | position_sp_to_replace, | |
| 214 | position_sp_for_msg, | |
| 215 | named_arg_sp, | |
| 216 | named_arg_name, | |
| 217 | is_formatting_arg, | |
| 218 | } => { | |
| 219 | let (suggestion, name) = if let Some(positional_arg_to_replace) = position_sp_to_replace | |
| 220 | { | |
| 221 | let mut name = named_arg_name.clone(); | |
| 222 | if is_formatting_arg { | |
| 223 | name.push('$') | |
| 179 | .into_diag(dcx, level), | |
| 180 | BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { | |
| 181 | let suggestion = match sugg { | |
| 182 | Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { | |
| 183 | left: left_sp, | |
| 184 | right: right_sp, | |
| 185 | sugg, | |
| 186 | }, | |
| 187 | None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, | |
| 224 | 188 | }; |
| 225 | let span_to_replace = if let Ok(positional_arg_content) = | |
| 226 | sess.source_map().span_to_snippet(positional_arg_to_replace) | |
| 227 | && positional_arg_content.starts_with(':') | |
| 228 | { | |
| 229 | positional_arg_to_replace.shrink_to_lo() | |
| 189 | lints::DeprecatedWhereClauseLocation { suggestion }.into_diag(dcx, level) | |
| 190 | } | |
| 191 | BuiltinLintDiag::SingleUseLifetime { | |
| 192 | param_span, | |
| 193 | use_span: Some((use_span, elide)), | |
| 194 | deletion_span, | |
| 195 | ident, | |
| 196 | } => { | |
| 197 | debug!(?param_span, ?use_span, ?deletion_span); | |
| 198 | let suggestion = if let Some(deletion_span) = deletion_span { | |
| 199 | let (use_span, replace_lt) = if elide { | |
| 200 | let use_span = | |
| 201 | self.sess.source_map().span_extend_while_whitespace(use_span); | |
| 202 | (use_span, String::new()) | |
| 203 | } else { | |
| 204 | (use_span, "'_".to_owned()) | |
| 205 | }; | |
| 206 | debug!(?deletion_span, ?use_span); | |
| 207 | ||
| 208 | // issue 107998 for the case such as a wrong function pointer type | |
| 209 | // `deletion_span` is empty and there is no need to report lifetime uses here | |
| 210 | let deletion_span = | |
| 211 | if deletion_span.is_empty() { None } else { Some(deletion_span) }; | |
| 212 | Some(lints::SingleUseLifetimeSugg { deletion_span, use_span, replace_lt }) | |
| 230 | 213 | } else { |
| 231 | positional_arg_to_replace | |
| 214 | None | |
| 232 | 215 | }; |
| 233 | (Some(span_to_replace), name) | |
| 234 | } else { | |
| 235 | (None, String::new()) | |
| 236 | }; | |
| 237 | 216 | |
| 238 | lints::NamedArgumentUsedPositionally { | |
| 217 | lints::SingleUseLifetime { suggestion, param_span, use_span, ident } | |
| 218 | .into_diag(dcx, level) | |
| 219 | } | |
| 220 | BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { | |
| 221 | lints::UnusedLifetime { deletion_span, ident }.into_diag(dcx, level) | |
| 222 | } | |
| 223 | BuiltinLintDiag::NamedArgumentUsedPositionally { | |
| 224 | position_sp_to_replace, | |
| 225 | position_sp_for_msg, | |
| 239 | 226 | named_arg_sp, |
| 240 | position_label_sp: position_sp_for_msg, | |
| 241 | suggestion, | |
| 242 | name, | |
| 243 | 227 | named_arg_name, |
| 228 | is_formatting_arg, | |
| 229 | } => { | |
| 230 | let (suggestion, name) = | |
| 231 | if let Some(positional_arg_to_replace) = position_sp_to_replace { | |
| 232 | let mut name = named_arg_name.clone(); | |
| 233 | if is_formatting_arg { | |
| 234 | name.push('$') | |
| 235 | }; | |
| 236 | let span_to_replace = if let Ok(positional_arg_content) = | |
| 237 | self.sess.source_map().span_to_snippet(positional_arg_to_replace) | |
| 238 | && positional_arg_content.starts_with(':') | |
| 239 | { | |
| 240 | positional_arg_to_replace.shrink_to_lo() | |
| 241 | } else { | |
| 242 | positional_arg_to_replace | |
| 243 | }; | |
| 244 | (Some(span_to_replace), name) | |
| 245 | } else { | |
| 246 | (None, String::new()) | |
| 247 | }; | |
| 248 | ||
| 249 | lints::NamedArgumentUsedPositionally { | |
| 250 | named_arg_sp, | |
| 251 | position_label_sp: position_sp_for_msg, | |
| 252 | suggestion, | |
| 253 | name, | |
| 254 | named_arg_name, | |
| 255 | } | |
| 256 | .into_diag(dcx, level) | |
| 244 | 257 | } |
| 245 | .decorate_lint(diag); | |
| 246 | } | |
| 247 | BuiltinLintDiag::AmbiguousGlobReexports { | |
| 248 | name, | |
| 249 | namespace, | |
| 250 | first_reexport_span, | |
| 251 | duplicate_reexport_span, | |
| 252 | } => { | |
| 253 | lints::AmbiguousGlobReexports { | |
| 258 | BuiltinLintDiag::AmbiguousGlobReexports { | |
| 259 | name, | |
| 260 | namespace, | |
| 261 | first_reexport_span, | |
| 262 | duplicate_reexport_span, | |
| 263 | } => lints::AmbiguousGlobReexports { | |
| 254 | 264 | first_reexport: first_reexport_span, |
| 255 | 265 | duplicate_reexport: duplicate_reexport_span, |
| 256 | 266 | name, |
| 257 | 267 | namespace, |
| 258 | 268 | } |
| 259 | .decorate_lint(diag); | |
| 260 | } | |
| 261 | BuiltinLintDiag::HiddenGlobReexports { | |
| 262 | name, | |
| 263 | namespace, | |
| 264 | glob_reexport_span, | |
| 265 | private_item_span, | |
| 266 | } => { | |
| 267 | lints::HiddenGlobReexports { | |
| 269 | .into_diag(dcx, level), | |
| 270 | BuiltinLintDiag::HiddenGlobReexports { | |
| 271 | name, | |
| 272 | namespace, | |
| 273 | glob_reexport_span, | |
| 274 | private_item_span, | |
| 275 | } => lints::HiddenGlobReexports { | |
| 268 | 276 | glob_reexport: glob_reexport_span, |
| 269 | 277 | private_item: private_item_span, |
| 270 | 278 | |
| 271 | 279 | name, |
| 272 | 280 | namespace, |
| 273 | 281 | } |
| 274 | .decorate_lint(diag); | |
| 275 | } | |
| 276 | BuiltinLintDiag::UnusedQualifications { removal_span } => { | |
| 277 | lints::UnusedQualifications { removal_span }.decorate_lint(diag); | |
| 278 | } | |
| 279 | BuiltinLintDiag::AssociatedConstElidedLifetime { | |
| 280 | elided, | |
| 281 | span: lt_span, | |
| 282 | lifetimes_in_scope, | |
| 283 | } => { | |
| 284 | let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; | |
| 285 | let code = if elided { "'static " } else { "'static" }; | |
| 286 | lints::AssociatedConstElidedLifetime { | |
| 287 | span: lt_span, | |
| 288 | code, | |
| 282 | .into_diag(dcx, level), | |
| 283 | BuiltinLintDiag::UnusedQualifications { removal_span } => { | |
| 284 | lints::UnusedQualifications { removal_span }.into_diag(dcx, level) | |
| 285 | } | |
| 286 | BuiltinLintDiag::AssociatedConstElidedLifetime { | |
| 289 | 287 | elided, |
| 288 | span: lt_span, | |
| 290 | 289 | lifetimes_in_scope, |
| 290 | } => { | |
| 291 | let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; | |
| 292 | let code = if elided { "'static " } else { "'static" }; | |
| 293 | lints::AssociatedConstElidedLifetime { | |
| 294 | span: lt_span, | |
| 295 | code, | |
| 296 | elided, | |
| 297 | lifetimes_in_scope, | |
| 298 | } | |
| 299 | .into_diag(dcx, level) | |
| 291 | 300 | } |
| 292 | .decorate_lint(diag); | |
| 293 | } | |
| 294 | BuiltinLintDiag::UnreachableCfg { span, wildcard_span } => match wildcard_span { | |
| 295 | Some(wildcard_span) => { | |
| 296 | lints::UnreachableCfgSelectPredicateWildcard { span, wildcard_span } | |
| 297 | .decorate_lint(diag) | |
| 298 | } | |
| 299 | None => lints::UnreachableCfgSelectPredicate { span }.decorate_lint(diag), | |
| 300 | }, | |
| 301 | BuiltinLintDiag::UnreachableCfg { span, wildcard_span } => match wildcard_span { | |
| 302 | Some(wildcard_span) => { | |
| 303 | lints::UnreachableCfgSelectPredicateWildcard { span, wildcard_span } | |
| 304 | .into_diag(dcx, level) | |
| 305 | } | |
| 306 | None => lints::UnreachableCfgSelectPredicate { span }.into_diag(dcx, level), | |
| 307 | }, | |
| 301 | 308 | |
| 302 | BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { | |
| 303 | lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) | |
| 304 | } | |
| 305 | BuiltinLintDiag::UnusedVisibility(span) => { | |
| 306 | lints::UnusedVisibility { span }.decorate_lint(diag) | |
| 309 | BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { | |
| 310 | lints::UnusedCrateDependency { extern_crate, local_crate }.into_diag(dcx, level) | |
| 311 | } | |
| 312 | BuiltinLintDiag::UnusedVisibility(span) => { | |
| 313 | lints::UnusedVisibility { span }.into_diag(dcx, level) | |
| 314 | } | |
| 315 | BuiltinLintDiag::AttributeLint(kind) => { | |
| 316 | DecorateAttrLint { sess: self.sess, tcx: self.tcx, diagnostic: &kind } | |
| 317 | .into_diag(dcx, level) | |
| 318 | } | |
| 307 | 319 | } |
| 308 | BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, diag), | |
| 309 | 320 | } |
| 310 | 321 | } |
| 311 | 322 | |
| 312 | pub fn decorate_attribute_lint( | |
| 313 | sess: &Session, | |
| 314 | tcx: Option<TyCtxt<'_>>, | |
| 315 | kind: &AttributeLintKind, | |
| 316 | diag: &mut Diag<'_, ()>, | |
| 317 | ) { | |
| 318 | match kind { | |
| 319 | &AttributeLintKind::UnusedDuplicate { this, other, warning } => { | |
| 320 | lints::UnusedDuplicate { this, other, warning }.decorate_lint(diag) | |
| 321 | } | |
| 322 | AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => { | |
| 323 | lints::IllFormedAttributeInput { | |
| 324 | num_suggestions: suggestions.len(), | |
| 325 | suggestions: DiagArgValue::StrListSepByAnd( | |
| 326 | suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), | |
| 327 | ), | |
| 328 | has_docs: docs.is_some(), | |
| 329 | docs: docs.unwrap_or(""), | |
| 323 | /// This is a diagnostic struct that will decorate a `AttributeLintKind` | |
| 324 | /// Directly creating the lint structs is expensive, using this will only decorate the lint structs when needed. | |
| 325 | pub struct DecorateAttrLint<'a, 'sess, 'tcx> { | |
| 326 | pub sess: &'sess Session, | |
| 327 | pub tcx: Option<TyCtxt<'tcx>>, | |
| 328 | pub diagnostic: &'a AttributeLintKind, | |
| 329 | } | |
| 330 | ||
| 331 | impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { | |
| 332 | fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { | |
| 333 | match self.diagnostic { | |
| 334 | &AttributeLintKind::UnusedDuplicate { this, other, warning } => { | |
| 335 | lints::UnusedDuplicate { this, other, warning }.into_diag(dcx, level) | |
| 330 | 336 | } |
| 331 | .decorate_lint(diag) | |
| 332 | } | |
| 333 | AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { | |
| 334 | lints::EmptyAttributeList { | |
| 335 | attr_span: *first_span, | |
| 336 | attr_path: attr_path.clone(), | |
| 337 | valid_without_list: *valid_without_list, | |
| 337 | AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => { | |
| 338 | lints::IllFormedAttributeInput { | |
| 339 | num_suggestions: suggestions.len(), | |
| 340 | suggestions: DiagArgValue::StrListSepByAnd( | |
| 341 | suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), | |
| 342 | ), | |
| 343 | has_docs: docs.is_some(), | |
| 344 | docs: docs.unwrap_or(""), | |
| 345 | } | |
| 346 | .into_diag(dcx, level) | |
| 338 | 347 | } |
| 339 | .decorate_lint(diag) | |
| 340 | } | |
| 341 | AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => { | |
| 342 | lints::InvalidTargetLint { | |
| 343 | name: name.clone(), | |
| 344 | target, | |
| 345 | applied: DiagArgValue::StrListSepByAnd( | |
| 346 | applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(), | |
| 347 | ), | |
| 348 | only, | |
| 349 | attr_span: *attr_span, | |
| 348 | AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { | |
| 349 | lints::EmptyAttributeList { | |
| 350 | attr_span: *first_span, | |
| 351 | attr_path: attr_path.clone(), | |
| 352 | valid_without_list: *valid_without_list, | |
| 353 | } | |
| 354 | .into_diag(dcx, level) | |
| 350 | 355 | } |
| 351 | .decorate_lint(diag) | |
| 352 | } | |
| 353 | &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => { | |
| 354 | lints::InvalidAttrStyle { | |
| 356 | AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => { | |
| 357 | lints::InvalidTargetLint { | |
| 358 | name: name.clone(), | |
| 359 | target, | |
| 360 | applied: DiagArgValue::StrListSepByAnd( | |
| 361 | applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(), | |
| 362 | ), | |
| 363 | only, | |
| 364 | attr_span: *attr_span, | |
| 365 | } | |
| 366 | .into_diag(dcx, level) | |
| 367 | } | |
| 368 | &AttributeLintKind::InvalidStyle { | |
| 369 | ref name, | |
| 370 | is_used_as_inner, | |
| 371 | target, | |
| 372 | target_span, | |
| 373 | } => lints::InvalidAttrStyle { | |
| 355 | 374 | name: name.clone(), |
| 356 | 375 | is_used_as_inner, |
| 357 | 376 | target_span: (!is_used_as_inner).then_some(target_span), |
| 358 | 377 | target, |
| 359 | 378 | } |
| 360 | .decorate_lint(diag) | |
| 361 | } | |
| 362 | &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => { | |
| 363 | lints::UnsafeAttrOutsideUnsafeLint { | |
| 364 | span: attribute_name_span, | |
| 365 | suggestion: sugg_spans | |
| 366 | .map(|(left, right)| lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }), | |
| 379 | .into_diag(dcx, level), | |
| 380 | &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => { | |
| 381 | lints::UnsafeAttrOutsideUnsafeLint { | |
| 382 | span: attribute_name_span, | |
| 383 | suggestion: sugg_spans.map(|(left, right)| { | |
| 384 | lints::UnsafeAttrOutsideUnsafeSuggestion { left, right } | |
| 385 | }), | |
| 386 | } | |
| 387 | .into_diag(dcx, level) | |
| 388 | } | |
| 389 | &AttributeLintKind::UnexpectedCfgName(name, value) => { | |
| 390 | check_cfg::unexpected_cfg_name(self.sess, self.tcx, name, value) | |
| 391 | .into_diag(dcx, level) | |
| 392 | } | |
| 393 | &AttributeLintKind::UnexpectedCfgValue(name, value) => { | |
| 394 | check_cfg::unexpected_cfg_value(self.sess, self.tcx, name, value) | |
| 395 | .into_diag(dcx, level) | |
| 396 | } | |
| 397 | &AttributeLintKind::DuplicateDocAlias { first_definition } => { | |
| 398 | lints::DocAliasDuplicated { first_defn: first_definition }.into_diag(dcx, level) | |
| 367 | 399 | } |
| 368 | .decorate_lint(diag) | |
| 369 | } | |
| 370 | &AttributeLintKind::UnexpectedCfgName(name, value) => { | |
| 371 | check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag) | |
| 372 | } | |
| 373 | &AttributeLintKind::UnexpectedCfgValue(name, value) => { | |
| 374 | check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag) | |
| 375 | } | |
| 376 | &AttributeLintKind::DuplicateDocAlias { first_definition } => { | |
| 377 | lints::DocAliasDuplicated { first_defn: first_definition }.decorate_lint(diag) | |
| 378 | } | |
| 379 | 400 | |
| 380 | &AttributeLintKind::DocAutoCfgExpectsHideOrShow => { | |
| 381 | lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag) | |
| 382 | } | |
| 401 | &AttributeLintKind::DocAutoCfgExpectsHideOrShow => { | |
| 402 | lints::DocAutoCfgExpectsHideOrShow.into_diag(dcx, level) | |
| 403 | } | |
| 383 | 404 | |
| 384 | &AttributeLintKind::AmbiguousDeriveHelpers => { | |
| 385 | lints::AmbiguousDeriveHelpers.decorate_lint(diag) | |
| 386 | } | |
| 405 | &AttributeLintKind::AmbiguousDeriveHelpers => { | |
| 406 | lints::AmbiguousDeriveHelpers.into_diag(dcx, level) | |
| 407 | } | |
| 387 | 408 | |
| 388 | &AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => { | |
| 389 | lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.decorate_lint(diag) | |
| 390 | } | |
| 409 | &AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => { | |
| 410 | lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.into_diag(dcx, level) | |
| 411 | } | |
| 391 | 412 | |
| 392 | &AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name } => { | |
| 393 | lints::DocAutoCfgHideShowExpectsList { attr_name }.decorate_lint(diag) | |
| 394 | } | |
| 413 | &AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name } => { | |
| 414 | lints::DocAutoCfgHideShowExpectsList { attr_name }.into_diag(dcx, level) | |
| 415 | } | |
| 395 | 416 | |
| 396 | &AttributeLintKind::DocInvalid => { lints::DocInvalid }.decorate_lint(diag), | |
| 417 | &AttributeLintKind::DocInvalid => lints::DocInvalid.into_diag(dcx, level), | |
| 397 | 418 | |
| 398 | &AttributeLintKind::DocUnknownInclude { span, inner, value } => { | |
| 399 | lints::DocUnknownInclude { inner, value, sugg: (span, Applicability::MaybeIncorrect) } | |
| 400 | } | |
| 401 | .decorate_lint(diag), | |
| 419 | &AttributeLintKind::DocUnknownInclude { span, inner, value } => { | |
| 420 | lints::DocUnknownInclude { | |
| 421 | inner, | |
| 422 | value, | |
| 423 | sugg: (span, Applicability::MaybeIncorrect), | |
| 424 | } | |
| 425 | .into_diag(dcx, level) | |
| 426 | } | |
| 402 | 427 | |
| 403 | &AttributeLintKind::DocUnknownSpotlight { span } => { | |
| 404 | lints::DocUnknownSpotlight { sugg_span: span }.decorate_lint(diag) | |
| 405 | } | |
| 428 | &AttributeLintKind::DocUnknownSpotlight { span } => { | |
| 429 | lints::DocUnknownSpotlight { sugg_span: span }.into_diag(dcx, level) | |
| 430 | } | |
| 406 | 431 | |
| 407 | &AttributeLintKind::DocUnknownPasses { name, span } => { | |
| 408 | lints::DocUnknownPasses { name, note_span: span }.decorate_lint(diag) | |
| 409 | } | |
| 432 | &AttributeLintKind::DocUnknownPasses { name, span } => { | |
| 433 | lints::DocUnknownPasses { name, note_span: span }.into_diag(dcx, level) | |
| 434 | } | |
| 410 | 435 | |
| 411 | &AttributeLintKind::DocUnknownPlugins { span } => { | |
| 412 | lints::DocUnknownPlugins { label_span: span }.decorate_lint(diag) | |
| 413 | } | |
| 436 | &AttributeLintKind::DocUnknownPlugins { span } => { | |
| 437 | lints::DocUnknownPlugins { label_span: span }.into_diag(dcx, level) | |
| 438 | } | |
| 414 | 439 | |
| 415 | &AttributeLintKind::DocUnknownAny { name } => { | |
| 416 | lints::DocUnknownAny { name }.decorate_lint(diag) | |
| 417 | } | |
| 440 | &AttributeLintKind::DocUnknownAny { name } => { | |
| 441 | lints::DocUnknownAny { name }.into_diag(dcx, level) | |
| 442 | } | |
| 418 | 443 | |
| 419 | &AttributeLintKind::DocAutoCfgWrongLiteral => { | |
| 420 | lints::DocAutoCfgWrongLiteral.decorate_lint(diag) | |
| 421 | } | |
| 444 | &AttributeLintKind::DocAutoCfgWrongLiteral => { | |
| 445 | lints::DocAutoCfgWrongLiteral.into_diag(dcx, level) | |
| 446 | } | |
| 422 | 447 | |
| 423 | &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.decorate_lint(diag), | |
| 448 | &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.into_diag(dcx, level), | |
| 424 | 449 | |
| 425 | &AttributeLintKind::DocTestUnknown { name } => { | |
| 426 | lints::DocTestUnknown { name }.decorate_lint(diag) | |
| 427 | } | |
| 450 | &AttributeLintKind::DocTestUnknown { name } => { | |
| 451 | lints::DocTestUnknown { name }.into_diag(dcx, level) | |
| 452 | } | |
| 428 | 453 | |
| 429 | &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.decorate_lint(diag), | |
| 454 | &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.into_diag(dcx, level), | |
| 430 | 455 | |
| 431 | &AttributeLintKind::AttrCrateLevelOnly => lints::AttrCrateLevelOnly.decorate_lint(diag), | |
| 456 | &AttributeLintKind::AttrCrateLevelOnly => { | |
| 457 | lints::AttrCrateLevelOnly.into_diag(dcx, level) | |
| 458 | } | |
| 432 | 459 | |
| 433 | &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => { | |
| 434 | lints::DoNotRecommendDoesNotExpectArgs.decorate_lint(diag) | |
| 435 | } | |
| 460 | &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => { | |
| 461 | lints::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level) | |
| 462 | } | |
| 436 | 463 | |
| 437 | &AttributeLintKind::CrateTypeUnknown { span, suggested } => lints::UnknownCrateTypes { | |
| 438 | sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), | |
| 439 | } | |
| 440 | .decorate_lint(diag), | |
| 464 | &AttributeLintKind::CrateTypeUnknown { span, suggested } => lints::UnknownCrateTypes { | |
| 465 | sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), | |
| 466 | } | |
| 467 | .into_diag(dcx, level), | |
| 441 | 468 | |
| 442 | &AttributeLintKind::MalformedDoc => lints::MalformedDoc.decorate_lint(diag), | |
| 469 | &AttributeLintKind::MalformedDoc => lints::MalformedDoc.into_diag(dcx, level), | |
| 443 | 470 | |
| 444 | &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.decorate_lint(diag), | |
| 471 | &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.into_diag(dcx, level), | |
| 445 | 472 | |
| 446 | &AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.decorate_lint(diag), | |
| 447 | &AttributeLintKind::MalformedOnUnimplementedAttr { span } => { | |
| 448 | lints::MalformedOnUnimplementedAttrLint { span }.decorate_lint(diag) | |
| 449 | } | |
| 450 | &AttributeLintKind::MalformedOnConstAttr { span } => { | |
| 451 | lints::MalformedOnConstAttrLint { span }.decorate_lint(diag) | |
| 452 | } | |
| 453 | AttributeLintKind::MalformedDiagnosticFormat { warning } => match warning { | |
| 454 | FormatWarning::PositionalArgument { .. } => { | |
| 455 | lints::DisallowedPositionalArgument.decorate_lint(diag) | |
| 473 | &AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.into_diag(dcx, level), | |
| 474 | &AttributeLintKind::MalformedOnUnimplementedAttr { span } => { | |
| 475 | lints::MalformedOnUnimplementedAttrLint { span }.into_diag(dcx, level) | |
| 456 | 476 | } |
| 457 | FormatWarning::InvalidSpecifier { .. } => { | |
| 458 | lints::InvalidFormatSpecifier.decorate_lint(diag) | |
| 477 | &AttributeLintKind::MalformedOnConstAttr { span } => { | |
| 478 | lints::MalformedOnConstAttrLint { span }.into_diag(dcx, level) | |
| 479 | } | |
| 480 | AttributeLintKind::MalformedDiagnosticFormat { warning } => match warning { | |
| 481 | FormatWarning::PositionalArgument { .. } => { | |
| 482 | lints::DisallowedPositionalArgument.into_diag(dcx, level) | |
| 483 | } | |
| 484 | FormatWarning::InvalidSpecifier { .. } => { | |
| 485 | lints::InvalidFormatSpecifier.into_diag(dcx, level) | |
| 486 | } | |
| 487 | }, | |
| 488 | AttributeLintKind::DiagnosticWrappedParserError { description, label, span } => { | |
| 489 | lints::WrappedParserError { description, label, span: *span }.into_diag(dcx, level) | |
| 490 | } | |
| 491 | &AttributeLintKind::IgnoredDiagnosticOption { option_name, first_span, later_span } => { | |
| 492 | lints::IgnoredDiagnosticOption { option_name, first_span, later_span } | |
| 493 | .into_diag(dcx, level) | |
| 494 | } | |
| 495 | &AttributeLintKind::MissingOptionsForOnUnimplemented => { | |
| 496 | lints::MissingOptionsForOnUnimplementedAttr.into_diag(dcx, level) | |
| 497 | } | |
| 498 | &AttributeLintKind::MissingOptionsForOnConst => { | |
| 499 | lints::MissingOptionsForOnConstAttr.into_diag(dcx, level) | |
| 459 | 500 | } |
| 460 | }, | |
| 461 | AttributeLintKind::DiagnosticWrappedParserError { description, label, span } => { | |
| 462 | lints::WrappedParserError { description, label, span: *span }.decorate_lint(diag) | |
| 463 | } | |
| 464 | &AttributeLintKind::IgnoredDiagnosticOption { option_name, first_span, later_span } => { | |
| 465 | lints::IgnoredDiagnosticOption { option_name, first_span, later_span } | |
| 466 | .decorate_lint(diag) | |
| 467 | } | |
| 468 | &AttributeLintKind::MissingOptionsForOnUnimplemented => { | |
| 469 | lints::MissingOptionsForOnUnimplementedAttr.decorate_lint(diag) | |
| 470 | } | |
| 471 | &AttributeLintKind::MissingOptionsForOnConst => { | |
| 472 | lints::MissingOptionsForOnConstAttr.decorate_lint(diag) | |
| 473 | 501 | } |
| 474 | 502 | } |
| 475 | 503 | } |
compiler/rustc_lint/src/lib.rs+1-1| ... | ... | @@ -131,7 +131,7 @@ use unused::*; |
| 131 | 131 | #[rustfmt::skip] |
| 132 | 132 | pub use builtin::{MissingDoc, SoftLints}; |
| 133 | 133 | pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; |
| 134 | pub use early::diagnostics::{decorate_attribute_lint, decorate_builtin_lint}; | |
| 134 | pub use early::diagnostics::{DecorateAttrLint, DecorateBuiltinLint}; | |
| 135 | 135 | pub use early::{EarlyCheckNode, check_ast_node}; |
| 136 | 136 | pub use late::{check_crate, late_lint_mod, unerased_lint_store}; |
| 137 | 137 | pub use levels::LintLevelsBuilder; |
compiler/rustc_lint/src/lints.rs+62-62| ... | ... | @@ -11,7 +11,7 @@ use rustc_errors::{ |
| 11 | 11 | use rustc_hir as hir; |
| 12 | 12 | use rustc_hir::def_id::DefId; |
| 13 | 13 | use rustc_hir::intravisit::VisitorExt; |
| 14 | use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; | |
| 14 | use rustc_macros::{Diagnostic, Subdiagnostic}; | |
| 15 | 15 | use rustc_middle::ty::inhabitedness::InhabitedPredicate; |
| 16 | 16 | use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; |
| 17 | 17 | use rustc_session::Session; |
| ... | ... | @@ -1600,7 +1600,7 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { |
| 1600 | 1600 | } |
| 1601 | 1601 | } |
| 1602 | 1602 | |
| 1603 | #[derive(LintDiagnostic)] | |
| 1603 | #[derive(Diagnostic)] | |
| 1604 | 1604 | #[diag("{$sort} `{$name}` should have an upper case name")] |
| 1605 | 1605 | pub(crate) struct NonUpperCaseGlobal<'a> { |
| 1606 | 1606 | pub sort: &'a str, |
| ... | ... | @@ -2712,7 +2712,7 @@ pub(crate) struct UnexpectedCfgCargoMacroHelp { |
| 2712 | 2712 | pub crate_name: Symbol, |
| 2713 | 2713 | } |
| 2714 | 2714 | |
| 2715 | #[derive(LintDiagnostic)] | |
| 2715 | #[derive(Diagnostic)] | |
| 2716 | 2716 | #[diag("unexpected `cfg` condition name: `{$name}`")] |
| 2717 | 2717 | pub(crate) struct UnexpectedCfgName { |
| 2718 | 2718 | #[subdiagnostic] |
| ... | ... | @@ -2859,7 +2859,7 @@ pub(crate) mod unexpected_cfg_name { |
| 2859 | 2859 | } |
| 2860 | 2860 | } |
| 2861 | 2861 | |
| 2862 | #[derive(LintDiagnostic)] | |
| 2862 | #[derive(Diagnostic)] | |
| 2863 | 2863 | #[diag( |
| 2864 | 2864 | "unexpected `cfg` condition value: {$has_value -> |
| 2865 | 2865 | [true] `{$value}` |
| ... | ... | @@ -2994,7 +2994,7 @@ pub(crate) mod unexpected_cfg_value { |
| 2994 | 2994 | } |
| 2995 | 2995 | } |
| 2996 | 2996 | |
| 2997 | #[derive(LintDiagnostic)] | |
| 2997 | #[derive(Diagnostic)] | |
| 2998 | 2998 | #[diag("extern crate `{$extern_crate}` is unused in crate `{$local_crate}`")] |
| 2999 | 2999 | #[help("remove the dependency or add `use {$extern_crate} as _;` to the crate root")] |
| 3000 | 3000 | pub(crate) struct UnusedCrateDependency { |
| ... | ... | @@ -3003,7 +3003,7 @@ pub(crate) struct UnusedCrateDependency { |
| 3003 | 3003 | } |
| 3004 | 3004 | |
| 3005 | 3005 | // FIXME(jdonszelmann): duplicated in rustc_attr_parsing, should be moved there completely. |
| 3006 | #[derive(LintDiagnostic)] | |
| 3006 | #[derive(Diagnostic)] | |
| 3007 | 3007 | #[diag( |
| 3008 | 3008 | "{$num_suggestions -> |
| 3009 | 3009 | [1] attribute must be of the form {$suggestions} |
| ... | ... | @@ -3018,7 +3018,7 @@ pub(crate) struct IllFormedAttributeInput { |
| 3018 | 3018 | pub docs: &'static str, |
| 3019 | 3019 | } |
| 3020 | 3020 | |
| 3021 | #[derive(LintDiagnostic)] | |
| 3021 | #[derive(Diagnostic)] | |
| 3022 | 3022 | #[diag("unicode codepoint changing visible direction of text present in comment")] |
| 3023 | 3023 | #[note( |
| 3024 | 3024 | "these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen" |
| ... | ... | @@ -3058,7 +3058,7 @@ pub(crate) struct UnicodeTextFlowSuggestion { |
| 3058 | 3058 | pub spans: Vec<Span>, |
| 3059 | 3059 | } |
| 3060 | 3060 | |
| 3061 | #[derive(LintDiagnostic)] | |
| 3061 | #[derive(Diagnostic)] | |
| 3062 | 3062 | #[diag( |
| 3063 | 3063 | "absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition" |
| 3064 | 3064 | )] |
| ... | ... | @@ -3077,14 +3077,14 @@ pub(crate) struct AbsPathWithModuleSugg { |
| 3077 | 3077 | pub replacement: String, |
| 3078 | 3078 | } |
| 3079 | 3079 | |
| 3080 | #[derive(LintDiagnostic)] | |
| 3080 | #[derive(Diagnostic)] | |
| 3081 | 3081 | #[diag("hidden lifetime parameters in types are deprecated")] |
| 3082 | 3082 | pub(crate) struct ElidedLifetimesInPaths { |
| 3083 | 3083 | #[subdiagnostic] |
| 3084 | 3084 | pub subdiag: ElidedLifetimeInPathSubdiag, |
| 3085 | 3085 | } |
| 3086 | 3086 | |
| 3087 | #[derive(LintDiagnostic)] | |
| 3087 | #[derive(Diagnostic)] | |
| 3088 | 3088 | #[diag( |
| 3089 | 3089 | "{$num_snippets -> |
| 3090 | 3090 | [one] unused import: {$span_snippets} |
| ... | ... | @@ -3128,7 +3128,7 @@ pub(crate) enum UnusedImportsSugg { |
| 3128 | 3128 | }, |
| 3129 | 3129 | } |
| 3130 | 3130 | |
| 3131 | #[derive(LintDiagnostic)] | |
| 3131 | #[derive(Diagnostic)] | |
| 3132 | 3132 | #[diag("the item `{$ident}` is imported redundantly")] |
| 3133 | 3133 | pub(crate) struct RedundantImport { |
| 3134 | 3134 | #[subdiagnostic] |
| ... | ... | @@ -3164,7 +3164,7 @@ pub(crate) enum RedundantImportSub { |
| 3164 | 3164 | }, |
| 3165 | 3165 | } |
| 3166 | 3166 | |
| 3167 | #[derive(LintDiagnostic)] | |
| 3167 | #[derive(Diagnostic)] | |
| 3168 | 3168 | pub(crate) enum PatternsInFnsWithoutBody { |
| 3169 | 3169 | #[diag("patterns aren't allowed in foreign function declarations")] |
| 3170 | 3170 | Foreign { |
| ... | ... | @@ -3191,7 +3191,7 @@ pub(crate) struct PatternsInFnsWithoutBodySub { |
| 3191 | 3191 | pub ident: Ident, |
| 3192 | 3192 | } |
| 3193 | 3193 | |
| 3194 | #[derive(LintDiagnostic)] | |
| 3194 | #[derive(Diagnostic)] | |
| 3195 | 3195 | #[diag("prefix `{$prefix}` is unknown")] |
| 3196 | 3196 | pub(crate) struct ReservedPrefix { |
| 3197 | 3197 | #[label("unknown prefix")] |
| ... | ... | @@ -3206,7 +3206,7 @@ pub(crate) struct ReservedPrefix { |
| 3206 | 3206 | pub prefix: String, |
| 3207 | 3207 | } |
| 3208 | 3208 | |
| 3209 | #[derive(LintDiagnostic)] | |
| 3209 | #[derive(Diagnostic)] | |
| 3210 | 3210 | #[diag("prefix `'r` is reserved")] |
| 3211 | 3211 | pub(crate) struct RawPrefix { |
| 3212 | 3212 | #[label("reserved prefix")] |
| ... | ... | @@ -3219,7 +3219,7 @@ pub(crate) struct RawPrefix { |
| 3219 | 3219 | pub suggestion: Span, |
| 3220 | 3220 | } |
| 3221 | 3221 | |
| 3222 | #[derive(LintDiagnostic)] | |
| 3222 | #[derive(Diagnostic)] | |
| 3223 | 3223 | #[diag( |
| 3224 | 3224 | "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression" |
| 3225 | 3225 | )] |
| ... | ... | @@ -3237,7 +3237,7 @@ pub(crate) struct BreakWithLabelAndLoopSub { |
| 3237 | 3237 | pub right: Span, |
| 3238 | 3238 | } |
| 3239 | 3239 | |
| 3240 | #[derive(LintDiagnostic)] | |
| 3240 | #[derive(Diagnostic)] | |
| 3241 | 3241 | #[diag("where clause not allowed here")] |
| 3242 | 3242 | #[note("see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information")] |
| 3243 | 3243 | pub(crate) struct DeprecatedWhereClauseLocation { |
| ... | ... | @@ -3266,7 +3266,7 @@ pub(crate) enum DeprecatedWhereClauseLocationSugg { |
| 3266 | 3266 | }, |
| 3267 | 3267 | } |
| 3268 | 3268 | |
| 3269 | #[derive(LintDiagnostic)] | |
| 3269 | #[derive(Diagnostic)] | |
| 3270 | 3270 | #[diag("lifetime parameter `{$ident}` only used once")] |
| 3271 | 3271 | pub(crate) struct SingleUseLifetime { |
| 3272 | 3272 | #[label("this lifetime...")] |
| ... | ... | @@ -3290,7 +3290,7 @@ pub(crate) struct SingleUseLifetimeSugg { |
| 3290 | 3290 | pub replace_lt: String, |
| 3291 | 3291 | } |
| 3292 | 3292 | |
| 3293 | #[derive(LintDiagnostic)] | |
| 3293 | #[derive(Diagnostic)] | |
| 3294 | 3294 | #[diag("lifetime parameter `{$ident}` never used")] |
| 3295 | 3295 | pub(crate) struct UnusedLifetime { |
| 3296 | 3296 | #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] |
| ... | ... | @@ -3299,7 +3299,7 @@ pub(crate) struct UnusedLifetime { |
| 3299 | 3299 | pub ident: Ident, |
| 3300 | 3300 | } |
| 3301 | 3301 | |
| 3302 | #[derive(LintDiagnostic)] | |
| 3302 | #[derive(Diagnostic)] | |
| 3303 | 3303 | #[diag("named argument `{$named_arg_name}` is not used by name")] |
| 3304 | 3304 | pub(crate) struct NamedArgumentUsedPositionally { |
| 3305 | 3305 | #[label("this named argument is referred to by position in formatting string")] |
| ... | ... | @@ -3318,7 +3318,7 @@ pub(crate) struct NamedArgumentUsedPositionally { |
| 3318 | 3318 | pub named_arg_name: String, |
| 3319 | 3319 | } |
| 3320 | 3320 | |
| 3321 | #[derive(LintDiagnostic)] | |
| 3321 | #[derive(Diagnostic)] | |
| 3322 | 3322 | #[diag("ambiguous glob re-exports")] |
| 3323 | 3323 | pub(crate) struct AmbiguousGlobReexports { |
| 3324 | 3324 | #[label("the name `{$name}` in the {$namespace} namespace is first re-exported here")] |
| ... | ... | @@ -3330,7 +3330,7 @@ pub(crate) struct AmbiguousGlobReexports { |
| 3330 | 3330 | pub namespace: String, |
| 3331 | 3331 | } |
| 3332 | 3332 | |
| 3333 | #[derive(LintDiagnostic)] | |
| 3333 | #[derive(Diagnostic)] | |
| 3334 | 3334 | #[diag("private item shadows public glob re-export")] |
| 3335 | 3335 | pub(crate) struct HiddenGlobReexports { |
| 3336 | 3336 | #[note( |
| ... | ... | @@ -3344,7 +3344,7 @@ pub(crate) struct HiddenGlobReexports { |
| 3344 | 3344 | pub namespace: String, |
| 3345 | 3345 | } |
| 3346 | 3346 | |
| 3347 | #[derive(LintDiagnostic)] | |
| 3347 | #[derive(Diagnostic)] | |
| 3348 | 3348 | #[diag("unnecessary qualification")] |
| 3349 | 3349 | pub(crate) struct UnusedQualifications { |
| 3350 | 3350 | #[suggestion( |
| ... | ... | @@ -3356,7 +3356,7 @@ pub(crate) struct UnusedQualifications { |
| 3356 | 3356 | pub removal_span: Span, |
| 3357 | 3357 | } |
| 3358 | 3358 | |
| 3359 | #[derive(LintDiagnostic)] | |
| 3359 | #[derive(Diagnostic)] | |
| 3360 | 3360 | #[diag( |
| 3361 | 3361 | "{$elided -> |
| 3362 | 3362 | [true] `&` without an explicit lifetime name cannot be used here |
| ... | ... | @@ -3422,7 +3422,7 @@ pub(crate) enum MutRefSugg { |
| 3422 | 3422 | #[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")] |
| 3423 | 3423 | pub(crate) struct UnqualifiedLocalImportsDiag; |
| 3424 | 3424 | |
| 3425 | #[derive(LintDiagnostic)] | |
| 3425 | #[derive(Diagnostic)] | |
| 3426 | 3426 | #[diag("will be parsed as a guarded string in Rust 2024")] |
| 3427 | 3427 | pub(crate) struct ReservedString { |
| 3428 | 3428 | #[suggestion( |
| ... | ... | @@ -3433,7 +3433,7 @@ pub(crate) struct ReservedString { |
| 3433 | 3433 | pub suggestion: Span, |
| 3434 | 3434 | } |
| 3435 | 3435 | |
| 3436 | #[derive(LintDiagnostic)] | |
| 3436 | #[derive(Diagnostic)] | |
| 3437 | 3437 | #[diag("reserved token in Rust 2024")] |
| 3438 | 3438 | pub(crate) struct ReservedMultihash { |
| 3439 | 3439 | #[suggestion( |
| ... | ... | @@ -3642,7 +3642,7 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { |
| 3642 | 3642 | } |
| 3643 | 3643 | } |
| 3644 | 3644 | |
| 3645 | #[derive(LintDiagnostic)] | |
| 3645 | #[derive(Diagnostic)] | |
| 3646 | 3646 | #[diag("unused attribute")] |
| 3647 | 3647 | #[note( |
| 3648 | 3648 | "{$valid_without_list -> |
| ... | ... | @@ -3664,7 +3664,7 @@ pub(crate) struct EmptyAttributeList { |
| 3664 | 3664 | pub valid_without_list: bool, |
| 3665 | 3665 | } |
| 3666 | 3666 | |
| 3667 | #[derive(LintDiagnostic)] | |
| 3667 | #[derive(Diagnostic)] | |
| 3668 | 3668 | #[diag("`#[{$name}]` attribute cannot be used on {$target}")] |
| 3669 | 3669 | #[warning( |
| 3670 | 3670 | "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" |
| ... | ... | @@ -3684,7 +3684,7 @@ pub(crate) struct InvalidTargetLint { |
| 3684 | 3684 | pub attr_span: Span, |
| 3685 | 3685 | } |
| 3686 | 3686 | |
| 3687 | #[derive(LintDiagnostic)] | |
| 3687 | #[derive(Diagnostic)] | |
| 3688 | 3688 | #[diag( |
| 3689 | 3689 | "{$is_used_as_inner -> |
| 3690 | 3690 | [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` |
| ... | ... | @@ -3699,7 +3699,7 @@ pub(crate) struct InvalidAttrStyle { |
| 3699 | 3699 | pub target: &'static str, |
| 3700 | 3700 | } |
| 3701 | 3701 | |
| 3702 | #[derive(LintDiagnostic)] | |
| 3702 | #[derive(Diagnostic)] | |
| 3703 | 3703 | #[diag("unused attribute")] |
| 3704 | 3704 | pub(crate) struct UnusedDuplicate { |
| 3705 | 3705 | #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] |
| ... | ... | @@ -3712,28 +3712,28 @@ pub(crate) struct UnusedDuplicate { |
| 3712 | 3712 | pub warning: bool, |
| 3713 | 3713 | } |
| 3714 | 3714 | |
| 3715 | #[derive(LintDiagnostic)] | |
| 3715 | #[derive(Diagnostic)] | |
| 3716 | 3716 | #[diag("malformed `doc` attribute input")] |
| 3717 | 3717 | #[warning( |
| 3718 | 3718 | "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" |
| 3719 | 3719 | )] |
| 3720 | 3720 | pub(crate) struct MalformedDoc; |
| 3721 | 3721 | |
| 3722 | #[derive(LintDiagnostic)] | |
| 3722 | #[derive(Diagnostic)] | |
| 3723 | 3723 | #[diag("didn't expect any arguments here")] |
| 3724 | 3724 | #[warning( |
| 3725 | 3725 | "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" |
| 3726 | 3726 | )] |
| 3727 | 3727 | pub(crate) struct ExpectedNoArgs; |
| 3728 | 3728 | |
| 3729 | #[derive(LintDiagnostic)] | |
| 3729 | #[derive(Diagnostic)] | |
| 3730 | 3730 | #[diag("expected this to be of the form `... = \"...\"`")] |
| 3731 | 3731 | #[warning( |
| 3732 | 3732 | "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" |
| 3733 | 3733 | )] |
| 3734 | 3734 | pub(crate) struct ExpectedNameValue; |
| 3735 | 3735 | |
| 3736 | #[derive(LintDiagnostic)] | |
| 3736 | #[derive(Diagnostic)] | |
| 3737 | 3737 | #[diag("unsafe attribute used without unsafe")] |
| 3738 | 3738 | pub(crate) struct UnsafeAttrOutsideUnsafeLint { |
| 3739 | 3739 | #[label("usage of unsafe attribute")] |
| ... | ... | @@ -3751,7 +3751,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { |
| 3751 | 3751 | pub right: Span, |
| 3752 | 3752 | } |
| 3753 | 3753 | |
| 3754 | #[derive(LintDiagnostic)] | |
| 3754 | #[derive(Diagnostic)] | |
| 3755 | 3755 | #[diag("visibility qualifiers have no effect on `const _` declarations")] |
| 3756 | 3756 | #[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] |
| 3757 | 3757 | pub(crate) struct UnusedVisibility { |
| ... | ... | @@ -3764,38 +3764,38 @@ pub(crate) struct UnusedVisibility { |
| 3764 | 3764 | pub span: Span, |
| 3765 | 3765 | } |
| 3766 | 3766 | |
| 3767 | #[derive(LintDiagnostic)] | |
| 3767 | #[derive(Diagnostic)] | |
| 3768 | 3768 | #[diag("doc alias is duplicated")] |
| 3769 | 3769 | pub(crate) struct DocAliasDuplicated { |
| 3770 | 3770 | #[label("first defined here")] |
| 3771 | 3771 | pub first_defn: Span, |
| 3772 | 3772 | } |
| 3773 | 3773 | |
| 3774 | #[derive(LintDiagnostic)] | |
| 3774 | #[derive(Diagnostic)] | |
| 3775 | 3775 | #[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")] |
| 3776 | 3776 | pub(crate) struct DocAutoCfgExpectsHideOrShow; |
| 3777 | 3777 | |
| 3778 | #[derive(LintDiagnostic)] | |
| 3778 | #[derive(Diagnostic)] | |
| 3779 | 3779 | #[diag("there exists a built-in attribute with the same name")] |
| 3780 | 3780 | pub(crate) struct AmbiguousDeriveHelpers; |
| 3781 | 3781 | |
| 3782 | #[derive(LintDiagnostic)] | |
| 3782 | #[derive(Diagnostic)] | |
| 3783 | 3783 | #[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items")] |
| 3784 | 3784 | pub(crate) struct DocAutoCfgHideShowUnexpectedItem { |
| 3785 | 3785 | pub attr_name: Symbol, |
| 3786 | 3786 | } |
| 3787 | 3787 | |
| 3788 | #[derive(LintDiagnostic)] | |
| 3788 | #[derive(Diagnostic)] | |
| 3789 | 3789 | #[diag("`#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items")] |
| 3790 | 3790 | pub(crate) struct DocAutoCfgHideShowExpectsList { |
| 3791 | 3791 | pub attr_name: Symbol, |
| 3792 | 3792 | } |
| 3793 | 3793 | |
| 3794 | #[derive(LintDiagnostic)] | |
| 3794 | #[derive(Diagnostic)] | |
| 3795 | 3795 | #[diag("invalid `doc` attribute")] |
| 3796 | 3796 | pub(crate) struct DocInvalid; |
| 3797 | 3797 | |
| 3798 | #[derive(LintDiagnostic)] | |
| 3798 | #[derive(Diagnostic)] | |
| 3799 | 3799 | #[diag("unknown `doc` attribute `include`")] |
| 3800 | 3800 | pub(crate) struct DocUnknownInclude { |
| 3801 | 3801 | pub inner: &'static str, |
| ... | ... | @@ -3807,7 +3807,7 @@ pub(crate) struct DocUnknownInclude { |
| 3807 | 3807 | pub sugg: (Span, Applicability), |
| 3808 | 3808 | } |
| 3809 | 3809 | |
| 3810 | #[derive(LintDiagnostic)] | |
| 3810 | #[derive(Diagnostic)] | |
| 3811 | 3811 | #[diag("unknown `doc` attribute `spotlight`")] |
| 3812 | 3812 | #[note("`doc(spotlight)` was renamed to `doc(notable_trait)`")] |
| 3813 | 3813 | #[note("`doc(spotlight)` is now a no-op")] |
| ... | ... | @@ -3821,7 +3821,7 @@ pub(crate) struct DocUnknownSpotlight { |
| 3821 | 3821 | pub sugg_span: Span, |
| 3822 | 3822 | } |
| 3823 | 3823 | |
| 3824 | #[derive(LintDiagnostic)] | |
| 3824 | #[derive(Diagnostic)] | |
| 3825 | 3825 | #[diag("unknown `doc` attribute `{$name}`")] |
| 3826 | 3826 | #[note( |
| 3827 | 3827 | "`doc` attribute `{$name}` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136>" |
| ... | ... | @@ -3833,7 +3833,7 @@ pub(crate) struct DocUnknownPasses { |
| 3833 | 3833 | pub note_span: Span, |
| 3834 | 3834 | } |
| 3835 | 3835 | |
| 3836 | #[derive(LintDiagnostic)] | |
| 3836 | #[derive(Diagnostic)] | |
| 3837 | 3837 | #[diag("unknown `doc` attribute `plugins`")] |
| 3838 | 3838 | #[note( |
| 3839 | 3839 | "`doc` attribute `plugins` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> and CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622>" |
| ... | ... | @@ -3844,42 +3844,42 @@ pub(crate) struct DocUnknownPlugins { |
| 3844 | 3844 | pub label_span: Span, |
| 3845 | 3845 | } |
| 3846 | 3846 | |
| 3847 | #[derive(LintDiagnostic)] | |
| 3847 | #[derive(Diagnostic)] | |
| 3848 | 3848 | #[diag("unknown `doc` attribute `{$name}`")] |
| 3849 | 3849 | pub(crate) struct DocUnknownAny { |
| 3850 | 3850 | pub name: Symbol, |
| 3851 | 3851 | } |
| 3852 | 3852 | |
| 3853 | #[derive(LintDiagnostic)] | |
| 3853 | #[derive(Diagnostic)] | |
| 3854 | 3854 | #[diag("expected boolean for `#[doc(auto_cfg = ...)]`")] |
| 3855 | 3855 | pub(crate) struct DocAutoCfgWrongLiteral; |
| 3856 | 3856 | |
| 3857 | #[derive(LintDiagnostic)] | |
| 3857 | #[derive(Diagnostic)] | |
| 3858 | 3858 | #[diag("`#[doc(test(...)]` takes a list of attributes")] |
| 3859 | 3859 | pub(crate) struct DocTestTakesList; |
| 3860 | 3860 | |
| 3861 | #[derive(LintDiagnostic)] | |
| 3861 | #[derive(Diagnostic)] | |
| 3862 | 3862 | #[diag("unknown `doc(test)` attribute `{$name}`")] |
| 3863 | 3863 | pub(crate) struct DocTestUnknown { |
| 3864 | 3864 | pub name: Symbol, |
| 3865 | 3865 | } |
| 3866 | 3866 | |
| 3867 | #[derive(LintDiagnostic)] | |
| 3867 | #[derive(Diagnostic)] | |
| 3868 | 3868 | #[diag("`#![doc(test(...)]` does not take a literal")] |
| 3869 | 3869 | pub(crate) struct DocTestLiteral; |
| 3870 | 3870 | |
| 3871 | #[derive(LintDiagnostic)] | |
| 3871 | #[derive(Diagnostic)] | |
| 3872 | 3872 | #[diag("this attribute can only be applied at the crate level")] |
| 3873 | 3873 | #[note( |
| 3874 | 3874 | "read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information" |
| 3875 | 3875 | )] |
| 3876 | 3876 | pub(crate) struct AttrCrateLevelOnly; |
| 3877 | 3877 | |
| 3878 | #[derive(LintDiagnostic)] | |
| 3878 | #[derive(Diagnostic)] | |
| 3879 | 3879 | #[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] |
| 3880 | 3880 | pub(crate) struct DoNotRecommendDoesNotExpectArgs; |
| 3881 | 3881 | |
| 3882 | #[derive(LintDiagnostic)] | |
| 3882 | #[derive(Diagnostic)] | |
| 3883 | 3883 | #[diag("invalid `crate_type` value")] |
| 3884 | 3884 | pub(crate) struct UnknownCrateTypes { |
| 3885 | 3885 | #[subdiagnostic] |
| ... | ... | @@ -3894,14 +3894,14 @@ pub(crate) struct UnknownCrateTypesSuggestion { |
| 3894 | 3894 | pub snippet: Symbol, |
| 3895 | 3895 | } |
| 3896 | 3896 | |
| 3897 | #[derive(LintDiagnostic)] | |
| 3897 | #[derive(Diagnostic)] | |
| 3898 | 3898 | #[diag("unreachable configuration predicate")] |
| 3899 | 3899 | pub(crate) struct UnreachableCfgSelectPredicate { |
| 3900 | 3900 | #[label("this configuration predicate is never reached")] |
| 3901 | 3901 | pub span: Span, |
| 3902 | 3902 | } |
| 3903 | 3903 | |
| 3904 | #[derive(LintDiagnostic)] | |
| 3904 | #[derive(Diagnostic)] | |
| 3905 | 3905 | #[diag("unreachable configuration predicate")] |
| 3906 | 3906 | pub(crate) struct UnreachableCfgSelectPredicateWildcard { |
| 3907 | 3907 | #[label("this configuration predicate is never reached")] |
| ... | ... | @@ -3911,19 +3911,19 @@ pub(crate) struct UnreachableCfgSelectPredicateWildcard { |
| 3911 | 3911 | pub wildcard_span: Span, |
| 3912 | 3912 | } |
| 3913 | 3913 | |
| 3914 | #[derive(LintDiagnostic)] | |
| 3914 | #[derive(Diagnostic)] | |
| 3915 | 3915 | #[diag("positional format arguments are not allowed here")] |
| 3916 | 3916 | #[help( |
| 3917 | 3917 | "only named format arguments with the name of one of the generic types are allowed in this context" |
| 3918 | 3918 | )] |
| 3919 | 3919 | pub(crate) struct DisallowedPositionalArgument; |
| 3920 | 3920 | |
| 3921 | #[derive(LintDiagnostic)] | |
| 3921 | #[derive(Diagnostic)] | |
| 3922 | 3922 | #[diag("invalid format specifier")] |
| 3923 | 3923 | #[help("no format specifier are supported in this position")] |
| 3924 | 3924 | pub(crate) struct InvalidFormatSpecifier; |
| 3925 | 3925 | |
| 3926 | #[derive(LintDiagnostic)] | |
| 3926 | #[derive(Diagnostic)] | |
| 3927 | 3927 | #[diag("{$description}")] |
| 3928 | 3928 | pub(crate) struct WrappedParserError<'a> { |
| 3929 | 3929 | pub description: &'a str, |
| ... | ... | @@ -3932,7 +3932,7 @@ pub(crate) struct WrappedParserError<'a> { |
| 3932 | 3932 | pub label: &'a str, |
| 3933 | 3933 | } |
| 3934 | 3934 | |
| 3935 | #[derive(LintDiagnostic)] | |
| 3935 | #[derive(Diagnostic)] | |
| 3936 | 3936 | #[diag("`{$option_name}` is ignored due to previous definition of `{$option_name}`")] |
| 3937 | 3937 | pub(crate) struct IgnoredDiagnosticOption { |
| 3938 | 3938 | pub option_name: Symbol, |
| ... | ... | @@ -3942,17 +3942,17 @@ pub(crate) struct IgnoredDiagnosticOption { |
| 3942 | 3942 | pub later_span: Span, |
| 3943 | 3943 | } |
| 3944 | 3944 | |
| 3945 | #[derive(LintDiagnostic)] | |
| 3945 | #[derive(Diagnostic)] | |
| 3946 | 3946 | #[diag("missing options for `on_unimplemented` attribute")] |
| 3947 | 3947 | #[help("at least one of the `message`, `note` and `label` options are expected")] |
| 3948 | 3948 | pub(crate) struct MissingOptionsForOnUnimplementedAttr; |
| 3949 | 3949 | |
| 3950 | #[derive(LintDiagnostic)] | |
| 3950 | #[derive(Diagnostic)] | |
| 3951 | 3951 | #[diag("missing options for `on_const` attribute")] |
| 3952 | 3952 | #[help("at least one of the `message`, `note` and `label` options are expected")] |
| 3953 | 3953 | pub(crate) struct MissingOptionsForOnConstAttr; |
| 3954 | 3954 | |
| 3955 | #[derive(LintDiagnostic)] | |
| 3955 | #[derive(Diagnostic)] | |
| 3956 | 3956 | #[diag("malformed `on_unimplemented` attribute")] |
| 3957 | 3957 | #[help("only `message`, `note` and `label` are allowed as options")] |
| 3958 | 3958 | pub(crate) struct MalformedOnUnimplementedAttrLint { |
| ... | ... | @@ -3960,7 +3960,7 @@ pub(crate) struct MalformedOnUnimplementedAttrLint { |
| 3960 | 3960 | pub span: Span, |
| 3961 | 3961 | } |
| 3962 | 3962 | |
| 3963 | #[derive(LintDiagnostic)] | |
| 3963 | #[derive(Diagnostic)] | |
| 3964 | 3964 | #[diag("malformed `on_const` attribute")] |
| 3965 | 3965 | #[help("only `message`, `note` and `label` are allowed as options")] |
| 3966 | 3966 | pub(crate) struct MalformedOnConstAttrLint { |
compiler/rustc_lint/src/nonstandard_style.rs+21-3| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | use rustc_abi::ExternAbi; |
| 2 | 2 | use rustc_attr_parsing::AttributeParser; |
| 3 | use rustc_errors::Applicability; | |
| 3 | use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level}; | |
| 4 | 4 | use rustc_hir::attrs::{AttributeKind, ReprAttr}; |
| 5 | 5 | use rustc_hir::def::{DefKind, Res}; |
| 6 | 6 | use rustc_hir::def_id::DefId; |
| ... | ... | @@ -461,6 +461,19 @@ declare_lint! { |
| 461 | 461 | |
| 462 | 462 | declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]); |
| 463 | 463 | |
| 464 | struct NonUpperCaseGlobalGenerator<'a, F: FnOnce() -> NonUpperCaseGlobal<'a>> { | |
| 465 | callback: F, | |
| 466 | } | |
| 467 | ||
| 468 | impl<'a, 'b, F: FnOnce() -> NonUpperCaseGlobal<'b>> Diagnostic<'a, ()> | |
| 469 | for NonUpperCaseGlobalGenerator<'b, F> | |
| 470 | { | |
| 471 | fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { | |
| 472 | let Self { callback } = self; | |
| 473 | callback().into_diag(dcx, level) | |
| 474 | } | |
| 475 | } | |
| 476 | ||
| 464 | 477 | impl NonUpperCaseGlobals { |
| 465 | 478 | fn check_upper_case(cx: &LateContext<'_>, sort: &str, did: Option<LocalDefId>, ident: &Ident) { |
| 466 | 479 | let name = ident.name.as_str(); |
| ... | ... | @@ -517,7 +530,7 @@ impl NonUpperCaseGlobals { |
| 517 | 530 | } |
| 518 | 531 | } |
| 519 | 532 | |
| 520 | cx.emit_span_lint_lazy(NON_UPPER_CASE_GLOBALS, ident.span, || { | |
| 533 | let callback = || { | |
| 521 | 534 | // Compute usages lazily as it can expansive and useless when the lint is allowed. |
| 522 | 535 | // cf. https://github.com/rust-lang/rust/pull/142645#issuecomment-2993024625 |
| 523 | 536 | let usages = if can_change_usages |
| ... | ... | @@ -537,7 +550,12 @@ impl NonUpperCaseGlobals { |
| 537 | 550 | }; |
| 538 | 551 | |
| 539 | 552 | NonUpperCaseGlobal { sort, name, sub, usages } |
| 540 | }); | |
| 553 | }; | |
| 554 | cx.emit_span_lint( | |
| 555 | NON_UPPER_CASE_GLOBALS, | |
| 556 | ident.span, | |
| 557 | NonUpperCaseGlobalGenerator { callback }, | |
| 558 | ); | |
| 541 | 559 | } |
| 542 | 560 | } |
| 543 | 561 | } |
compiler/rustc_mir_build/src/thir/cx/expr.rs+6-2| ... | ... | @@ -632,7 +632,8 @@ impl<'tcx> ThirBuildCx<'tcx> { |
| 632 | 632 | .collect(), |
| 633 | 633 | ) |
| 634 | 634 | } |
| 635 | hir::StructTailExpr::None => AdtExprBase::None, | |
| 635 | hir::StructTailExpr::None | |
| 636 | | hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None, | |
| 636 | 637 | }, |
| 637 | 638 | })) |
| 638 | 639 | } |
| ... | ... | @@ -669,7 +670,10 @@ impl<'tcx> ThirBuildCx<'tcx> { |
| 669 | 670 | hir::StructTailExpr::Base(base) => { |
| 670 | 671 | span_bug!(base.span, "unexpected res: {:?}", res); |
| 671 | 672 | } |
| 672 | hir::StructTailExpr::None => AdtExprBase::None, | |
| 673 | hir::StructTailExpr::None | |
| 674 | | hir::StructTailExpr::NoneWithError(_) => { | |
| 675 | AdtExprBase::None | |
| 676 | } | |
| 673 | 677 | }, |
| 674 | 678 | })) |
| 675 | 679 | } |
compiler/rustc_parse/src/parser/expr.rs+13| ... | ... | @@ -3842,6 +3842,15 @@ impl<'a> Parser<'a> { |
| 3842 | 3842 | recovered_async = Some(guar); |
| 3843 | 3843 | } |
| 3844 | 3844 | |
| 3845 | // If we encountered an error which we are recovering from, treat the struct | |
| 3846 | // as if it has a `..` in it, because we don’t know what fields the user | |
| 3847 | // might have *intended* it to have. | |
| 3848 | // | |
| 3849 | // This assignment will be overwritten if we actually parse a `..` later. | |
| 3850 | // | |
| 3851 | // (Note that this code is duplicated between here and below in comma parsing. | |
| 3852 | base = ast::StructRest::NoneWithError(guar); | |
| 3853 | ||
| 3845 | 3854 | // If the next token is a comma, then try to parse |
| 3846 | 3855 | // what comes next as additional fields, rather than |
| 3847 | 3856 | // bailing out until next `}`. |
| ... | ... | @@ -3892,6 +3901,10 @@ impl<'a> Parser<'a> { |
| 3892 | 3901 | } else if let Some(f) = field_ident(self, guar) { |
| 3893 | 3902 | fields.push(f); |
| 3894 | 3903 | } |
| 3904 | ||
| 3905 | // See comment above on this same assignment inside of field parsing. | |
| 3906 | base = ast::StructRest::NoneWithError(guar); | |
| 3907 | ||
| 3895 | 3908 | self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore); |
| 3896 | 3909 | let _ = self.eat(exp!(Comma)); |
| 3897 | 3910 | } |
compiler/rustc_privacy/src/lib.rs+1-1| ... | ... | @@ -1100,7 +1100,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { |
| 1100 | 1100 | qpath.span(), |
| 1101 | 1101 | ); |
| 1102 | 1102 | } |
| 1103 | hir::StructTailExpr::None => { | |
| 1103 | hir::StructTailExpr::None | hir::StructTailExpr::NoneWithError(_) => { | |
| 1104 | 1104 | let mut failed_fields = vec![]; |
| 1105 | 1105 | for field in fields { |
| 1106 | 1106 | let (hir_id, use_ctxt) = (field.hir_id, field.ident.span); |
compiler/rustc_resolve/src/late.rs+1-1| ... | ... | @@ -5066,7 +5066,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 5066 | 5066 | match &se.rest { |
| 5067 | 5067 | StructRest::Base(expr) => self.visit_expr(expr), |
| 5068 | 5068 | StructRest::Rest(_span) => {} |
| 5069 | StructRest::None => {} | |
| 5069 | StructRest::None | StructRest::NoneWithError(_) => {} | |
| 5070 | 5070 | } |
| 5071 | 5071 | } |
| 5072 | 5072 |
compiler/rustc_target/src/callconv/aarch64.rs+3-3| ... | ... | @@ -3,7 +3,7 @@ use std::iter; |
| 3 | 3 | use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface}; |
| 4 | 4 | |
| 5 | 5 | use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; |
| 6 | use crate::spec::{Abi, HasTargetSpec, Target}; | |
| 6 | use crate::spec::{HasTargetSpec, RustcAbi, Target}; | |
| 7 | 7 | |
| 8 | 8 | /// Indicates the variant of the AArch64 ABI we are compiling for. |
| 9 | 9 | /// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI. |
| ... | ... | @@ -34,7 +34,7 @@ where |
| 34 | 34 | RegKind::Integer => false, |
| 35 | 35 | // The softfloat ABI treats floats like integers, so they |
| 36 | 36 | // do not get homogeneous aggregate treatment. |
| 37 | RegKind::Float => cx.target_spec().abi != Abi::SoftFloat, | |
| 37 | RegKind::Float => cx.target_spec().rustc_abi != Some(RustcAbi::Softfloat), | |
| 38 | 38 | RegKind::Vector => size.bits() == 64 || size.bits() == 128, |
| 39 | 39 | }; |
| 40 | 40 | |
| ... | ... | @@ -43,7 +43,7 @@ where |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | fn softfloat_float_abi<Ty>(target: &Target, arg: &mut ArgAbi<'_, Ty>) { |
| 46 | if target.abi != Abi::SoftFloat { | |
| 46 | if target.rustc_abi != Some(RustcAbi::Softfloat) { | |
| 47 | 47 | return; |
| 48 | 48 | } |
| 49 | 49 | // Do *not* use the float registers for passing arguments, as that would make LLVM pick the ABI |
compiler/rustc_target/src/spec/mod.rs+6-4| ... | ... | @@ -2210,8 +2210,10 @@ pub struct TargetOptions { |
| 2210 | 2210 | pub env: Env, |
| 2211 | 2211 | /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"` |
| 2212 | 2212 | /// or `"eabihf"`. Defaults to [`Abi::Unspecified`]. |
| 2213 | /// This field is *not* forwarded directly to LLVM; its primary purpose is `cfg(target_abi)`. | |
| 2214 | /// However, parts of the backend do check this field for specific values to enable special behavior. | |
| 2213 | /// This field is *not* forwarded directly to LLVM and therefore does not control which ABI (in | |
| 2214 | /// the sense of function calling convention) is actually used; its primary purpose is | |
| 2215 | /// `cfg(target_abi)`. The actual calling convention is controlled by `llvm_abiname`, | |
| 2216 | /// `llvm_floatabi`, and `rustc_abi`. | |
| 2215 | 2217 | pub abi: Abi, |
| 2216 | 2218 | /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown". |
| 2217 | 2219 | #[rustc_lint_opt_deny_field_access( |
| ... | ... | @@ -3228,8 +3230,8 @@ impl Target { |
| 3228 | 3230 | ), |
| 3229 | 3231 | RustcAbi::Softfloat => check_matches!( |
| 3230 | 3232 | self.arch, |
| 3231 | Arch::X86 | Arch::X86_64 | Arch::S390x, | |
| 3232 | "`softfloat` ABI is only valid for x86 and s390x targets" | |
| 3233 | Arch::X86 | Arch::X86_64 | Arch::S390x | Arch::AArch64, | |
| 3234 | "`softfloat` ABI is only valid for x86, s390x, and aarch64 targets" | |
| 3233 | 3235 | ), |
| 3234 | 3236 | } |
| 3235 | 3237 | } |
compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs+3-2| ... | ... | @@ -8,13 +8,14 @@ |
| 8 | 8 | use rustc_abi::Endian; |
| 9 | 9 | |
| 10 | 10 | use crate::spec::{ |
| 11 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, | |
| 12 | Target, TargetMetadata, TargetOptions, | |
| 11 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, | |
| 12 | StackProbeType, Target, TargetMetadata, TargetOptions, | |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | 15 | pub(crate) fn target() -> Target { |
| 16 | 16 | let opts = TargetOptions { |
| 17 | 17 | abi: Abi::SoftFloat, |
| 18 | rustc_abi: Some(RustcAbi::Softfloat), | |
| 18 | 19 | linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), |
| 19 | 20 | linker: Some("rust-lld".into()), |
| 20 | 21 | features: "+v8a,+strict-align,-neon".into(), |
compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs+3-2| ... | ... | @@ -7,13 +7,14 @@ |
| 7 | 7 | // For example, `-C target-cpu=cortex-a53`. |
| 8 | 8 | |
| 9 | 9 | use crate::spec::{ |
| 10 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, | |
| 11 | Target, TargetMetadata, TargetOptions, | |
| 10 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, | |
| 11 | StackProbeType, Target, TargetMetadata, TargetOptions, | |
| 12 | 12 | }; |
| 13 | 13 | |
| 14 | 14 | pub(crate) fn target() -> Target { |
| 15 | 15 | let opts = TargetOptions { |
| 16 | 16 | abi: Abi::SoftFloat, |
| 17 | rustc_abi: Some(RustcAbi::Softfloat), | |
| 17 | 18 | linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), |
| 18 | 19 | linker: Some("rust-lld".into()), |
| 19 | 20 | features: "+v8a,+strict-align,-neon".into(), |
compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs+3-2| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | use crate::spec::{ |
| 2 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, | |
| 3 | Target, TargetMetadata, TargetOptions, | |
| 2 | Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, | |
| 3 | StackProbeType, Target, TargetMetadata, TargetOptions, | |
| 4 | 4 | }; |
| 5 | 5 | |
| 6 | 6 | pub(crate) fn target() -> Target { |
| 7 | 7 | let opts = TargetOptions { |
| 8 | 8 | abi: Abi::SoftFloat, |
| 9 | rustc_abi: Some(RustcAbi::Softfloat), | |
| 9 | 10 | linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), |
| 10 | 11 | linker: Some("rust-lld".into()), |
| 11 | 12 | relocation_model: RelocModel::Static, |
compiler/rustc_target/src/target_features.rs+16-12| ... | ... | @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; |
| 5 | 5 | use rustc_macros::HashStable_Generic; |
| 6 | 6 | use rustc_span::{Symbol, sym}; |
| 7 | 7 | |
| 8 | use crate::spec::{Abi, Arch, FloatAbi, RustcAbi, Target}; | |
| 8 | use crate::spec::{Arch, FloatAbi, RustcAbi, Target}; | |
| 9 | 9 | |
| 10 | 10 | /// Features that control behaviour of rustc, rather than the codegen. |
| 11 | 11 | /// These exist globally and are not in the target-specific lists below. |
| ... | ... | @@ -1154,17 +1154,21 @@ impl Target { |
| 1154 | 1154 | Arch::AArch64 | Arch::Arm64EC => { |
| 1155 | 1155 | // Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force |
| 1156 | 1156 | // the use of soft-float, so all we can do here is some crude hacks. |
| 1157 | if self.abi == Abi::SoftFloat { | |
| 1158 | // LLVM will use float registers when `fp-armv8` is available, e.g. for | |
| 1159 | // calls to built-ins. The only way to ensure a consistent softfloat ABI | |
| 1160 | // on aarch64 is to never enable `fp-armv8`, so we enforce that. | |
| 1161 | // In Rust we tie `neon` and `fp-armv8` together, therefore `neon` is the | |
| 1162 | // feature we have to mark as incompatible. | |
| 1163 | FeatureConstraints { required: &[], incompatible: &["neon"] } | |
| 1164 | } else { | |
| 1165 | // Everything else is assumed to use a hardfloat ABI. neon and fp-armv8 must be enabled. | |
| 1166 | // `FeatureConstraints` uses Rust feature names, hence only "neon" shows up. | |
| 1167 | FeatureConstraints { required: &["neon"], incompatible: &[] } | |
| 1157 | match self.rustc_abi { | |
| 1158 | Some(RustcAbi::Softfloat) => { | |
| 1159 | // LLVM will use float registers when `fp-armv8` is available, e.g. for | |
| 1160 | // calls to built-ins. The only way to ensure a consistent softfloat ABI | |
| 1161 | // on aarch64 is to never enable `fp-armv8`, so we enforce that. | |
| 1162 | // In Rust we tie `neon` and `fp-armv8` together, therefore `neon` is the | |
| 1163 | // feature we have to mark as incompatible. | |
| 1164 | FeatureConstraints { required: &[], incompatible: &["neon"] } | |
| 1165 | } | |
| 1166 | None => { | |
| 1167 | // Everything else is assumed to use a hardfloat ABI. neon and fp-armv8 must be enabled. | |
| 1168 | // `FeatureConstraints` uses Rust feature names, hence only "neon" shows up. | |
| 1169 | FeatureConstraints { required: &["neon"], incompatible: &[] } | |
| 1170 | } | |
| 1171 | Some(r) => panic!("invalid Rust ABI for aarch64: {r:?}"), | |
| 1168 | 1172 | } |
| 1169 | 1173 | } |
| 1170 | 1174 | Arch::RiscV32 | Arch::RiscV64 => { |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs-1| ... | ... | @@ -3883,7 +3883,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { |
| 3883 | 3883 | err.span_note(assoc_span, msg); |
| 3884 | 3884 | } |
| 3885 | 3885 | ObligationCauseCode::TrivialBound => { |
| 3886 | err.help("see issue #48214"); | |
| 3887 | 3886 | tcx.disabled_nightly_features(err, [(String::new(), sym::trivial_bounds)]); |
| 3888 | 3887 | } |
| 3889 | 3888 | ObligationCauseCode::OpaqueReturnType(expr_info) => { |
library/core/src/iter/traits/iterator.rs+23-7| ... | ... | @@ -631,8 +631,15 @@ pub const trait Iterator { |
| 631 | 631 | Zip::new(self, other.into_iter()) |
| 632 | 632 | } |
| 633 | 633 | |
| 634 | /// Creates a new iterator which places a copy of `separator` between adjacent | |
| 635 | /// items of the original iterator. | |
| 634 | /// Creates a new iterator which places a copy of `separator` between items | |
| 635 | /// of the original iterator. | |
| 636 | /// | |
| 637 | /// Specifically on fused iterators, it is guaranteed that the new iterator | |
| 638 | /// places a copy of `separator` between adjacent `Some(_)` items. However, | |
| 639 | /// for non-fused iterators, [`intersperse`] will create a new iterator that | |
| 640 | /// is a fused version of the original iterator and place a copy of `separator` | |
| 641 | /// between adjacent `Some(_)` items. This behavior for non-fused iterators | |
| 642 | /// is subject to change. | |
| 636 | 643 | /// |
| 637 | 644 | /// In case `separator` does not implement [`Clone`] or needs to be |
| 638 | 645 | /// computed every time, use [`intersperse_with`]. |
| ... | ... | @@ -663,6 +670,7 @@ pub const trait Iterator { |
| 663 | 670 | /// ``` |
| 664 | 671 | /// |
| 665 | 672 | /// [`Clone`]: crate::clone::Clone |
| 673 | /// [`intersperse`]: Iterator::intersperse | |
| 666 | 674 | /// [`intersperse_with`]: Iterator::intersperse_with |
| 667 | 675 | #[inline] |
| 668 | 676 | #[unstable(feature = "iter_intersperse", issue = "79524")] |
| ... | ... | @@ -676,12 +684,19 @@ pub const trait Iterator { |
| 676 | 684 | } |
| 677 | 685 | |
| 678 | 686 | /// Creates a new iterator which places an item generated by `separator` |
| 679 | /// between adjacent items of the original iterator. | |
| 687 | /// between items of the original iterator. | |
| 680 | 688 | /// |
| 681 | /// The closure will be called exactly once each time an item is placed | |
| 682 | /// between two adjacent items from the underlying iterator; specifically, | |
| 683 | /// the closure is not called if the underlying iterator yields less than | |
| 684 | /// two items and after the last item is yielded. | |
| 689 | /// Specifically on fused iterators, it is guaranteed that the new iterator | |
| 690 | /// places an item generated by `separator` between adjacent `Some(_)` items. | |
| 691 | /// However, for non-fused iterators, [`intersperse_with`] will create a new | |
| 692 | /// iterator that is a fused version of the original iterator and place an item | |
| 693 | /// generated by `separator` between adjacent `Some(_)` items. This | |
| 694 | /// behavior for non-fused iterators is subject to change. | |
| 695 | /// | |
| 696 | /// The `separator` closure will be called exactly once each time an item | |
| 697 | /// is placed between two adjacent items from the underlying iterator; | |
| 698 | /// specifically, the closure is not called if the underlying iterator yields | |
| 699 | /// less than two items and after the last item is yielded. | |
| 685 | 700 | /// |
| 686 | 701 | /// If the iterator's item implements [`Clone`], it may be easier to use |
| 687 | 702 | /// [`intersperse`]. |
| ... | ... | @@ -723,6 +738,7 @@ pub const trait Iterator { |
| 723 | 738 | /// ``` |
| 724 | 739 | /// [`Clone`]: crate::clone::Clone |
| 725 | 740 | /// [`intersperse`]: Iterator::intersperse |
| 741 | /// [`intersperse_with`]: Iterator::intersperse_with | |
| 726 | 742 | #[inline] |
| 727 | 743 | #[unstable(feature = "iter_intersperse", issue = "79524")] |
| 728 | 744 | #[rustc_non_const_trait_method] |
library/coretests/tests/iter/adapters/intersperse.rs+200| ... | ... | @@ -152,3 +152,203 @@ fn test_try_fold_specialization_intersperse_err() { |
| 152 | 152 | iter.try_for_each(|item| if item == "b" { None } else { Some(()) }); |
| 153 | 153 | assert_eq!(iter.next(), None); |
| 154 | 154 | } |
| 155 | ||
| 156 | // FIXME(iter_intersperse): `intersperse` current behavior may change for | |
| 157 | // non-fused iterators, so this test will likely have to | |
| 158 | // be adjusted; see PR #152855 and issue #79524 | |
| 159 | // if `intersperse` doesn't change, remove this FIXME. | |
| 160 | #[test] | |
| 161 | fn test_non_fused_iterator_intersperse() { | |
| 162 | #[derive(Debug)] | |
| 163 | struct TestCounter { | |
| 164 | counter: usize, | |
| 165 | } | |
| 166 | ||
| 167 | /// Given a counter of 0, this produces: | |
| 168 | /// `None` -> `Some(2)` -> `None` -> `Some(4)` -> `None` -> `Some(6)` | |
| 169 | /// -> and then `None` endlessly | |
| 170 | impl Iterator for TestCounter { | |
| 171 | type Item = usize; | |
| 172 | fn next(&mut self) -> Option<Self::Item> { | |
| 173 | if self.counter > 6 { | |
| 174 | None | |
| 175 | } else if self.counter % 2 == 0 { | |
| 176 | self.counter += 1; | |
| 177 | None | |
| 178 | } else { | |
| 179 | self.counter += 1; | |
| 180 | Some(self.counter) | |
| 181 | } | |
| 182 | } | |
| 183 | } | |
| 184 | ||
| 185 | let counter = 0; | |
| 186 | // places a 2 between `Some(_)` items | |
| 187 | let non_fused_iter = TestCounter { counter }; | |
| 188 | let mut intersperse_iter = non_fused_iter.intersperse(2); | |
| 189 | // Since `intersperse` currently transforms the original | |
| 190 | // iterator into a fused iterator, this intersperse_iter | |
| 191 | // should always have `None` | |
| 192 | for _ in 0..counter + 6 { | |
| 193 | assert_eq!(intersperse_iter.next(), None); | |
| 194 | } | |
| 195 | ||
| 196 | // Extra check to make sure it is `None` after processing 6 items | |
| 197 | assert_eq!(intersperse_iter.next(), None); | |
| 198 | } | |
| 199 | ||
| 200 | // FIXME(iter_intersperse): `intersperse` current behavior may change for | |
| 201 | // non-fused iterators, so this test will likely have to | |
| 202 | // be adjusted; see PR #152855 and issue #79524 | |
| 203 | // if `intersperse` doesn't change, remove this FIXME. | |
| 204 | #[test] | |
| 205 | fn test_non_fused_iterator_intersperse_2() { | |
| 206 | #[derive(Debug)] | |
| 207 | struct TestCounter { | |
| 208 | counter: usize, | |
| 209 | } | |
| 210 | ||
| 211 | // Given a counter of 0, this produces: | |
| 212 | // `Some(1)` -> `Some(2)` -> `None` -> `Some(4)` -> `Some(5)` -> | |
| 213 | // and then `None` endlessly | |
| 214 | impl Iterator for TestCounter { | |
| 215 | type Item = usize; | |
| 216 | fn next(&mut self) -> Option<Self::Item> { | |
| 217 | if self.counter < 5 { | |
| 218 | self.counter += 1; | |
| 219 | if self.counter % 3 != 0 { | |
| 220 | return Some(self.counter); | |
| 221 | } else { | |
| 222 | return None; | |
| 223 | } | |
| 224 | } | |
| 225 | self.counter += 1; | |
| 226 | None | |
| 227 | } | |
| 228 | } | |
| 229 | ||
| 230 | let counter = 0; | |
| 231 | // places a 2 between `Some(_)` items | |
| 232 | let non_fused_iter = TestCounter { counter }; | |
| 233 | let mut intersperse_iter = non_fused_iter.intersperse(2); | |
| 234 | // Since `intersperse` currently transforms the original | |
| 235 | // iterator into a fused iterator, this interspersed iter | |
| 236 | // will be `Some(1)` -> `Some(2)` -> `Some(2)` -> and then | |
| 237 | // `None` endlessly | |
| 238 | let mut items_processed = 0; | |
| 239 | for num in 0..counter + 6 { | |
| 240 | if num < 3 { | |
| 241 | if num % 2 != 0 { | |
| 242 | assert_eq!(intersperse_iter.next(), Some(2)); | |
| 243 | } else { | |
| 244 | items_processed += 1; | |
| 245 | assert_eq!(intersperse_iter.next(), Some(items_processed)); | |
| 246 | } | |
| 247 | } else { | |
| 248 | assert_eq!(intersperse_iter.next(), None); | |
| 249 | } | |
| 250 | } | |
| 251 | ||
| 252 | // Extra check to make sure it is `None` after processing 6 items | |
| 253 | assert_eq!(intersperse_iter.next(), None); | |
| 254 | } | |
| 255 | ||
| 256 | // FIXME(iter_intersperse): `intersperse_with` current behavior may change for | |
| 257 | // non-fused iterators, so this test will likely have to | |
| 258 | // be adjusted; see PR #152855 and issue #79524 | |
| 259 | // if `intersperse_with` doesn't change, remove this FIXME. | |
| 260 | #[test] | |
| 261 | fn test_non_fused_iterator_intersperse_with() { | |
| 262 | #[derive(Debug)] | |
| 263 | struct TestCounter { | |
| 264 | counter: usize, | |
| 265 | } | |
| 266 | ||
| 267 | // Given a counter of 0, this produces: | |
| 268 | // `None` -> `Some(2)` -> `None` -> `Some(4)` -> `None` -> `Some(6)` | |
| 269 | // -> and then `None` endlessly | |
| 270 | impl Iterator for TestCounter { | |
| 271 | type Item = usize; | |
| 272 | fn next(&mut self) -> Option<Self::Item> { | |
| 273 | if self.counter > 6 { | |
| 274 | None | |
| 275 | } else if self.counter % 2 == 0 { | |
| 276 | self.counter += 1; | |
| 277 | None | |
| 278 | } else { | |
| 279 | self.counter += 1; | |
| 280 | Some(self.counter) | |
| 281 | } | |
| 282 | } | |
| 283 | } | |
| 284 | ||
| 285 | let counter = 0; | |
| 286 | let non_fused_iter = TestCounter { counter }; | |
| 287 | // places a 2 between `Some(_)` items | |
| 288 | let mut intersperse_iter = non_fused_iter.intersperse_with(|| 2); | |
| 289 | // Since `intersperse` currently transforms the original | |
| 290 | // iterator into a fused iterator, this intersperse_iter | |
| 291 | // should always have `None` | |
| 292 | for _ in 0..counter + 6 { | |
| 293 | assert_eq!(intersperse_iter.next(), None); | |
| 294 | } | |
| 295 | ||
| 296 | // Extra check to make sure it is `None` after processing 6 items | |
| 297 | assert_eq!(intersperse_iter.next(), None); | |
| 298 | } | |
| 299 | ||
| 300 | // FIXME(iter_intersperse): `intersperse_with` current behavior may change for | |
| 301 | // non-fused iterators, so this test will likely have to | |
| 302 | // be adjusted; see PR #152855 and issue #79524 | |
| 303 | // if `intersperse_with` doesn't change, remove this FIXME. | |
| 304 | #[test] | |
| 305 | fn test_non_fused_iterator_intersperse_with_2() { | |
| 306 | #[derive(Debug)] | |
| 307 | struct TestCounter { | |
| 308 | counter: usize, | |
| 309 | } | |
| 310 | ||
| 311 | // Given a counter of 0, this produces: | |
| 312 | // `Some(1)` -> `Some(2)` -> `None` -> `Some(4)` -> `Some(5)` -> | |
| 313 | // and then `None` endlessly | |
| 314 | impl Iterator for TestCounter { | |
| 315 | type Item = usize; | |
| 316 | fn next(&mut self) -> Option<Self::Item> { | |
| 317 | if self.counter < 5 { | |
| 318 | self.counter += 1; | |
| 319 | if self.counter % 3 != 0 { | |
| 320 | return Some(self.counter); | |
| 321 | } else { | |
| 322 | return None; | |
| 323 | } | |
| 324 | } | |
| 325 | self.counter += 1; | |
| 326 | None | |
| 327 | } | |
| 328 | } | |
| 329 | ||
| 330 | let counter = 0; | |
| 331 | // places a 2 between `Some(_)` items | |
| 332 | let non_fused_iter = TestCounter { counter }; | |
| 333 | let mut intersperse_iter = non_fused_iter.intersperse(2); | |
| 334 | // Since `intersperse` currently transforms the original | |
| 335 | // iterator into a fused iterator, this interspersed iter | |
| 336 | // will be `Some(1)` -> `Some(2)` -> `Some(2)` -> and then | |
| 337 | // `None` endlessly | |
| 338 | let mut items_processed = 0; | |
| 339 | for num in 0..counter + 6 { | |
| 340 | if num < 3 { | |
| 341 | if num % 2 != 0 { | |
| 342 | assert_eq!(intersperse_iter.next(), Some(2)); | |
| 343 | } else { | |
| 344 | items_processed += 1; | |
| 345 | assert_eq!(intersperse_iter.next(), Some(items_processed)); | |
| 346 | } | |
| 347 | } else { | |
| 348 | assert_eq!(intersperse_iter.next(), None); | |
| 349 | } | |
| 350 | } | |
| 351 | ||
| 352 | // Extra check to make sure it is `None` after processing 6 items | |
| 353 | assert_eq!(intersperse_iter.next(), None); | |
| 354 | } |
library/std/src/os/hermit/ffi.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | //! HermitCore-specific extension to the primitives in the `std::ffi` module | |
| 1 | //! Hermit-specific extension to the primitives in the `std::ffi` module | |
| 2 | 2 | //! |
| 3 | 3 | //! # Examples |
| 4 | 4 | //! |
library/std/src/sys/pal/hermit/mod.rs+3-3| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | //! System bindings for HermitCore | |
| 1 | //! System bindings for Hermit | |
| 2 | 2 | //! |
| 3 | 3 | //! This module contains the facade (aka platform-specific) implementations of |
| 4 | //! OS level functionality for HermitCore. | |
| 4 | //! OS level functionality for Hermit. | |
| 5 | 5 | //! |
| 6 | 6 | //! This is all super highly experimental and not actually intended for |
| 7 | 7 | //! wide/production use yet, it's still all in the experimental category. This |
| ... | ... | @@ -30,7 +30,7 @@ pub fn unsupported<T>() -> io::Result<T> { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | pub fn unsupported_err() -> io::Error { |
| 33 | io::const_error!(io::ErrorKind::Unsupported, "operation not supported on HermitCore yet") | |
| 33 | io::const_error!(io::ErrorKind::Unsupported, "operation not supported on Hermit yet") | |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | pub fn abort_internal() -> ! { |
src/librustdoc/clean/cfg.rs+1-1| ... | ... | @@ -429,7 +429,7 @@ impl fmt::Display for Display<'_> { |
| 429 | 429 | "freebsd" => "FreeBSD", |
| 430 | 430 | "fuchsia" => "Fuchsia", |
| 431 | 431 | "haiku" => "Haiku", |
| 432 | "hermit" => "HermitCore", | |
| 432 | "hermit" => "Hermit", | |
| 433 | 433 | "illumos" => "illumos", |
| 434 | 434 | "ios" => "iOS", |
| 435 | 435 | "l4re" => "L4Re", |
src/librustdoc/core.rs+5-1| ... | ... | @@ -285,7 +285,11 @@ pub(crate) fn create_config( |
| 285 | 285 | crate_check_cfg: check_cfgs, |
| 286 | 286 | input, |
| 287 | 287 | output_file: None, |
| 288 | output_dir: None, | |
| 288 | output_dir: if render_options.output_to_stdout { | |
| 289 | None | |
| 290 | } else { | |
| 291 | Some(render_options.output.clone()) | |
| 292 | }, | |
| 289 | 293 | file_loader: None, |
| 290 | 294 | lint_caps, |
| 291 | 295 | psess_created: None, |
src/librustdoc/lib.rs+1-18| ... | ... | @@ -74,7 +74,6 @@ use std::process::ExitCode; |
| 74 | 74 | |
| 75 | 75 | use rustc_errors::DiagCtxtHandle; |
| 76 | 76 | use rustc_hir::def_id::LOCAL_CRATE; |
| 77 | use rustc_hir::lints::DelayedLint; | |
| 78 | 77 | use rustc_interface::interface; |
| 79 | 78 | use rustc_middle::ty::TyCtxt; |
| 80 | 79 | use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; |
| ... | ... | @@ -910,23 +909,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { |
| 910 | 909 | for owner_id in tcx.hir_crate_items(()).delayed_lint_items() { |
| 911 | 910 | if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { |
| 912 | 911 | for lint in &delayed_lints.lints { |
| 913 | match lint { | |
| 914 | DelayedLint::AttributeParsing(attribute_lint) => { | |
| 915 | tcx.node_span_lint( | |
| 916 | attribute_lint.lint_id.lint, | |
| 917 | attribute_lint.id, | |
| 918 | attribute_lint.span, | |
| 919 | |diag| { | |
| 920 | rustc_lint::decorate_attribute_lint( | |
| 921 | tcx.sess, | |
| 922 | Some(tcx), | |
| 923 | &attribute_lint.kind, | |
| 924 | diag, | |
| 925 | ); | |
| 926 | }, | |
| 927 | ); | |
| 928 | } | |
| 929 | } | |
| 912 | rustc_hir_analysis::emit_delayed_lint(lint, tcx); | |
| 930 | 913 | } |
| 931 | 914 | } |
| 932 | 915 | } |
src/rustdoc-json-types/lib.rs+33| ... | ... | @@ -682,6 +682,39 @@ pub enum ItemEnum { |
| 682 | 682 | }, |
| 683 | 683 | } |
| 684 | 684 | |
| 685 | impl ItemEnum { | |
| 686 | /// Returns the [`ItemKind`] of this item. | |
| 687 | pub fn item_kind(&self) -> ItemKind { | |
| 688 | match self { | |
| 689 | ItemEnum::Module(_) => ItemKind::Module, | |
| 690 | ItemEnum::ExternCrate { .. } => ItemKind::ExternCrate, | |
| 691 | ItemEnum::Use(_) => ItemKind::Use, | |
| 692 | ItemEnum::Union(_) => ItemKind::Union, | |
| 693 | ItemEnum::Struct(_) => ItemKind::Struct, | |
| 694 | ItemEnum::StructField(_) => ItemKind::StructField, | |
| 695 | ItemEnum::Enum(_) => ItemKind::Enum, | |
| 696 | ItemEnum::Variant(_) => ItemKind::Variant, | |
| 697 | ItemEnum::Function(_) => ItemKind::Function, | |
| 698 | ItemEnum::Trait(_) => ItemKind::Trait, | |
| 699 | ItemEnum::TraitAlias(_) => ItemKind::TraitAlias, | |
| 700 | ItemEnum::Impl(_) => ItemKind::Impl, | |
| 701 | ItemEnum::TypeAlias(_) => ItemKind::TypeAlias, | |
| 702 | ItemEnum::Constant { .. } => ItemKind::Constant, | |
| 703 | ItemEnum::Static(_) => ItemKind::Static, | |
| 704 | ItemEnum::ExternType => ItemKind::ExternType, | |
| 705 | ItemEnum::Macro(_) => ItemKind::Macro, | |
| 706 | ItemEnum::ProcMacro(pm) => match pm.kind { | |
| 707 | MacroKind::Bang => ItemKind::Macro, | |
| 708 | MacroKind::Attr => ItemKind::ProcAttribute, | |
| 709 | MacroKind::Derive => ItemKind::ProcDerive, | |
| 710 | }, | |
| 711 | ItemEnum::Primitive(_) => ItemKind::Primitive, | |
| 712 | ItemEnum::AssocConst { .. } => ItemKind::AssocConst, | |
| 713 | ItemEnum::AssocType { .. } => ItemKind::AssocType, | |
| 714 | } | |
| 715 | } | |
| 716 | } | |
| 717 | ||
| 685 | 718 | /// A module declaration, e.g. `mod foo;` or `mod foo {}`. |
| 686 | 719 | #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] |
| 687 | 720 | pub struct Module { |
src/tools/clippy/clippy_lints/src/no_effect.rs+2-2| ... | ... | @@ -242,7 +242,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { |
| 242 | 242 | !expr_ty_has_significant_drop(cx, expr) |
| 243 | 243 | && fields.iter().all(|field| has_no_effect(cx, field.expr)) |
| 244 | 244 | && match &base { |
| 245 | StructTailExpr::None | StructTailExpr::DefaultFields(_) => true, | |
| 245 | StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => true, | |
| 246 | 246 | StructTailExpr::Base(base) => has_no_effect(cx, base), |
| 247 | 247 | } |
| 248 | 248 | }, |
| ... | ... | @@ -353,7 +353,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec |
| 353 | 353 | } else { |
| 354 | 354 | let base = match base { |
| 355 | 355 | StructTailExpr::Base(base) => Some(base), |
| 356 | StructTailExpr::None | StructTailExpr::DefaultFields(_) => None, | |
| 356 | StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None, | |
| 357 | 357 | }; |
| 358 | 358 | Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect()) |
| 359 | 359 | } |
src/tools/clippy/clippy_lints/src/utils/author.rs+1-1| ... | ... | @@ -673,7 +673,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { |
| 673 | 673 | bind!(self, qpath, fields); |
| 674 | 674 | let base = OptionPat::new(match base { |
| 675 | 675 | StructTailExpr::Base(base) => Some(self.bind("base", base)), |
| 676 | StructTailExpr::None | StructTailExpr::DefaultFields(_) => None, | |
| 676 | StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None, | |
| 677 | 677 | }); |
| 678 | 678 | kind!("Struct({qpath}, {fields}, {base})"); |
| 679 | 679 | self.qpath(qpath, &expr.name, expr.value.hir_id); |
src/tools/rustfmt/src/expr.rs+1-1| ... | ... | @@ -1809,7 +1809,7 @@ fn rewrite_struct_lit<'a>( |
| 1809 | 1809 | match struct_rest { |
| 1810 | 1810 | ast::StructRest::Base(expr) => Some(StructLitField::Base(&**expr)), |
| 1811 | 1811 | ast::StructRest::Rest(span) => Some(StructLitField::Rest(*span)), |
| 1812 | ast::StructRest::None => None, | |
| 1812 | ast::StructRest::None | ast::StructRest::NoneWithError(_) => None, | |
| 1813 | 1813 | } |
| 1814 | 1814 | .into_iter(), |
| 1815 | 1815 | ); |
tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs+13-17| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | #![crate_type = "staticlib"] |
| 2 | 2 | #![feature(c_variadic)] |
| 3 | 3 | |
| 4 | use std::ffi::{CStr, CString, VaList, c_char, c_double, c_int, c_long, c_longlong}; | |
| 4 | use core::ffi::{CStr, VaList, c_char, c_double, c_int, c_long, c_longlong}; | |
| 5 | 5 | |
| 6 | 6 | macro_rules! continue_if { |
| 7 | 7 | ($cond:expr) => { |
| ... | ... | @@ -11,12 +11,8 @@ macro_rules! continue_if { |
| 11 | 11 | }; |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool { | |
| 15 | let cstr0 = CStr::from_ptr(ptr); | |
| 16 | match CString::new(val) { | |
| 17 | Ok(cstr1) => &*cstr1 == cstr0, | |
| 18 | Err(_) => false, | |
| 19 | } | |
| 14 | unsafe fn compare_c_str(ptr: *const c_char, val: &CStr) -> bool { | |
| 15 | val == CStr::from_ptr(ptr) | |
| 20 | 16 | } |
| 21 | 17 | |
| 22 | 18 | #[unsafe(no_mangle)] |
| ... | ... | @@ -35,42 +31,42 @@ pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize { |
| 35 | 31 | continue_if!(ap.arg::<c_int>() == ';' as c_int); |
| 36 | 32 | continue_if!(ap.arg::<c_int>() == 0x32); |
| 37 | 33 | continue_if!(ap.arg::<c_int>() == 0x10000001); |
| 38 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!")); | |
| 34 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Valid!")); | |
| 39 | 35 | 0 |
| 40 | 36 | } |
| 41 | 37 | |
| 42 | 38 | #[unsafe(no_mangle)] |
| 43 | 39 | pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize { |
| 44 | continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); | |
| 40 | continue_if!(ap.arg::<c_double>() == 3.14f64); | |
| 45 | 41 | continue_if!(ap.arg::<c_long>() == 12); |
| 46 | 42 | continue_if!(ap.arg::<c_int>() == 'a' as c_int); |
| 47 | continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor()); | |
| 48 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); | |
| 43 | continue_if!(ap.arg::<c_double>() == 6.28f64); | |
| 44 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Hello")); | |
| 49 | 45 | continue_if!(ap.arg::<c_int>() == 42); |
| 50 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); | |
| 46 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"World")); | |
| 51 | 47 | 0 |
| 52 | 48 | } |
| 53 | 49 | |
| 54 | 50 | #[unsafe(no_mangle)] |
| 55 | 51 | pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { |
| 56 | continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor()); | |
| 52 | continue_if!(ap.arg::<c_double>() == 6.28f64); | |
| 57 | 53 | continue_if!(ap.arg::<c_int>() == 16); |
| 58 | 54 | continue_if!(ap.arg::<c_int>() == 'A' as c_int); |
| 59 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); | |
| 55 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Skip Me!")); | |
| 60 | 56 | let mut ap = ap.clone(); |
| 61 | if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { 0xff } | |
| 57 | if compare_c_str(ap.arg::<*const c_char>(), c"Correct") { 0 } else { 0xff } | |
| 62 | 58 | } |
| 63 | 59 | |
| 64 | 60 | #[unsafe(no_mangle)] |
| 65 | 61 | pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize { |
| 66 | 62 | continue_if!(ap.arg::<c_int>() == 42); |
| 67 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello, World!")); | |
| 63 | continue_if!(compare_c_str(ap.arg::<*const c_char>(), c"Hello, World!")); | |
| 68 | 64 | 0 |
| 69 | 65 | } |
| 70 | 66 | |
| 71 | 67 | #[unsafe(no_mangle)] |
| 72 | 68 | pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { |
| 73 | continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); | |
| 69 | continue_if!(ap.arg::<c_double>() == 3.14f64); | |
| 74 | 70 | continue_if!(ap.arg::<c_long>() == 12); |
| 75 | 71 | continue_if!(ap.arg::<c_int>() == 'A' as c_int); |
| 76 | 72 | continue_if!(ap.arg::<c_longlong>() == 1); |
tests/run-make/c-link-to-rust-va-list-fn/rmake.rs+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name}; |
| 11 | 11 | |
| 12 | 12 | fn main() { |
| 13 | rustc().input("checkrust.rs").run(); | |
| 13 | rustc().edition("2021").input("checkrust.rs").run(); | |
| 14 | 14 | cc().input("test.c") |
| 15 | 15 | .input(static_lib_name("checkrust")) |
| 16 | 16 | .out_exe("test") |
tests/run-make/rustdoc-dep-info/rmake.rs+3-1| ... | ... | @@ -7,6 +7,8 @@ use run_make_support::assertion_helpers::assert_contains; |
| 7 | 7 | use run_make_support::{path, rfs, rustdoc}; |
| 8 | 8 | |
| 9 | 9 | fn main() { |
| 10 | rfs::create_dir("doc"); | |
| 11 | ||
| 10 | 12 | // We're only emitting dep info, so we shouldn't be running static analysis to |
| 11 | 13 | // figure out that this program is erroneous. |
| 12 | 14 | // Ensure that all kinds of input reading flags end up in dep-info. |
| ... | ... | @@ -20,7 +22,7 @@ fn main() { |
| 20 | 22 | .emit("dep-info") |
| 21 | 23 | .run(); |
| 22 | 24 | |
| 23 | let content = rfs::read_to_string("foo.d"); | |
| 25 | let content = rfs::read_to_string("doc/foo.d"); | |
| 24 | 26 | assert_contains(&content, "lib.rs:"); |
| 25 | 27 | assert_contains(&content, "foo.rs:"); |
| 26 | 28 | assert_contains(&content, "bar.rs:"); |
tests/run-make/rustdoc-scrape-examples-dep-info/rmake.rs+4-2| ... | ... | @@ -5,15 +5,17 @@ use run_make_support::{assert_contains, rfs}; |
| 5 | 5 | mod scrape; |
| 6 | 6 | |
| 7 | 7 | fn main() { |
| 8 | rfs::create_dir("rustdoc"); | |
| 9 | ||
| 8 | 10 | scrape::scrape( |
| 9 | 11 | &["--scrape-tests", "--emit=dep-info"], |
| 10 | 12 | &["--emit=dep-info,invocation-specific"], |
| 11 | 13 | ); |
| 12 | 14 | |
| 13 | let content = rfs::read_to_string("foobar.d").replace(r"\", "/"); | |
| 15 | let content = rfs::read_to_string("rustdoc/foobar.d").replace(r"\", "/"); | |
| 14 | 16 | assert_contains(&content, "lib.rs:"); |
| 15 | 17 | assert_contains(&content, "rustdoc/ex.calls:"); |
| 16 | 18 | |
| 17 | let content = rfs::read_to_string("ex.d").replace(r"\", "/"); | |
| 19 | let content = rfs::read_to_string("rustdoc/ex.d").replace(r"\", "/"); | |
| 18 | 20 | assert_contains(&content, "examples/ex.rs:"); |
| 19 | 21 | } |
tests/ui/const-generics/issues/issue-67185-2.stderr-2| ... | ... | @@ -11,7 +11,6 @@ LL | impl Bar for [u16; 4] {} |
| 11 | 11 | | ^^^^^^^^^^^^^^^^^^^^^ `[u16; 4]` |
| 12 | 12 | LL | impl Bar for [[u16; 3]; 3] {} |
| 13 | 13 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `[[u16; 3]; 3]` |
| 14 | = help: see issue #48214 | |
| 15 | 14 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 16 | 15 | | |
| 17 | 16 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -30,7 +29,6 @@ LL | impl Bar for [u16; 4] {} |
| 30 | 29 | | ^^^^^^^^^^^^^^^^^^^^^ `[u16; 4]` |
| 31 | 30 | LL | impl Bar for [[u16; 3]; 3] {} |
| 32 | 31 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `[[u16; 3]; 3]` |
| 33 | = help: see issue #48214 | |
| 34 | 32 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 35 | 33 | | |
| 36 | 34 | LL + #![feature(trivial_bounds)] |
tests/ui/consts/assoc-const-elided-lifetime.stderr+4-4| ... | ... | @@ -4,13 +4,13 @@ error: `'_` cannot be used here |
| 4 | 4 | LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&()> }; |
| 5 | 5 | | ^^ |
| 6 | 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 #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 9 | 7 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 10 | 8 | --> $DIR/assoc-const-elided-lifetime.rs:9:6 |
| 11 | 9 | | |
| 12 | 10 | LL | impl<'a> Foo<'a> { |
| 13 | 11 | | ^^ |
| 12 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 13 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 14 | 14 | note: the lint level is defined here |
| 15 | 15 | --> $DIR/assoc-const-elided-lifetime.rs:1:9 |
| 16 | 16 | | |
| ... | ... | @@ -28,13 +28,13 @@ error: `&` without an explicit lifetime name cannot be used here |
| 28 | 28 | LL | const BAR: &() = &(); |
| 29 | 29 | | ^ |
| 30 | 30 | | |
| 31 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 32 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 33 | 31 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 34 | 32 | --> $DIR/assoc-const-elided-lifetime.rs:9:6 |
| 35 | 33 | | |
| 36 | 34 | LL | impl<'a> Foo<'a> { |
| 37 | 35 | | ^^ |
| 36 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 37 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 38 | 38 | help: use the `'static` lifetime |
| 39 | 39 | | |
| 40 | 40 | LL | const BAR: &'static () = &(); |
tests/ui/consts/const-eval/ptr_fragments_in_final.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | //! Test that we properly error when there is a pointer fragment in the final value. |
| 2 | //@ ignore-s390x different alignment on s390x make the test fail | |
| 2 | 3 | |
| 3 | 4 | use std::{mem::{self, MaybeUninit}, ptr}; |
| 4 | 5 |
tests/ui/consts/const-eval/ptr_fragments_in_final.stderr+3-3| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error: encountered partial pointer in final value of constant |
| 2 | --> $DIR/ptr_fragments_in_final.rs:15:1 | |
| 2 | --> $DIR/ptr_fragments_in_final.rs:16:1 | |
| 3 | 3 | | |
| 4 | 4 | LL | const MEMCPY_RET: MaybeUninit<*const i32> = unsafe { |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -7,7 +7,7 @@ LL | const MEMCPY_RET: MaybeUninit<*const i32> = unsafe { |
| 7 | 7 | = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value |
| 8 | 8 | |
| 9 | 9 | error: encountered partial pointer in final value of constant |
| 10 | --> $DIR/ptr_fragments_in_final.rs:24:1 | |
| 10 | --> $DIR/ptr_fragments_in_final.rs:25:1 | |
| 11 | 11 | | |
| 12 | 12 | LL | const MIXED_PTR: MaybeUninit<*const u8> = { |
| 13 | 13 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -15,7 +15,7 @@ LL | const MIXED_PTR: MaybeUninit<*const u8> = { |
| 15 | 15 | = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value |
| 16 | 16 | |
| 17 | 17 | error: encountered partial pointer in final value of constant |
| 18 | --> $DIR/ptr_fragments_in_final.rs:61:5 | |
| 18 | --> $DIR/ptr_fragments_in_final.rs:62:5 | |
| 19 | 19 | | |
| 20 | 20 | LL | const A: Thing = unsafe { |
| 21 | 21 | | ^^^^^^^^^^^^^^ |
tests/ui/consts/static-default-lifetime/elided-lifetime.stderr+4-4| ... | ... | @@ -4,13 +4,13 @@ error: `&` without an explicit lifetime name cannot be used here |
| 4 | 4 | LL | const STATIC: &str = ""; |
| 5 | 5 | | ^ |
| 6 | 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 #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 9 | 7 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 10 | 8 | --> $DIR/elided-lifetime.rs:5:10 |
| 11 | 9 | | |
| 12 | 10 | LL | impl Foo<'_> { |
| 13 | 11 | | ^^ |
| 12 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 13 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 14 | 14 | note: the lint level is defined here |
| 15 | 15 | --> $DIR/elided-lifetime.rs:1:9 |
| 16 | 16 | | |
| ... | ... | @@ -27,13 +27,13 @@ error: `&` without an explicit lifetime name cannot be used here |
| 27 | 27 | LL | const STATIC: &str = ""; |
| 28 | 28 | | ^ |
| 29 | 29 | | |
| 30 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 31 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 32 | 30 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 33 | 31 | --> $DIR/elided-lifetime.rs:15:18 |
| 34 | 32 | | |
| 35 | 33 | LL | impl Bar for Foo<'_> { |
| 36 | 34 | | ^^ |
| 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 #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 37 | 37 | help: use the `'static` lifetime |
| 38 | 38 | | |
| 39 | 39 | LL | const STATIC: &'static str = ""; |
tests/ui/consts/static-default-lifetime/generic-associated-const.stderr+2-2| ... | ... | @@ -24,13 +24,13 @@ error: `&` without an explicit lifetime name cannot be used here |
| 24 | 24 | LL | const GAC_LIFETIME<'a>: &str = ""; |
| 25 | 25 | | ^ |
| 26 | 26 | | |
| 27 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 28 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 29 | 27 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 30 | 28 | --> $DIR/generic-associated-const.rs:8:24 |
| 31 | 29 | | |
| 32 | 30 | LL | const GAC_LIFETIME<'a>: &str = ""; |
| 33 | 31 | | ^^ |
| 32 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 33 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 34 | 34 | note: the lint level is defined here |
| 35 | 35 | --> $DIR/generic-associated-const.rs:1:9 |
| 36 | 36 | | |
tests/ui/consts/static-default-lifetime/static-trait-impl.stderr+2-2| ... | ... | @@ -4,13 +4,13 @@ error: `&` without an explicit lifetime name cannot be used here |
| 4 | 4 | LL | const STATIC: &str = ""; |
| 5 | 5 | | ^ |
| 6 | 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 #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 9 | 7 | note: cannot automatically infer `'static` because of other lifetimes in scope |
| 10 | 8 | --> $DIR/static-trait-impl.rs:8:10 |
| 11 | 9 | | |
| 12 | 10 | LL | impl Bar<'_> for A { |
| 13 | 11 | | ^^ |
| 12 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
| 13 | = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010> | |
| 14 | 14 | note: the lint level is defined here |
| 15 | 15 | --> $DIR/static-trait-impl.rs:1:9 |
| 16 | 16 | | |
tests/ui/cross/cross-fn-cache-hole.stderr-1| ... | ... | @@ -9,7 +9,6 @@ help: this trait has no implementations, consider adding one |
| 9 | 9 | | |
| 10 | 10 | LL | trait Bar<X> { } |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | = help: see issue #48214 | |
| 13 | 12 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 14 | 13 | | |
| 15 | 14 | LL + #![feature(trivial_bounds)] |
tests/ui/delegation/generics/impl-to-trait-method.stderr-1| ... | ... | @@ -14,7 +14,6 @@ help: this trait has no implementations, consider adding one |
| 14 | 14 | | |
| 15 | 15 | LL | trait Trait0 {} |
| 16 | 16 | | ^^^^^^^^^^^^ |
| 17 | = help: see issue #48214 | |
| 18 | 17 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 19 | 18 | | |
| 20 | 19 | LL + #![feature(trivial_bounds)] |
tests/ui/feature-gates/feature-gate-trivial_bounds.stderr-11| ... | ... | @@ -9,7 +9,6 @@ help: the trait `Foo` is implemented for `()` |
| 9 | 9 | | |
| 10 | 10 | LL | impl Foo for () where i32: Foo { |
| 11 | 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 12 | = help: see issue #48214 | |
| 13 | 12 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 14 | 13 | | |
| 15 | 14 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -26,7 +25,6 @@ help: the trait `Foo` is implemented for `()` |
| 26 | 25 | | |
| 27 | 26 | LL | impl Foo for () where i32: Foo { |
| 28 | 27 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 29 | = help: see issue #48214 | |
| 30 | 28 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 31 | 29 | | |
| 32 | 30 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -43,7 +41,6 @@ help: the trait `Foo` is implemented for `()` |
| 43 | 41 | | |
| 44 | 42 | LL | impl Foo for () where i32: Foo { |
| 45 | 43 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 46 | = help: see issue #48214 | |
| 47 | 44 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 48 | 45 | | |
| 49 | 46 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -60,7 +57,6 @@ help: the trait `Foo` is implemented for `()` |
| 60 | 57 | | |
| 61 | 58 | LL | impl Foo for () where i32: Foo { |
| 62 | 59 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 63 | = help: see issue #48214 | |
| 64 | 60 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 65 | 61 | | |
| 66 | 62 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -77,7 +73,6 @@ help: the trait `Foo` is implemented for `()` |
| 77 | 73 | | |
| 78 | 74 | LL | impl Foo for () where i32: Foo { |
| 79 | 75 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 80 | = help: see issue #48214 | |
| 81 | 76 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 82 | 77 | | |
| 83 | 78 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -94,7 +89,6 @@ help: the trait `Foo` is implemented for `()` |
| 94 | 89 | | |
| 95 | 90 | LL | impl Foo for () where i32: Foo { |
| 96 | 91 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 97 | = help: see issue #48214 | |
| 98 | 92 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 99 | 93 | | |
| 100 | 94 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -106,7 +100,6 @@ error[E0277]: the trait bound `String: Neg` is not satisfied |
| 106 | 100 | LL | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> { |
| 107 | 101 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Neg` is not implemented for `String` |
| 108 | 102 | | |
| 109 | = help: see issue #48214 | |
| 110 | 103 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 111 | 104 | | |
| 112 | 105 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -119,7 +112,6 @@ LL | fn use_for() where i32: Iterator { |
| 119 | 112 | | ^^^^^^^^^^^^^ `i32` is not an iterator |
| 120 | 113 | | |
| 121 | 114 | = help: the trait `Iterator` is not implemented for `i32` |
| 122 | = help: see issue #48214 | |
| 123 | 115 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 124 | 116 | | |
| 125 | 117 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -132,7 +124,6 @@ LL | struct TwoStrs(str, str) where str: Sized; |
| 132 | 124 | | ^^^^^^^^^^ doesn't have a size known at compile-time |
| 133 | 125 | | |
| 134 | 126 | = help: the trait `Sized` is not implemented for `str` |
| 135 | = help: see issue #48214 | |
| 136 | 127 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 137 | 128 | | |
| 138 | 129 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -150,7 +141,6 @@ note: required because it appears within the type `Dst<(dyn A + 'static)>` |
| 150 | 141 | | |
| 151 | 142 | LL | struct Dst<X: ?Sized> { |
| 152 | 143 | | ^^^ |
| 153 | = help: see issue #48214 | |
| 154 | 144 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 155 | 145 | | |
| 156 | 146 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -163,7 +153,6 @@ LL | fn return_str() -> str where str: Sized { |
| 163 | 153 | | ^^^^^^^^^^ doesn't have a size known at compile-time |
| 164 | 154 | | |
| 165 | 155 | = help: the trait `Sized` is not implemented for `str` |
| 166 | = help: see issue #48214 | |
| 167 | 156 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 168 | 157 | | |
| 169 | 158 | LL + #![feature(trivial_bounds)] |
tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.stderr-2| ... | ... | @@ -4,7 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied |
| 4 | 4 | LL | String: Copy; |
| 5 | 5 | | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` |
| 6 | 6 | | |
| 7 | = help: see issue #48214 | |
| 8 | 7 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 9 | 8 | | |
| 10 | 9 | LL + #![feature(trivial_bounds)] |
| ... | ... | @@ -16,7 +15,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied |
| 16 | 15 | LL | fn demo() -> impl Foo |
| 17 | 16 | | ^^^^^^^^ the trait `Copy` is not implemented for `String` |
| 18 | 17 | | |
| 19 | = help: see issue #48214 | |
| 20 | 18 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 21 | 19 | | |
| 22 | 20 | LL + #![feature(trivial_bounds)] |
tests/ui/imports/auxiliary/extern-crate-alias-impl-method-aux.rs created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | #![crate_type="lib"] | |
| 2 | #![deny(warnings)] | |
| 3 | ||
| 4 | pub use src::aliases::B; | |
| 5 | pub use src::hidden_core::make; | |
| 6 | ||
| 7 | mod src { | |
| 8 | pub mod aliases { | |
| 9 | use super::hidden_core::A; | |
| 10 | pub type B = A; | |
| 11 | } | |
| 12 | ||
| 13 | pub mod hidden_core { | |
| 14 | use super::aliases::B; | |
| 15 | ||
| 16 | #[derive(Copy, Clone)] | |
| 17 | pub struct A; | |
| 18 | ||
| 19 | pub fn make() -> B { A } | |
| 20 | ||
| 21 | impl A { | |
| 22 | pub fn foo(&mut self) { println!("called foo"); } | |
| 23 | } | |
| 24 | } | |
| 25 | } |
tests/ui/imports/auxiliary/extern-crate-indirect-fn-ptr-aux-1.rs created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | pub struct Foo { | |
| 2 | pub foo: extern "C" fn() | |
| 3 | } | |
| 4 | ||
| 5 | extern "C" fn the_foo() {} | |
| 6 | ||
| 7 | pub const FOO: Foo = Foo { | |
| 8 | foo: the_foo | |
| 9 | }; |
tests/ui/imports/auxiliary/extern-crate-indirect-fn-ptr-aux-2.rs created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | extern crate extern_crate_indirect_fn_ptr_aux_1 as crate1; | |
| 2 | ||
| 3 | pub static FOO2: crate1::Foo = crate1::FOO; |
tests/ui/imports/auxiliary/extern-crate-no-prefer-dynamic-aux-1.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | //@ no-prefer-dynamic | |
| 2 | ||
| 3 | #![crate_type = "rlib"] | |
| 4 | ||
| 5 | pub fn foo() {} |
tests/ui/imports/auxiliary/extern-crate-no-prefer-dynamic-aux-2.rs created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | extern crate extern_crate_no_prefer_dynamic_aux_1; | |
| 2 | ||
| 3 | pub fn bar() {} |
tests/ui/imports/auxiliary/extern-transmute-aux.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | #![crate_type = "lib"] | |
| 2 | ||
| 3 | extern "C" { | |
| 4 | pub fn transmute(); | |
| 5 | } |
tests/ui/imports/auxiliary/typeid-cross-crate-aux.rs created+87| ... | ... | @@ -0,0 +1,87 @@ |
| 1 | pub mod testtypes { | |
| 2 | use std::any::TypeId; | |
| 3 | ||
| 4 | pub fn type_ids() -> Vec<TypeId> { | |
| 5 | vec![ | |
| 6 | TypeId::of::<FooBool>(), | |
| 7 | TypeId::of::<FooInt>(), | |
| 8 | TypeId::of::<FooUint>(), | |
| 9 | TypeId::of::<FooFloat>(), | |
| 10 | TypeId::of::<FooStr>(), | |
| 11 | TypeId::of::<FooArray>(), | |
| 12 | TypeId::of::<FooSlice>(), | |
| 13 | TypeId::of::<FooBox>(), | |
| 14 | TypeId::of::<FooPtr>(), | |
| 15 | TypeId::of::<FooRef>(), | |
| 16 | TypeId::of::<FooFnPtr>(), | |
| 17 | TypeId::of::<FooNil>(), | |
| 18 | TypeId::of::<FooTuple>(), | |
| 19 | TypeId::of::<dyn FooTrait>(), | |
| 20 | TypeId::of::<FooStruct>(), | |
| 21 | TypeId::of::<FooEnum>() | |
| 22 | ] | |
| 23 | } | |
| 24 | ||
| 25 | // Tests Bool | |
| 26 | pub type FooBool = bool; | |
| 27 | ||
| 28 | // Tests Char | |
| 29 | pub type FooChar = char; | |
| 30 | ||
| 31 | // Tests Int (does not test all variants of IntTy) | |
| 32 | pub type FooInt = isize; | |
| 33 | ||
| 34 | // Tests Uint (does not test all variants of UintTy) | |
| 35 | pub type FooUint = usize; | |
| 36 | ||
| 37 | // Tests Float (does not test all variants of FloatTy) | |
| 38 | pub type FooFloat = f64; | |
| 39 | ||
| 40 | // Tests Str | |
| 41 | pub type FooStr = str; | |
| 42 | ||
| 43 | // Tests Array | |
| 44 | pub type FooArray = [u8; 1]; | |
| 45 | ||
| 46 | // Tests Slice | |
| 47 | pub type FooSlice = [u8]; | |
| 48 | ||
| 49 | // Tests Box (of u8) | |
| 50 | pub type FooBox = Box<u8>; | |
| 51 | ||
| 52 | // Tests RawPtr | |
| 53 | pub type FooPtr = *const u8; | |
| 54 | ||
| 55 | // Tests Ref | |
| 56 | pub type FooRef = &'static u8; | |
| 57 | ||
| 58 | // Tests FnPtr | |
| 59 | pub type FooFnPtr = fn(u8) -> bool; | |
| 60 | ||
| 61 | // Tests Dynamic | |
| 62 | pub trait FooTrait { | |
| 63 | fn foo_method(&self) -> usize; | |
| 64 | } | |
| 65 | ||
| 66 | // Tests struct | |
| 67 | pub struct FooStruct { | |
| 68 | pub pub_foo_field: usize, | |
| 69 | foo_field: usize | |
| 70 | } | |
| 71 | ||
| 72 | // Tests enum | |
| 73 | pub enum FooEnum { | |
| 74 | VarA(usize), | |
| 75 | VarB(usize, usize) | |
| 76 | } | |
| 77 | ||
| 78 | // Tests Tuple | |
| 79 | pub type FooNil = (); | |
| 80 | pub type FooTuple = (u8, i8, bool); | |
| 81 | ||
| 82 | // Skipping Param | |
| 83 | ||
| 84 | // Skipping Infer | |
| 85 | ||
| 86 | // Skipping Error | |
| 87 | } |
tests/ui/imports/auxiliary/unused-cross-crate-import-aux-1.rs created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | pub mod bar { | |
| 2 | pub fn foo() {} | |
| 3 | } |
tests/ui/imports/auxiliary/unused-cross-crate-import-aux-2.rs created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub fn baz() {} |
tests/ui/imports/auxiliary/unused-extern-crate-aux.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | #![deny(dead_code)] | |
| 2 | ||
| 3 | mod inner { | |
| 4 | pub trait Trait { | |
| 5 | fn f(&self) { f(); } | |
| 6 | } | |
| 7 | ||
| 8 | impl Trait for isize {} | |
| 9 | ||
| 10 | fn f() {} | |
| 11 | } | |
| 12 | ||
| 13 | pub fn foo() { | |
| 14 | let a = &1isize as &dyn inner::Trait; | |
| 15 | a.f(); | |
| 16 | } |
tests/ui/imports/extern-crate-alias-impl-method.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/14422> | |
| 2 | // Test that we can call an inherently implemented method via aliasing from an extern crate. | |
| 3 | //@ run-pass | |
| 4 | #![allow(non_snake_case)] | |
| 5 | ||
| 6 | //@ aux-build:extern-crate-alias-impl-method-aux.rs | |
| 7 | ||
| 8 | extern crate extern_crate_alias_impl_method_aux as bug_lib; | |
| 9 | ||
| 10 | use bug_lib::B; | |
| 11 | use bug_lib::make; | |
| 12 | ||
| 13 | pub fn main() { | |
| 14 | let mut an_A: B = make(); | |
| 15 | an_A.foo(); | |
| 16 | } |
tests/ui/imports/extern-crate-indirect-fn-ptr.rs created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/13620> | |
| 2 | // Test cross crate resolution of an indirect function pointer | |
| 3 | //@ run-pass | |
| 4 | //@ aux-build:extern-crate-indirect-fn-ptr-aux-1.rs | |
| 5 | //@ aux-build:extern-crate-indirect-fn-ptr-aux-2.rs | |
| 6 | ||
| 7 | extern crate extern_crate_indirect_fn_ptr_aux_2 as crate2; | |
| 8 | ||
| 9 | fn main() { | |
| 10 | (crate2::FOO2.foo)(); | |
| 11 | } |
tests/ui/imports/extern-crate-no-prefer-dynamic.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/14344> | |
| 2 | // Test that we can depend on an `no-prefer-dynamic` crate. | |
| 3 | //@ run-pass | |
| 4 | //@ aux-build:extern-crate-no-prefer-dynamic-aux-1.rs | |
| 5 | //@ aux-build:extern-crate-no-prefer-dynamic-aux-2.rs | |
| 6 | ||
| 7 | extern crate extern_crate_no_prefer_dynamic_aux_1; | |
| 8 | extern crate extern_crate_no_prefer_dynamic_aux_2; | |
| 9 | ||
| 10 | fn main() { | |
| 11 | extern_crate_no_prefer_dynamic_aux_1::foo(); | |
| 12 | extern_crate_no_prefer_dynamic_aux_2::bar(); | |
| 13 | } |
tests/ui/imports/extern-transmute.rs created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/15562> | |
| 2 | // Test resolution of `transmute` in an extern block to rust intrinsics. | |
| 3 | //@ run-pass | |
| 4 | //@ aux-build:extern-transmute-aux.rs | |
| 5 | ||
| 6 | extern crate extern_transmute_aux as i; | |
| 7 | ||
| 8 | pub fn main() { | |
| 9 | unsafe { | |
| 10 | transmute(); | |
| 11 | i::transmute(); | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | // We declare this so we don't run into unresolved symbol errors | |
| 16 | // The above extern is NOT `extern "rust-intrinsic"` and thus | |
| 17 | // means it'll try to find a corresponding symbol to link to. | |
| 18 | #[no_mangle] | |
| 19 | pub extern "C" fn transmute() {} |
tests/ui/imports/typeid-cross-crate.rs created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/13507> | |
| 2 | // Test cross-crate TypeId stability | |
| 3 | //@ run-pass | |
| 4 | #![allow(unused_imports)] | |
| 5 | //@ aux-build:typeid-cross-crate-aux.rs | |
| 6 | ||
| 7 | extern crate typeid_cross_crate_aux; | |
| 8 | use typeid_cross_crate_aux::testtypes; | |
| 9 | ||
| 10 | use std::any::TypeId; | |
| 11 | ||
| 12 | pub fn type_ids() -> Vec<TypeId> { | |
| 13 | use typeid_cross_crate_aux::testtypes::*; | |
| 14 | vec![ | |
| 15 | TypeId::of::<FooBool>(), | |
| 16 | TypeId::of::<FooInt>(), | |
| 17 | TypeId::of::<FooUint>(), | |
| 18 | TypeId::of::<FooFloat>(), | |
| 19 | TypeId::of::<FooStr>(), | |
| 20 | TypeId::of::<FooArray>(), | |
| 21 | TypeId::of::<FooSlice>(), | |
| 22 | TypeId::of::<FooBox>(), | |
| 23 | TypeId::of::<FooPtr>(), | |
| 24 | TypeId::of::<FooRef>(), | |
| 25 | TypeId::of::<FooFnPtr>(), | |
| 26 | TypeId::of::<FooNil>(), | |
| 27 | TypeId::of::<FooTuple>(), | |
| 28 | TypeId::of::<dyn FooTrait>(), | |
| 29 | TypeId::of::<FooStruct>(), | |
| 30 | TypeId::of::<FooEnum>(), | |
| 31 | ] | |
| 32 | } | |
| 33 | ||
| 34 | pub fn main() { | |
| 35 | let othercrate = typeid_cross_crate_aux::testtypes::type_ids(); | |
| 36 | let thiscrate = type_ids(); | |
| 37 | assert_eq!(thiscrate, othercrate); | |
| 38 | } |
tests/ui/imports/unused-cross-crate-import.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/12612> | |
| 2 | // Test that unused `use` declarations involving multiple external crates are handled properly. | |
| 3 | //@ run-pass | |
| 4 | #![allow(unused_imports)] | |
| 5 | //@ aux-build:unused-cross-crate-import-aux-1.rs | |
| 6 | //@ aux-build:unused-cross-crate-import-aux-2.rs | |
| 7 | ||
| 8 | extern crate unused_cross_crate_import_aux_1 as foo; | |
| 9 | extern crate unused_cross_crate_import_aux_2 as bar; | |
| 10 | ||
| 11 | mod test { | |
| 12 | use bar::baz; | |
| 13 | } | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/imports/unused-extern-crate.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/11224> | |
| 2 | // Test that an unused `extern crate` declaration does not crash the compiler. | |
| 3 | //@ run-pass | |
| 4 | //@ aux-build:unused-extern-crate-aux.rs | |
| 5 | ||
| 6 | extern crate unused_extern_crate_aux as unused; | |
| 7 | ||
| 8 | pub fn main() {} |
tests/ui/issues/auxiliary/issue-11224.rs deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | #![deny(dead_code)] | |
| 2 | ||
| 3 | mod inner { | |
| 4 | pub trait Trait { | |
| 5 | fn f(&self) { f(); } | |
| 6 | } | |
| 7 | ||
| 8 | impl Trait for isize {} | |
| 9 | ||
| 10 | fn f() {} | |
| 11 | } | |
| 12 | ||
| 13 | pub fn foo() { | |
| 14 | let a = &1isize as &dyn inner::Trait; | |
| 15 | a.f(); | |
| 16 | } |
tests/ui/issues/auxiliary/issue-11508.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | pub struct Closed01<F>(pub F); | |
| 2 | ||
| 3 | pub trait Bar { fn new() -> Self; } | |
| 4 | ||
| 5 | impl<T: Bar> Bar for Closed01<T> { | |
| 6 | fn new() -> Closed01<T> { Closed01(Bar::new()) } | |
| 7 | } | |
| 8 | impl Bar for f32 { fn new() -> f32 { 1.0 } } | |
| 9 | ||
| 10 | pub fn random<T: Bar>() -> T { Bar::new() } |
tests/ui/issues/auxiliary/issue-12612-1.rs deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | pub mod bar { | |
| 2 | pub fn foo() {} | |
| 3 | } |
tests/ui/issues/auxiliary/issue-12612-2.rs deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub fn baz() {} |
tests/ui/issues/auxiliary/issue-13507.rs deleted-87| ... | ... | @@ -1,87 +0,0 @@ |
| 1 | pub mod testtypes { | |
| 2 | use std::any::TypeId; | |
| 3 | ||
| 4 | pub fn type_ids() -> Vec<TypeId> { | |
| 5 | vec![ | |
| 6 | TypeId::of::<FooBool>(), | |
| 7 | TypeId::of::<FooInt>(), | |
| 8 | TypeId::of::<FooUint>(), | |
| 9 | TypeId::of::<FooFloat>(), | |
| 10 | TypeId::of::<FooStr>(), | |
| 11 | TypeId::of::<FooArray>(), | |
| 12 | TypeId::of::<FooSlice>(), | |
| 13 | TypeId::of::<FooBox>(), | |
| 14 | TypeId::of::<FooPtr>(), | |
| 15 | TypeId::of::<FooRef>(), | |
| 16 | TypeId::of::<FooFnPtr>(), | |
| 17 | TypeId::of::<FooNil>(), | |
| 18 | TypeId::of::<FooTuple>(), | |
| 19 | TypeId::of::<dyn FooTrait>(), | |
| 20 | TypeId::of::<FooStruct>(), | |
| 21 | TypeId::of::<FooEnum>() | |
| 22 | ] | |
| 23 | } | |
| 24 | ||
| 25 | // Tests Bool | |
| 26 | pub type FooBool = bool; | |
| 27 | ||
| 28 | // Tests Char | |
| 29 | pub type FooChar = char; | |
| 30 | ||
| 31 | // Tests Int (does not test all variants of IntTy) | |
| 32 | pub type FooInt = isize; | |
| 33 | ||
| 34 | // Tests Uint (does not test all variants of UintTy) | |
| 35 | pub type FooUint = usize; | |
| 36 | ||
| 37 | // Tests Float (does not test all variants of FloatTy) | |
| 38 | pub type FooFloat = f64; | |
| 39 | ||
| 40 | // Tests Str | |
| 41 | pub type FooStr = str; | |
| 42 | ||
| 43 | // Tests Array | |
| 44 | pub type FooArray = [u8; 1]; | |
| 45 | ||
| 46 | // Tests Slice | |
| 47 | pub type FooSlice = [u8]; | |
| 48 | ||
| 49 | // Tests Box (of u8) | |
| 50 | pub type FooBox = Box<u8>; | |
| 51 | ||
| 52 | // Tests RawPtr | |
| 53 | pub type FooPtr = *const u8; | |
| 54 | ||
| 55 | // Tests Ref | |
| 56 | pub type FooRef = &'static u8; | |
| 57 | ||
| 58 | // Tests FnPtr | |
| 59 | pub type FooFnPtr = fn(u8) -> bool; | |
| 60 | ||
| 61 | // Tests Dynamic | |
| 62 | pub trait FooTrait { | |
| 63 | fn foo_method(&self) -> usize; | |
| 64 | } | |
| 65 | ||
| 66 | // Tests struct | |
| 67 | pub struct FooStruct { | |
| 68 | pub pub_foo_field: usize, | |
| 69 | foo_field: usize | |
| 70 | } | |
| 71 | ||
| 72 | // Tests enum | |
| 73 | pub enum FooEnum { | |
| 74 | VarA(usize), | |
| 75 | VarB(usize, usize) | |
| 76 | } | |
| 77 | ||
| 78 | // Tests Tuple | |
| 79 | pub type FooNil = (); | |
| 80 | pub type FooTuple = (u8, i8, bool); | |
| 81 | ||
| 82 | // Skipping Param | |
| 83 | ||
| 84 | // Skipping Infer | |
| 85 | ||
| 86 | // Skipping Error | |
| 87 | } |
tests/ui/issues/auxiliary/issue-13620-1.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | pub struct Foo { | |
| 2 | pub foo: extern "C" fn() | |
| 3 | } | |
| 4 | ||
| 5 | extern "C" fn the_foo() {} | |
| 6 | ||
| 7 | pub const FOO: Foo = Foo { | |
| 8 | foo: the_foo | |
| 9 | }; |
tests/ui/issues/auxiliary/issue-13620-2.rs deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | extern crate issue_13620_1 as crate1; | |
| 2 | ||
| 3 | pub static FOO2: crate1::Foo = crate1::FOO; |
tests/ui/issues/auxiliary/issue-14344-1.rs deleted-5| ... | ... | @@ -1,5 +0,0 @@ |
| 1 | //@ no-prefer-dynamic | |
| 2 | ||
| 3 | #![crate_type = "rlib"] | |
| 4 | ||
| 5 | pub fn foo() {} |
tests/ui/issues/auxiliary/issue-14344-2.rs deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | extern crate issue_14344_1; | |
| 2 | ||
| 3 | pub fn bar() {} |
tests/ui/issues/auxiliary/issue-14422.rs deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | #![crate_type="lib"] | |
| 2 | #![deny(warnings)] | |
| 3 | ||
| 4 | pub use src::aliases::B; | |
| 5 | pub use src::hidden_core::make; | |
| 6 | ||
| 7 | mod src { | |
| 8 | pub mod aliases { | |
| 9 | use super::hidden_core::A; | |
| 10 | pub type B = A; | |
| 11 | } | |
| 12 | ||
| 13 | pub mod hidden_core { | |
| 14 | use super::aliases::B; | |
| 15 | ||
| 16 | #[derive(Copy, Clone)] | |
| 17 | pub struct A; | |
| 18 | ||
| 19 | pub fn make() -> B { A } | |
| 20 | ||
| 21 | impl A { | |
| 22 | pub fn foo(&mut self) { println!("called foo"); } | |
| 23 | } | |
| 24 | } | |
| 25 | } |
tests/ui/issues/auxiliary/issue-15562.rs deleted-5| ... | ... | @@ -1,5 +0,0 @@ |
| 1 | #![crate_type = "lib"] | |
| 2 | ||
| 3 | extern "C" { | |
| 4 | pub fn transmute(); | |
| 5 | } |
tests/ui/issues/issue-11224.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | //@ aux-build:issue-11224.rs | |
| 3 | ||
| 4 | ||
| 5 | extern crate issue_11224 as unused; | |
| 6 | ||
| 7 | pub fn main() {} |
tests/ui/issues/issue-11508.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | //@ aux-build:issue-11508.rs | |
| 3 | ||
| 4 | extern crate issue_11508 as rand; | |
| 5 | ||
| 6 | use rand::{Closed01, random}; | |
| 7 | ||
| 8 | fn main() { | |
| 9 | let Closed01(val) = random::<Closed01<f32>>(); | |
| 10 | println!("{}", val); | |
| 11 | } |
tests/ui/issues/issue-11552.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![feature(box_patterns)] | |
| 3 | ||
| 4 | #[derive(Clone)] | |
| 5 | enum Noun | |
| 6 | { | |
| 7 | Atom(isize), | |
| 8 | Cell(Box<Noun>, Box<Noun>) | |
| 9 | } | |
| 10 | ||
| 11 | fn fas(n: &Noun) -> Noun | |
| 12 | { | |
| 13 | match n { | |
| 14 | &Noun::Cell(box Noun::Atom(2), box Noun::Cell(ref a, _)) => (**a).clone(), | |
| 15 | _ => panic!("Invalid fas pattern") | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | pub fn main() { | |
| 20 | fas( | |
| 21 | &Noun::Cell(Box::new(Noun::Atom(2)), | |
| 22 | Box::new(Noun::Cell(Box::new(Noun::Atom(2)), Box::new(Noun::Atom(3))))) | |
| 23 | ); | |
| 24 | } |
tests/ui/issues/issue-11592.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | //! Ensure the private trait Bar isn't complained about. | |
| 3 | ||
| 4 | #![deny(missing_docs)] | |
| 5 | ||
| 6 | mod foo { | |
| 7 | trait Bar { fn bar(&self) { } } | |
| 8 | impl Bar for i8 { fn bar(&self) { } } | |
| 9 | } | |
| 10 | ||
| 11 | fn main() { } |
tests/ui/issues/issue-11677.rs deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unused_imports)] | |
| 3 | ||
| 4 | #![allow(dead_code)] | |
| 5 | ||
| 6 | // this code used to cause an ICE | |
| 7 | ||
| 8 | use std::marker; | |
| 9 | ||
| 10 | trait X<T> { | |
| 11 | fn dummy(&self) -> T { panic!() } | |
| 12 | } | |
| 13 | ||
| 14 | struct S<T> {f: Box<dyn X<T>+'static>, | |
| 15 | g: Box<dyn X<T>+'static>} | |
| 16 | ||
| 17 | struct F; | |
| 18 | impl X<isize> for F { | |
| 19 | } | |
| 20 | ||
| 21 | fn main() { | |
| 22 | S {f: Box::new(F), g: Box::new(F) }; | |
| 23 | } |
tests/ui/issues/issue-12612.rs deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unused_imports)] | |
| 3 | //@ aux-build:issue-12612-1.rs | |
| 4 | //@ aux-build:issue-12612-2.rs | |
| 5 | ||
| 6 | ||
| 7 | extern crate issue_12612_1 as foo; | |
| 8 | extern crate issue_12612_2 as bar; | |
| 9 | ||
| 10 | mod test { | |
| 11 | use bar::baz; | |
| 12 | } | |
| 13 | ||
| 14 | fn main() {} |
tests/ui/issues/issue-13507-2.rs deleted-36| ... | ... | @@ -1,36 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unused_imports)] | |
| 3 | //@ aux-build:issue-13507.rs | |
| 4 | ||
| 5 | extern crate issue_13507; | |
| 6 | use issue_13507::testtypes; | |
| 7 | ||
| 8 | use std::any::TypeId; | |
| 9 | ||
| 10 | pub fn type_ids() -> Vec<TypeId> { | |
| 11 | use issue_13507::testtypes::*; | |
| 12 | vec![ | |
| 13 | TypeId::of::<FooBool>(), | |
| 14 | TypeId::of::<FooInt>(), | |
| 15 | TypeId::of::<FooUint>(), | |
| 16 | TypeId::of::<FooFloat>(), | |
| 17 | TypeId::of::<FooStr>(), | |
| 18 | TypeId::of::<FooArray>(), | |
| 19 | TypeId::of::<FooSlice>(), | |
| 20 | TypeId::of::<FooBox>(), | |
| 21 | TypeId::of::<FooPtr>(), | |
| 22 | TypeId::of::<FooRef>(), | |
| 23 | TypeId::of::<FooFnPtr>(), | |
| 24 | TypeId::of::<FooNil>(), | |
| 25 | TypeId::of::<FooTuple>(), | |
| 26 | TypeId::of::<dyn FooTrait>(), | |
| 27 | TypeId::of::<FooStruct>(), | |
| 28 | TypeId::of::<FooEnum>() | |
| 29 | ] | |
| 30 | } | |
| 31 | ||
| 32 | pub fn main() { | |
| 33 | let othercrate = issue_13507::testtypes::type_ids(); | |
| 34 | let thiscrate = type_ids(); | |
| 35 | assert_eq!(thiscrate, othercrate); | |
| 36 | } |
tests/ui/issues/issue-13620.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | //@ aux-build:issue-13620-1.rs | |
| 3 | //@ aux-build:issue-13620-2.rs | |
| 4 | ||
| 5 | ||
| 6 | extern crate issue_13620_2 as crate2; | |
| 7 | ||
| 8 | fn main() { | |
| 9 | (crate2::FOO2.foo)(); | |
| 10 | } |
tests/ui/issues/issue-14344.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | //@ aux-build:issue-14344-1.rs | |
| 3 | //@ aux-build:issue-14344-2.rs | |
| 4 | ||
| 5 | extern crate issue_14344_1; | |
| 6 | extern crate issue_14344_2; | |
| 7 | ||
| 8 | fn main() { | |
| 9 | issue_14344_1::foo(); | |
| 10 | issue_14344_2::bar(); | |
| 11 | } |
tests/ui/issues/issue-14422.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(non_snake_case)] | |
| 3 | ||
| 4 | //@ aux-build:issue-14422.rs | |
| 5 | ||
| 6 | ||
| 7 | extern crate issue_14422 as bug_lib; | |
| 8 | ||
| 9 | use bug_lib::B; | |
| 10 | use bug_lib::make; | |
| 11 | ||
| 12 | pub fn main() { | |
| 13 | let mut an_A: B = make(); | |
| 14 | an_A.foo(); | |
| 15 | } |
tests/ui/issues/issue-15562.rs deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | //@ aux-build:issue-15562.rs | |
| 3 | ||
| 4 | ||
| 5 | extern crate issue_15562 as i; | |
| 6 | ||
| 7 | pub fn main() { | |
| 8 | unsafe { | |
| 9 | transmute(); | |
| 10 | i::transmute(); | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | // We declare this so we don't run into unresolved symbol errors | |
| 15 | // The above extern is NOT `extern "rust-intrinsic"` and thus | |
| 16 | // means it'll try to find a corresponding symbol to link to. | |
| 17 | #[no_mangle] | |
| 18 | pub extern "C" fn transmute() {} |
tests/ui/lint/missing-docs-private-trait.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/11592> | |
| 2 | // Test that the `missing_docs` lint does not trigger for a private trait. | |
| 3 | //@ check-pass | |
| 4 | //! Ensure the private trait Bar isn't complained about. | |
| 5 | ||
| 6 | #![deny(missing_docs)] | |
| 7 | ||
| 8 | mod foo { | |
| 9 | trait Bar { | |
| 10 | fn bar(&self) {} | |
| 11 | } | |
| 12 | impl Bar for i8 { | |
| 13 | fn bar(&self) {} | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn main() {} |
tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr-2| ... | ... | @@ -88,7 +88,6 @@ error[E0277]: the trait bound `X: Eq` is not satisfied |
| 88 | 88 | LL | type W: Ord where Self: Eq; |
| 89 | 89 | | ^^^^^^^^ the trait `Eq` is not implemented for `X` |
| 90 | 90 | | |
| 91 | = help: see issue #48214 | |
| 92 | 91 | help: consider annotating `X` with `#[derive(Eq)]` |
| 93 | 92 | | |
| 94 | 93 | LL + #[derive(Eq)] |
| ... | ... | @@ -105,7 +104,6 @@ error[E0277]: the trait bound `X: Eq` is not satisfied |
| 105 | 104 | LL | type W where Self: Eq; |
| 106 | 105 | | ^^^^^^^^ the trait `Eq` is not implemented for `X` |
| 107 | 106 | | |
| 108 | = help: see issue #48214 | |
| 109 | 107 | help: consider annotating `X` with `#[derive(Eq)]` |
| 110 | 108 | | |
| 111 | 109 | LL + #[derive(Eq)] |
tests/ui/parser/issues/issue-102806.rs-1| ... | ... | @@ -16,7 +16,6 @@ fn pz(v: V3) { |
| 16 | 16 | |
| 17 | 17 | let _ = V3 { z: 0.0, ... }; |
| 18 | 18 | //~^ ERROR expected identifier |
| 19 | //~| ERROR missing fields `x` and `y` in initializer of `V3` | |
| 20 | 19 | |
| 21 | 20 | let V3 { z: val, ... } = v; |
| 22 | 21 | //~^ ERROR expected field pattern |
tests/ui/parser/issues/issue-102806.stderr+2-9| ... | ... | @@ -31,7 +31,7 @@ LL | let _ = V3 { z: 0.0, ... }; |
| 31 | 31 | | while parsing this struct |
| 32 | 32 | |
| 33 | 33 | error: expected field pattern, found `...` |
| 34 | --> $DIR/issue-102806.rs:21:22 | |
| 34 | --> $DIR/issue-102806.rs:20:22 | |
| 35 | 35 | | |
| 36 | 36 | LL | let V3 { z: val, ... } = v; |
| 37 | 37 | | ^^^ |
| ... | ... | @@ -42,12 +42,5 @@ LL - let V3 { z: val, ... } = v; |
| 42 | 42 | LL + let V3 { z: val, .. } = v; |
| 43 | 43 | | |
| 44 | 44 | |
| 45 | error[E0063]: missing fields `x` and `y` in initializer of `V3` | |
| 46 | --> $DIR/issue-102806.rs:17:13 | |
| 47 | | | |
| 48 | LL | let _ = V3 { z: 0.0, ... }; | |
| 49 | | ^^ missing `x` and `y` | |
| 50 | ||
| 51 | error: aborting due to 5 previous errors | |
| 45 | error: aborting due to 4 previous errors | |
| 52 | 46 | |
| 53 | For more information about this error, try `rustc --explain E0063`. |
tests/ui/parser/issues/issue-52496.rs-1| ... | ... | @@ -7,6 +7,5 @@ fn main() { |
| 7 | 7 | let bar = 1.5f32; |
| 8 | 8 | let _ = Foo { bar.into(), bat: -1, . }; |
| 9 | 9 | //~^ ERROR expected one of |
| 10 | //~| ERROR missing fields `bar` and `baz` in initializer of `Foo` | |
| 11 | 10 | //~| ERROR expected identifier, found `.` |
| 12 | 11 | } |
tests/ui/parser/issues/issue-52496.stderr+1-7| ... | ... | @@ -37,12 +37,6 @@ error[E0063]: missing field `bat` in initializer of `Foo` |
| 37 | 37 | LL | let _ = Foo { bar: .5, baz: 42 }; |
| 38 | 38 | | ^^^ missing `bat` |
| 39 | 39 | |
| 40 | error[E0063]: missing fields `bar` and `baz` in initializer of `Foo` | |
| 41 | --> $DIR/issue-52496.rs:8:13 | |
| 42 | | | |
| 43 | LL | let _ = Foo { bar.into(), bat: -1, . }; | |
| 44 | | ^^^ missing `bar` and `baz` | |
| 45 | ||
| 46 | error: aborting due to 5 previous errors | |
| 40 | error: aborting due to 4 previous errors | |
| 47 | 41 | |
| 48 | 42 | For more information about this error, try `rustc --explain E0063`. |
tests/ui/parser/removed-syntax/removed-syntax-with-2.rs-1| ... | ... | @@ -7,5 +7,4 @@ fn main() { |
| 7 | 7 | let a = S { foo: (), bar: () }; |
| 8 | 8 | let b = S { foo: (), with a }; |
| 9 | 9 | //~^ ERROR expected one of `,`, `:`, or `}`, found `a` |
| 10 | //~| ERROR missing field `bar` in initializer of `S` | |
| 11 | 10 | } |
tests/ui/parser/removed-syntax/removed-syntax-with-2.stderr+1-8| ... | ... | @@ -7,12 +7,5 @@ LL | let b = S { foo: (), with a }; |
| 7 | 7 | | | while parsing this struct field |
| 8 | 8 | | while parsing this struct |
| 9 | 9 | |
| 10 | error[E0063]: missing field `bar` in initializer of `S` | |
| 11 | --> $DIR/removed-syntax-with-2.rs:8:13 | |
| 12 | | | |
| 13 | LL | let b = S { foo: (), with a }; | |
| 14 | | ^ missing `bar` | |
| 15 | ||
| 16 | error: aborting due to 2 previous errors | |
| 10 | error: aborting due to 1 previous error | |
| 17 | 11 | |
| 18 | For more information about this error, try `rustc --explain E0063`. |
tests/ui/parser/struct-field-numeric-shorthand.rs-1| ... | ... | @@ -5,5 +5,4 @@ fn main() { |
| 5 | 5 | //~^ ERROR expected identifier, found `0` |
| 6 | 6 | //~| ERROR expected identifier, found `1` |
| 7 | 7 | //~| ERROR expected identifier, found `2` |
| 8 | //~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb` | |
| 9 | 8 | } |
tests/ui/parser/struct-field-numeric-shorthand.stderr+1-8| ... | ... | @@ -22,12 +22,5 @@ LL | let _ = Rgb { 0, 1, 2 }; |
| 22 | 22 | | | |
| 23 | 23 | | while parsing this struct |
| 24 | 24 | |
| 25 | error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb` | |
| 26 | --> $DIR/struct-field-numeric-shorthand.rs:4:13 | |
| 27 | | | |
| 28 | LL | let _ = Rgb { 0, 1, 2 }; | |
| 29 | | ^^^ missing `0`, `1` and `2` | |
| 30 | ||
| 31 | error: aborting due to 4 previous errors | |
| 25 | error: aborting due to 3 previous errors | |
| 32 | 26 | |
| 33 | For more information about this error, try `rustc --explain E0063`. |
tests/ui/pattern/auxiliary/tuple-struct-cross-crate-aux.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | pub struct Closed01<F>(pub F); | |
| 2 | ||
| 3 | pub trait Bar { fn new() -> Self; } | |
| 4 | ||
| 5 | impl<T: Bar> Bar for Closed01<T> { | |
| 6 | fn new() -> Closed01<T> { Closed01(Bar::new()) } | |
| 7 | } | |
| 8 | impl Bar for f32 { fn new() -> f32 { 1.0 } } | |
| 9 | ||
| 10 | pub fn random<T: Bar>() -> T { Bar::new() } |
tests/ui/pattern/box-pattern-nested.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/11552> | |
| 2 | // Test nested box pattern matching inside a larger `match` statement. | |
| 3 | //@ run-pass | |
| 4 | #![feature(box_patterns)] | |
| 5 | ||
| 6 | #[derive(Clone)] | |
| 7 | enum Noun { | |
| 8 | Atom(isize), | |
| 9 | Cell(Box<Noun>, Box<Noun>), | |
| 10 | } | |
| 11 | ||
| 12 | fn fas(n: &Noun) -> Noun { | |
| 13 | match n { | |
| 14 | &Noun::Cell(box Noun::Atom(2), box Noun::Cell(ref a, _)) => (**a).clone(), | |
| 15 | _ => panic!("Invalid fas pattern"), | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | pub fn main() { | |
| 20 | fas(&Noun::Cell( | |
| 21 | Box::new(Noun::Atom(2)), | |
| 22 | Box::new(Noun::Cell(Box::new(Noun::Atom(2)), Box::new(Noun::Atom(3)))), | |
| 23 | )); | |
| 24 | } |
tests/ui/pattern/tuple-struct-cross-crate.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/11508> | |
| 2 | // Test pattern matching on a tuple struct defined in an external crate. | |
| 3 | //@ run-pass | |
| 4 | //@ aux-build:tuple-struct-cross-crate-aux.rs | |
| 5 | ||
| 6 | extern crate tuple_struct_cross_crate_aux as rand; | |
| 7 | ||
| 8 | use rand::{Closed01, random}; | |
| 9 | ||
| 10 | fn main() { | |
| 11 | let Closed01(val) = random::<Closed01<f32>>(); | |
| 12 | println!("{}", val); | |
| 13 | } |
tests/ui/structs/syntax-error-not-missing-field.rs created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | // Check that a syntax error inside a struct literal does not also report missing fields, | |
| 2 | // because the field might be present but hidden by the syntax error. | |
| 3 | // | |
| 4 | // The stderr for this test should contain ONLY one syntax error per struct literal, | |
| 5 | // and not any errors about missing fields. | |
| 6 | ||
| 7 | struct Foo { a: isize, b: isize } | |
| 8 | ||
| 9 | fn make_a() -> isize { 1234 } | |
| 10 | ||
| 11 | fn expr_wrong_separator() { | |
| 12 | let f = Foo { a: make_a(); b: 2 }; //~ ERROR found `;` | |
| 13 | } | |
| 14 | ||
| 15 | fn expr_missing_separator() { | |
| 16 | let f = Foo { a: make_a() b: 2 }; //~ ERROR found `b` | |
| 17 | } | |
| 18 | ||
| 19 | fn expr_rest_trailing_comma() { | |
| 20 | let f = Foo { a: make_a(), ..todo!(), }; //~ ERROR cannot use a comma | |
| 21 | } | |
| 22 | ||
| 23 | fn expr_missing_field_name() { | |
| 24 | let f = Foo { make_a(), b: 2, }; //~ ERROR found `(` | |
| 25 | } | |
| 26 | ||
| 27 | fn pat_wrong_separator(Foo { a; b }: Foo) { //~ ERROR expected `,` | |
| 28 | let _ = (a, b); | |
| 29 | } | |
| 30 | ||
| 31 | fn pat_missing_separator(Foo { a b }: Foo) { //~ ERROR expected `,` | |
| 32 | let _ = (a, b); | |
| 33 | } | |
| 34 | ||
| 35 | fn pat_rest_trailing_comma(Foo { a, .., }: Foo) { //~ ERROR expected `}`, found `,` | |
| 36 | } | |
| 37 | ||
| 38 | fn main() {} |
tests/ui/structs/syntax-error-not-missing-field.stderr created+74| ... | ... | @@ -0,0 +1,74 @@ |
| 1 | error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;` | |
| 2 | --> $DIR/syntax-error-not-missing-field.rs:12:30 | |
| 3 | | | |
| 4 | LL | let f = Foo { a: make_a(); b: 2 }; | |
| 5 | | --- ^ | |
| 6 | | | | | |
| 7 | | | expected one of `,`, `.`, `?`, `}`, or an operator | |
| 8 | | | help: try adding a comma: `,` | |
| 9 | | while parsing this struct | |
| 10 | ||
| 11 | error: expected one of `,`, `.`, `?`, `}`, or an operator, found `b` | |
| 12 | --> $DIR/syntax-error-not-missing-field.rs:16:31 | |
| 13 | | | |
| 14 | LL | let f = Foo { a: make_a() b: 2 }; | |
| 15 | | --- -^ expected one of `,`, `.`, `?`, `}`, or an operator | |
| 16 | | | | | |
| 17 | | | help: try adding a comma: `,` | |
| 18 | | while parsing this struct | |
| 19 | ||
| 20 | error: cannot use a comma after the base struct | |
| 21 | --> $DIR/syntax-error-not-missing-field.rs:20:32 | |
| 22 | | | |
| 23 | LL | let f = Foo { a: make_a(), ..todo!(), }; | |
| 24 | | ^^^^^^^^^ | |
| 25 | | | |
| 26 | = note: the base struct must always be the last field | |
| 27 | help: remove this comma | |
| 28 | | | |
| 29 | LL - let f = Foo { a: make_a(), ..todo!(), }; | |
| 30 | LL + let f = Foo { a: make_a(), ..todo!() }; | |
| 31 | | | |
| 32 | ||
| 33 | error: expected one of `,`, `:`, or `}`, found `(` | |
| 34 | --> $DIR/syntax-error-not-missing-field.rs:24:25 | |
| 35 | | | |
| 36 | LL | let f = Foo { make_a(), b: 2, }; | |
| 37 | | --- ------^ expected one of `,`, `:`, or `}` | |
| 38 | | | | | |
| 39 | | | while parsing this struct field | |
| 40 | | while parsing this struct | |
| 41 | | | |
| 42 | help: try naming a field | |
| 43 | | | |
| 44 | LL | let f = Foo { make_a: make_a(), b: 2, }; | |
| 45 | | +++++++ | |
| 46 | ||
| 47 | error: expected `,` | |
| 48 | --> $DIR/syntax-error-not-missing-field.rs:27:31 | |
| 49 | | | |
| 50 | LL | fn pat_wrong_separator(Foo { a; b }: Foo) { | |
| 51 | | --- ^ | |
| 52 | | | | |
| 53 | | while parsing the fields for this pattern | |
| 54 | ||
| 55 | error: expected `,` | |
| 56 | --> $DIR/syntax-error-not-missing-field.rs:31:34 | |
| 57 | | | |
| 58 | LL | fn pat_missing_separator(Foo { a b }: Foo) { | |
| 59 | | --- ^ | |
| 60 | | | | |
| 61 | | while parsing the fields for this pattern | |
| 62 | ||
| 63 | error: expected `}`, found `,` | |
| 64 | --> $DIR/syntax-error-not-missing-field.rs:35:39 | |
| 65 | | | |
| 66 | LL | fn pat_rest_trailing_comma(Foo { a, .., }: Foo) { | |
| 67 | | --^ | |
| 68 | | | | | |
| 69 | | | expected `}` | |
| 70 | | | help: remove this comma | |
| 71 | | `..` must be at the end and cannot have a trailing comma | |
| 72 | ||
| 73 | error: aborting due to 7 previous errors | |
| 74 |
tests/ui/suggestions/struct-initializer-comma.fixed-1| ... | ... | @@ -7,7 +7,6 @@ pub struct Foo { |
| 7 | 7 | |
| 8 | 8 | fn main() { |
| 9 | 9 | let _ = Foo { |
| 10 | //~^ ERROR missing field | |
| 11 | 10 | first: true, |
| 12 | 11 | second: 25 |
| 13 | 12 | //~^ ERROR expected one of |
tests/ui/suggestions/struct-initializer-comma.rs-1| ... | ... | @@ -7,7 +7,6 @@ pub struct Foo { |
| 7 | 7 | |
| 8 | 8 | fn main() { |
| 9 | 9 | let _ = Foo { |
| 10 | //~^ ERROR missing field | |
| 11 | 10 | first: true |
| 12 | 11 | second: 25 |
| 13 | 12 | //~^ ERROR expected one of |
tests/ui/suggestions/struct-initializer-comma.stderr+2-10| ... | ... | @@ -1,9 +1,8 @@ |
| 1 | 1 | error: expected one of `,`, `.`, `?`, `}`, or an operator, found `second` |
| 2 | --> $DIR/struct-initializer-comma.rs:12:9 | |
| 2 | --> $DIR/struct-initializer-comma.rs:11:9 | |
| 3 | 3 | | |
| 4 | 4 | LL | let _ = Foo { |
| 5 | 5 | | --- while parsing this struct |
| 6 | LL | | |
| 7 | 6 | LL | first: true |
| 8 | 7 | | - |
| 9 | 8 | | | |
| ... | ... | @@ -12,12 +11,5 @@ LL | first: true |
| 12 | 11 | LL | second: 25 |
| 13 | 12 | | ^^^^^^ unexpected token |
| 14 | 13 | |
| 15 | error[E0063]: missing field `second` in initializer of `Foo` | |
| 16 | --> $DIR/struct-initializer-comma.rs:9:13 | |
| 17 | | | |
| 18 | LL | let _ = Foo { | |
| 19 | | ^^^ missing `second` | |
| 20 | ||
| 21 | error: aborting due to 2 previous errors | |
| 14 | error: aborting due to 1 previous error | |
| 22 | 15 | |
| 23 | For more information about this error, try `rustc --explain E0063`. |
tests/ui/trait-bounds/super-assoc-mismatch.stderr-1| ... | ... | @@ -77,7 +77,6 @@ help: this trait has no implementations, consider adding one |
| 77 | 77 | | |
| 78 | 78 | LL | trait Sub: Super<Assoc = u16> {} |
| 79 | 79 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 80 | = help: see issue #48214 | |
| 81 | 80 | help: add `#![feature(trivial_bounds)]` to the crate attributes to enable |
| 82 | 81 | | |
| 83 | 82 | LL + #![feature(trivial_bounds)] |
tests/ui/typeck/infer-struct-with-trait-object.rs created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | // issue: <https://github.com/rust-lang/rust/issues/11677> | |
| 2 | // Test that type inference works correctly for struct fields containing trait objects. | |
| 3 | //@ run-pass | |
| 4 | #![allow(unused_imports)] | |
| 5 | #![allow(dead_code)] | |
| 6 | ||
| 7 | // this code used to cause an ICE | |
| 8 | ||
| 9 | use std::marker; | |
| 10 | ||
| 11 | trait X<T> { | |
| 12 | fn dummy(&self) -> T { | |
| 13 | panic!() | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | struct S<T> { | |
| 18 | f: Box<dyn X<T> + 'static>, | |
| 19 | g: Box<dyn X<T> + 'static>, | |
| 20 | } | |
| 21 | ||
| 22 | struct F; | |
| 23 | impl X<isize> for F {} | |
| 24 | ||
| 25 | fn main() { | |
| 26 | S { f: Box::new(F), g: Box::new(F) }; | |
| 27 | } |