authorbors <bors@rust-lang.org> 2026-03-03 07:00:49 UTC
committerbors <bors@rust-lang.org> 2026-03-03 07:00:49 UTC
log1b7d722f429f09c87b08b757d89c689c6cf7f6e7
tree704d494d3e970dcbc3fbd86ea2970a88b25b4e2b
parentd3877ec33269edb7355ef8538d1cc5d157aa1ace
parentcec85ce7321988ca80079947df225f8999de62a6

Auto merge of #153331 - JonathanBrouwer:rollup-hr9XbEa, r=JonathanBrouwer

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 @@
1Version 1.94.0 (2026-03-05)
2==========================
3
4<a id="1.94.0-Language"></a>
5
6Language
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
16Platform Support
17----------------
18
19- [Add `riscv64im-unknown-none-elf` as a tier 3 target](https://github.com/rust-lang/rust/pull/148790)
20
21Refer to Rust's [platform support page][platform-support-doc]
22for 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
28Libraries
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
35Stabilized 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
59These 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
67Cargo
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
77Compatibility 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
106Internal Changes
107----------------
108
109These changes do not affect any public interfaces of Rust, but they represent
110significant improvements to the performance or internals of rustc and related
111tools.
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
1116Version 1.93.1 (2026-02-12)
2117===========================
3118
compiler/rustc_ast/src/ast.rs+6
......@@ -1724,6 +1724,12 @@ pub enum StructRest {
17241724 Rest(Span),
17251725 /// No trailing `..` or expression.
17261726 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),
17271733}
17281734
17291735#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
compiler/rustc_ast_lowering/src/expr.rs+5-4
......@@ -340,12 +340,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
340340 self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
341341 ),
342342 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)),
345345 StructRest::Rest(sp) => {
346 hir::StructTailExpr::DefaultFields(self.lower_span(*sp))
346 hir::StructTailExpr::DefaultFields(self.lower_span(sp))
347347 }
348348 StructRest::None => hir::StructTailExpr::None,
349 StructRest::NoneWithError(guar) => hir::StructTailExpr::NoneWithError(guar),
349350 };
350351 hir::ExprKind::Struct(
351352 self.arena.alloc(self.lower_qpath(
......@@ -1435,7 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14351436 Some(self.lower_span(e.span))
14361437 }
14371438 StructRest::Rest(span) => Some(self.lower_span(*span)),
1438 StructRest::None => None,
1439 StructRest::None | StructRest::NoneWithError(_) => None,
14391440 };
14401441 let struct_pat = hir::PatKind::Struct(qpath, field_pats, fields_omitted);
14411442 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> {
162162 self.word("{");
163163 let has_rest = match rest {
164164 ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true,
165 ast::StructRest::None => false,
165 ast::StructRest::None | ast::StructRest::NoneWithError(_) => false,
166166 };
167167 if fields.is_empty() && !has_rest {
168168 self.word("}");
compiler/rustc_codegen_llvm/src/va_arg.rs+3-3
......@@ -8,7 +8,7 @@ use rustc_codegen_ssa::traits::{
88use rustc_middle::bug;
99use rustc_middle::ty::Ty;
1010use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
11use rustc_target::spec::{Abi, Arch, Env};
11use rustc_target::spec::{Arch, Env, RustcAbi};
1212
1313use crate::builder::Builder;
1414use crate::llvm::{Type, Value};
......@@ -272,7 +272,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
272272
273273 // Rust does not currently support any powerpc softfloat targets.
274274 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);
276276 assert!(!is_soft_float_abi);
277277
278278 // All instances of VaArgSafe are passed directly.
......@@ -1077,7 +1077,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
10771077 AllowHigherAlign::Yes,
10781078 ForceRightAdjust::Yes,
10791079 ),
1080 Arch::RiscV32 if target.abi == Abi::Ilp32e => {
1080 Arch::RiscV32 if target.llvm_abiname == "ilp32e" => {
10811081 // FIXME: clang manually adjusts the alignment for this ABI. It notes:
10821082 //
10831083 // > 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<'_> {
26622662 ExprKind::Struct(_, fields, init) => {
26632663 let init_side_effects = match init {
26642664 StructTailExpr::Base(init) => init.can_have_side_effects(),
2665 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2665 StructTailExpr::DefaultFields(_)
2666 | StructTailExpr::None
2667 | StructTailExpr::NoneWithError(_) => false,
26662668 };
26672669 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
26682670 || init_side_effects
......@@ -2954,6 +2956,12 @@ pub enum StructTailExpr<'hir> {
29542956 /// fields' default values will be used to populate any fields not explicitly mentioned:
29552957 /// `Foo { .. }`.
29562958 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),
29572965}
29582966
29592967/// 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>)
830830 walk_list!(visitor, visit_expr_field, fields);
831831 match optional_base {
832832 StructTailExpr::Base(base) => try_visit!(visitor.visit_expr(base)),
833 StructTailExpr::None | StructTailExpr::DefaultFields(_) => {}
833 StructTailExpr::None
834 | StructTailExpr::NoneWithError(_)
835 | StructTailExpr::DefaultFields(_) => {}
834836 }
835837 }
836838 ExprKind::Tup(subexpressions) => {
compiler/rustc_hir_analysis/src/lib.rs+7-9
......@@ -88,6 +88,7 @@ use rustc_abi::{CVariadicStatus, ExternAbi};
8888use rustc_hir as hir;
8989use rustc_hir::def::DefKind;
9090use rustc_hir::lints::DelayedLint;
91use rustc_lint::DecorateAttrLint;
9192use rustc_middle::mir::interpret::GlobalId;
9293use rustc_middle::query::Providers;
9394use rustc_middle::ty::{Const, Ty, TyCtxt};
......@@ -148,20 +149,17 @@ pub fn provide(providers: &mut Providers) {
148149 };
149150}
150151
151fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
152pub fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
152153 match lint {
153154 DelayedLint::AttributeParsing(attribute_lint) => {
154 tcx.node_span_lint(
155 tcx.emit_node_span_lint(
155156 attribute_lint.lint_id.lint,
156157 attribute_lint.id,
157158 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,
165163 },
166164 );
167165 }
compiler/rustc_hir_pretty/src/lib.rs+1
......@@ -1314,6 +1314,7 @@ impl<'a> State<'a> {
13141314 self.end(ib);
13151315 }
13161316 hir::StructTailExpr::None => {}
1317 hir::StructTailExpr::NoneWithError(_) => {}
13171318 }
13181319 self.space();
13191320 self.word("}");
compiler/rustc_hir_typeck/src/expr.rs+232-205
......@@ -2000,229 +2000,256 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20002000 return;
20012001 }
20022002
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 }
20132015 }
20142016 }
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 });
20862046 return;
20872047 }
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 ),
21582055 );
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();
21662058 }
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",
21782070 )
21792071 .emit();
2180 }
2181 });
2182 match adt_ty.kind() {
2072 return;
2073 }
2074 let fru_tys = match adt_ty.kind() {
21832075 ty::Adt(adt, args) if adt.is_struct() => variant
21842076 .fields
21852077 .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)))
21872084 .collect(),
21882085 _ => {
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);
21892171 self.dcx()
21902172 .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
21912173 return;
21922174 }
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 }
21932252 }
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 );
22262253 }
22272254 }
22282255 }
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
673673
674674 let with_expr = match *opt_with {
675675 hir::StructTailExpr::Base(w) => &*w,
676 hir::StructTailExpr::DefaultFields(_) | hir::StructTailExpr::None => {
676 hir::StructTailExpr::DefaultFields(_)
677 | hir::StructTailExpr::None
678 | hir::StructTailExpr::NoneWithError(_) => {
677679 return Ok(());
678680 }
679681 };
compiler/rustc_lint/src/context.rs+5-27
......@@ -11,7 +11,7 @@ use rustc_ast::util::parser::ExprPrecedence;
1111use rustc_data_structures::fx::FxIndexMap;
1212use rustc_data_structures::sync;
1313use rustc_data_structures::unord::UnordMap;
14use rustc_errors::{Diag, Diagnostic, LintBuffer, LintDiagnostic, MultiSpan};
14use rustc_errors::{Diag, Diagnostic, LintBuffer, MultiSpan};
1515use rustc_feature::Features;
1616use rustc_hir::def::Res;
1717use rustc_hir::def_id::{CrateNum, DefId};
......@@ -535,8 +535,8 @@ pub trait LintContext {
535535 decorate: impl for<'a> Diagnostic<'a, ()>,
536536 );
537537
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)]`).
540540 fn emit_span_lint<S: Into<MultiSpan>>(
541541 &self,
542542 lint: &'static Lint,
......@@ -546,20 +546,6 @@ pub trait LintContext {
546546 self.opt_span_diag_lint(lint, Some(span), decorator);
547547 }
548548
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
563549 /// Emit a lint at the appropriate level, with an associated span.
564550 ///
565551 /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
......@@ -573,16 +559,8 @@ pub trait LintContext {
573559 self.opt_span_lint(lint, Some(span), decorate);
574560 }
575561
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)]`).
586564 fn emit_diag_lint(&self, lint: &'static Lint, decorator: impl for<'a> Diagnostic<'a, ()>) {
587565 self.opt_span_diag_lint(lint, None as Option<Span>, decorator);
588566 }
compiler/rustc_lint/src/early.rs+16-4
......@@ -15,6 +15,7 @@ use rustc_session::lint::LintPass;
1515use rustc_span::{Ident, Span};
1616use tracing::debug;
1717
18use crate::DecorateBuiltinLint;
1819use crate::context::{EarlyContext, LintContext, LintStore};
1920use crate::passes::{EarlyLintPass, EarlyLintPassObject};
2021
......@@ -36,12 +37,23 @@ impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> {
3637 fn check_id(&mut self, id: ast::NodeId) {
3738 for early_lint in self.context.buffered.take(id) {
3839 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 {
4041 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 );
4251 }
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 }
4557 }
4658 }
4759
compiler/rustc_lint/src/early/diagnostics.rs+403-375
......@@ -2,7 +2,8 @@ use std::borrow::Cow;
22
33use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
44use 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,
67};
78use rustc_hir::lints::{AttributeLintKind, FormatWarning};
89use rustc_middle::middle::stability;
......@@ -16,460 +17,487 @@ use crate::lints;
1617
1718mod check_cfg;
1819
19pub 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.
22pub struct DecorateBuiltinLint<'sess, 'tcx> {
23 pub sess: &'sess Session,
24 pub tcx: Option<TyCtxt<'tcx>>,
25 pub diagnostic: BuiltinLintDiag,
26}
27
28impl<'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 })
3339 })
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(),
6054 }
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)
6556 }
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 {
7085 subdiag: elided_lifetime_in_path_suggestion(
71 sess.source_map(),
86 self.sess.source_map(),
7287 n,
7388 path_span,
7489 incl_angl_brckt,
7590 insertion_span,
7691 ),
7792 }
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,
9798 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)
102118 }
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 {
127132 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 {
144157 label: label_span,
145158 suggestion: label_span.shrink_to_hi(),
146159 prefix,
147160 }
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)
159165 }
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 {
163174 sub: lints::BreakWithLabelAndLoopSub {
164175 left: sugg_span.shrink_to_lo(),
165176 right: sugg_span.shrink_to_hi(),
166177 },
167178 }
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 },
224188 };
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 })
230213 } else {
231 positional_arg_to_replace
214 None
232215 };
233 (Some(span_to_replace), name)
234 } else {
235 (None, String::new())
236 };
237216
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,
239226 named_arg_sp,
240 position_label_sp: position_sp_for_msg,
241 suggestion,
242 name,
243227 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)
244257 }
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 {
254264 first_reexport: first_reexport_span,
255265 duplicate_reexport: duplicate_reexport_span,
256266 name,
257267 namespace,
258268 }
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 {
268276 glob_reexport: glob_reexport_span,
269277 private_item: private_item_span,
270278
271279 name,
272280 namespace,
273281 }
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 {
289287 elided,
288 span: lt_span,
290289 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)
291300 }
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 },
301308
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 }
307319 }
308 BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, diag),
309320 }
310321}
311322
312pub 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.
325pub struct DecorateAttrLint<'a, 'sess, 'tcx> {
326 pub sess: &'sess Session,
327 pub tcx: Option<TyCtxt<'tcx>>,
328 pub diagnostic: &'a AttributeLintKind,
329}
330
331impl<'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)
330336 }
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)
338347 }
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)
350355 }
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 {
355374 name: name.clone(),
356375 is_used_as_inner,
357376 target_span: (!is_used_as_inner).then_some(target_span),
358377 target,
359378 }
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)
367399 }
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 }
379400
380 &AttributeLintKind::DocAutoCfgExpectsHideOrShow => {
381 lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag)
382 }
401 &AttributeLintKind::DocAutoCfgExpectsHideOrShow => {
402 lints::DocAutoCfgExpectsHideOrShow.into_diag(dcx, level)
403 }
383404
384 &AttributeLintKind::AmbiguousDeriveHelpers => {
385 lints::AmbiguousDeriveHelpers.decorate_lint(diag)
386 }
405 &AttributeLintKind::AmbiguousDeriveHelpers => {
406 lints::AmbiguousDeriveHelpers.into_diag(dcx, level)
407 }
387408
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 }
391412
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 }
395416
396 &AttributeLintKind::DocInvalid => { lints::DocInvalid }.decorate_lint(diag),
417 &AttributeLintKind::DocInvalid => lints::DocInvalid.into_diag(dcx, level),
397418
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 }
402427
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 }
406431
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 }
410435
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 }
414439
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 }
418443
419 &AttributeLintKind::DocAutoCfgWrongLiteral => {
420 lints::DocAutoCfgWrongLiteral.decorate_lint(diag)
421 }
444 &AttributeLintKind::DocAutoCfgWrongLiteral => {
445 lints::DocAutoCfgWrongLiteral.into_diag(dcx, level)
446 }
422447
423 &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.decorate_lint(diag),
448 &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.into_diag(dcx, level),
424449
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 }
428453
429 &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.decorate_lint(diag),
454 &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.into_diag(dcx, level),
430455
431 &AttributeLintKind::AttrCrateLevelOnly => lints::AttrCrateLevelOnly.decorate_lint(diag),
456 &AttributeLintKind::AttrCrateLevelOnly => {
457 lints::AttrCrateLevelOnly.into_diag(dcx, level)
458 }
432459
433 &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => {
434 lints::DoNotRecommendDoesNotExpectArgs.decorate_lint(diag)
435 }
460 &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => {
461 lints::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level)
462 }
436463
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),
441468
442 &AttributeLintKind::MalformedDoc => lints::MalformedDoc.decorate_lint(diag),
469 &AttributeLintKind::MalformedDoc => lints::MalformedDoc.into_diag(dcx, level),
443470
444 &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.decorate_lint(diag),
471 &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.into_diag(dcx, level),
445472
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)
456476 }
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)
459500 }
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)
473501 }
474502 }
475503}
compiler/rustc_lint/src/lib.rs+1-1
......@@ -131,7 +131,7 @@ use unused::*;
131131#[rustfmt::skip]
132132pub use builtin::{MissingDoc, SoftLints};
133133pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore};
134pub use early::diagnostics::{decorate_attribute_lint, decorate_builtin_lint};
134pub use early::diagnostics::{DecorateAttrLint, DecorateBuiltinLint};
135135pub use early::{EarlyCheckNode, check_ast_node};
136136pub use late::{check_crate, late_lint_mod, unerased_lint_store};
137137pub use levels::LintLevelsBuilder;
compiler/rustc_lint/src/lints.rs+62-62
......@@ -11,7 +11,7 @@ use rustc_errors::{
1111use rustc_hir as hir;
1212use rustc_hir::def_id::DefId;
1313use rustc_hir::intravisit::VisitorExt;
14use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
14use rustc_macros::{Diagnostic, Subdiagnostic};
1515use rustc_middle::ty::inhabitedness::InhabitedPredicate;
1616use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
1717use rustc_session::Session;
......@@ -1600,7 +1600,7 @@ impl Subdiagnostic for NonSnakeCaseDiagSub {
16001600 }
16011601}
16021602
1603#[derive(LintDiagnostic)]
1603#[derive(Diagnostic)]
16041604#[diag("{$sort} `{$name}` should have an upper case name")]
16051605pub(crate) struct NonUpperCaseGlobal<'a> {
16061606 pub sort: &'a str,
......@@ -2712,7 +2712,7 @@ pub(crate) struct UnexpectedCfgCargoMacroHelp {
27122712 pub crate_name: Symbol,
27132713}
27142714
2715#[derive(LintDiagnostic)]
2715#[derive(Diagnostic)]
27162716#[diag("unexpected `cfg` condition name: `{$name}`")]
27172717pub(crate) struct UnexpectedCfgName {
27182718 #[subdiagnostic]
......@@ -2859,7 +2859,7 @@ pub(crate) mod unexpected_cfg_name {
28592859 }
28602860}
28612861
2862#[derive(LintDiagnostic)]
2862#[derive(Diagnostic)]
28632863#[diag(
28642864 "unexpected `cfg` condition value: {$has_value ->
28652865 [true] `{$value}`
......@@ -2994,7 +2994,7 @@ pub(crate) mod unexpected_cfg_value {
29942994 }
29952995}
29962996
2997#[derive(LintDiagnostic)]
2997#[derive(Diagnostic)]
29982998#[diag("extern crate `{$extern_crate}` is unused in crate `{$local_crate}`")]
29992999#[help("remove the dependency or add `use {$extern_crate} as _;` to the crate root")]
30003000pub(crate) struct UnusedCrateDependency {
......@@ -3003,7 +3003,7 @@ pub(crate) struct UnusedCrateDependency {
30033003}
30043004
30053005// FIXME(jdonszelmann): duplicated in rustc_attr_parsing, should be moved there completely.
3006#[derive(LintDiagnostic)]
3006#[derive(Diagnostic)]
30073007#[diag(
30083008 "{$num_suggestions ->
30093009 [1] attribute must be of the form {$suggestions}
......@@ -3018,7 +3018,7 @@ pub(crate) struct IllFormedAttributeInput {
30183018 pub docs: &'static str,
30193019}
30203020
3021#[derive(LintDiagnostic)]
3021#[derive(Diagnostic)]
30223022#[diag("unicode codepoint changing visible direction of text present in comment")]
30233023#[note(
30243024 "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 {
30583058 pub spans: Vec<Span>,
30593059}
30603060
3061#[derive(LintDiagnostic)]
3061#[derive(Diagnostic)]
30623062#[diag(
30633063 "absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition"
30643064)]
......@@ -3077,14 +3077,14 @@ pub(crate) struct AbsPathWithModuleSugg {
30773077 pub replacement: String,
30783078}
30793079
3080#[derive(LintDiagnostic)]
3080#[derive(Diagnostic)]
30813081#[diag("hidden lifetime parameters in types are deprecated")]
30823082pub(crate) struct ElidedLifetimesInPaths {
30833083 #[subdiagnostic]
30843084 pub subdiag: ElidedLifetimeInPathSubdiag,
30853085}
30863086
3087#[derive(LintDiagnostic)]
3087#[derive(Diagnostic)]
30883088#[diag(
30893089 "{$num_snippets ->
30903090 [one] unused import: {$span_snippets}
......@@ -3128,7 +3128,7 @@ pub(crate) enum UnusedImportsSugg {
31283128 },
31293129}
31303130
3131#[derive(LintDiagnostic)]
3131#[derive(Diagnostic)]
31323132#[diag("the item `{$ident}` is imported redundantly")]
31333133pub(crate) struct RedundantImport {
31343134 #[subdiagnostic]
......@@ -3164,7 +3164,7 @@ pub(crate) enum RedundantImportSub {
31643164 },
31653165}
31663166
3167#[derive(LintDiagnostic)]
3167#[derive(Diagnostic)]
31683168pub(crate) enum PatternsInFnsWithoutBody {
31693169 #[diag("patterns aren't allowed in foreign function declarations")]
31703170 Foreign {
......@@ -3191,7 +3191,7 @@ pub(crate) struct PatternsInFnsWithoutBodySub {
31913191 pub ident: Ident,
31923192}
31933193
3194#[derive(LintDiagnostic)]
3194#[derive(Diagnostic)]
31953195#[diag("prefix `{$prefix}` is unknown")]
31963196pub(crate) struct ReservedPrefix {
31973197 #[label("unknown prefix")]
......@@ -3206,7 +3206,7 @@ pub(crate) struct ReservedPrefix {
32063206 pub prefix: String,
32073207}
32083208
3209#[derive(LintDiagnostic)]
3209#[derive(Diagnostic)]
32103210#[diag("prefix `'r` is reserved")]
32113211pub(crate) struct RawPrefix {
32123212 #[label("reserved prefix")]
......@@ -3219,7 +3219,7 @@ pub(crate) struct RawPrefix {
32193219 pub suggestion: Span,
32203220}
32213221
3222#[derive(LintDiagnostic)]
3222#[derive(Diagnostic)]
32233223#[diag(
32243224 "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression"
32253225)]
......@@ -3237,7 +3237,7 @@ pub(crate) struct BreakWithLabelAndLoopSub {
32373237 pub right: Span,
32383238}
32393239
3240#[derive(LintDiagnostic)]
3240#[derive(Diagnostic)]
32413241#[diag("where clause not allowed here")]
32423242#[note("see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information")]
32433243pub(crate) struct DeprecatedWhereClauseLocation {
......@@ -3266,7 +3266,7 @@ pub(crate) enum DeprecatedWhereClauseLocationSugg {
32663266 },
32673267}
32683268
3269#[derive(LintDiagnostic)]
3269#[derive(Diagnostic)]
32703270#[diag("lifetime parameter `{$ident}` only used once")]
32713271pub(crate) struct SingleUseLifetime {
32723272 #[label("this lifetime...")]
......@@ -3290,7 +3290,7 @@ pub(crate) struct SingleUseLifetimeSugg {
32903290 pub replace_lt: String,
32913291}
32923292
3293#[derive(LintDiagnostic)]
3293#[derive(Diagnostic)]
32943294#[diag("lifetime parameter `{$ident}` never used")]
32953295pub(crate) struct UnusedLifetime {
32963296 #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")]
......@@ -3299,7 +3299,7 @@ pub(crate) struct UnusedLifetime {
32993299 pub ident: Ident,
33003300}
33013301
3302#[derive(LintDiagnostic)]
3302#[derive(Diagnostic)]
33033303#[diag("named argument `{$named_arg_name}` is not used by name")]
33043304pub(crate) struct NamedArgumentUsedPositionally {
33053305 #[label("this named argument is referred to by position in formatting string")]
......@@ -3318,7 +3318,7 @@ pub(crate) struct NamedArgumentUsedPositionally {
33183318 pub named_arg_name: String,
33193319}
33203320
3321#[derive(LintDiagnostic)]
3321#[derive(Diagnostic)]
33223322#[diag("ambiguous glob re-exports")]
33233323pub(crate) struct AmbiguousGlobReexports {
33243324 #[label("the name `{$name}` in the {$namespace} namespace is first re-exported here")]
......@@ -3330,7 +3330,7 @@ pub(crate) struct AmbiguousGlobReexports {
33303330 pub namespace: String,
33313331}
33323332
3333#[derive(LintDiagnostic)]
3333#[derive(Diagnostic)]
33343334#[diag("private item shadows public glob re-export")]
33353335pub(crate) struct HiddenGlobReexports {
33363336 #[note(
......@@ -3344,7 +3344,7 @@ pub(crate) struct HiddenGlobReexports {
33443344 pub namespace: String,
33453345}
33463346
3347#[derive(LintDiagnostic)]
3347#[derive(Diagnostic)]
33483348#[diag("unnecessary qualification")]
33493349pub(crate) struct UnusedQualifications {
33503350 #[suggestion(
......@@ -3356,7 +3356,7 @@ pub(crate) struct UnusedQualifications {
33563356 pub removal_span: Span,
33573357}
33583358
3359#[derive(LintDiagnostic)]
3359#[derive(Diagnostic)]
33603360#[diag(
33613361 "{$elided ->
33623362 [true] `&` without an explicit lifetime name cannot be used here
......@@ -3422,7 +3422,7 @@ pub(crate) enum MutRefSugg {
34223422#[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")]
34233423pub(crate) struct UnqualifiedLocalImportsDiag;
34243424
3425#[derive(LintDiagnostic)]
3425#[derive(Diagnostic)]
34263426#[diag("will be parsed as a guarded string in Rust 2024")]
34273427pub(crate) struct ReservedString {
34283428 #[suggestion(
......@@ -3433,7 +3433,7 @@ pub(crate) struct ReservedString {
34333433 pub suggestion: Span,
34343434}
34353435
3436#[derive(LintDiagnostic)]
3436#[derive(Diagnostic)]
34373437#[diag("reserved token in Rust 2024")]
34383438pub(crate) struct ReservedMultihash {
34393439 #[suggestion(
......@@ -3642,7 +3642,7 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
36423642 }
36433643}
36443644
3645#[derive(LintDiagnostic)]
3645#[derive(Diagnostic)]
36463646#[diag("unused attribute")]
36473647#[note(
36483648 "{$valid_without_list ->
......@@ -3664,7 +3664,7 @@ pub(crate) struct EmptyAttributeList {
36643664 pub valid_without_list: bool,
36653665}
36663666
3667#[derive(LintDiagnostic)]
3667#[derive(Diagnostic)]
36683668#[diag("`#[{$name}]` attribute cannot be used on {$target}")]
36693669#[warning(
36703670 "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 {
36843684 pub attr_span: Span,
36853685}
36863686
3687#[derive(LintDiagnostic)]
3687#[derive(Diagnostic)]
36883688#[diag(
36893689 "{$is_used_as_inner ->
36903690 [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
......@@ -3699,7 +3699,7 @@ pub(crate) struct InvalidAttrStyle {
36993699 pub target: &'static str,
37003700}
37013701
3702#[derive(LintDiagnostic)]
3702#[derive(Diagnostic)]
37033703#[diag("unused attribute")]
37043704pub(crate) struct UnusedDuplicate {
37053705 #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")]
......@@ -3712,28 +3712,28 @@ pub(crate) struct UnusedDuplicate {
37123712 pub warning: bool,
37133713}
37143714
3715#[derive(LintDiagnostic)]
3715#[derive(Diagnostic)]
37163716#[diag("malformed `doc` attribute input")]
37173717#[warning(
37183718 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
37193719)]
37203720pub(crate) struct MalformedDoc;
37213721
3722#[derive(LintDiagnostic)]
3722#[derive(Diagnostic)]
37233723#[diag("didn't expect any arguments here")]
37243724#[warning(
37253725 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
37263726)]
37273727pub(crate) struct ExpectedNoArgs;
37283728
3729#[derive(LintDiagnostic)]
3729#[derive(Diagnostic)]
37303730#[diag("expected this to be of the form `... = \"...\"`")]
37313731#[warning(
37323732 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
37333733)]
37343734pub(crate) struct ExpectedNameValue;
37353735
3736#[derive(LintDiagnostic)]
3736#[derive(Diagnostic)]
37373737#[diag("unsafe attribute used without unsafe")]
37383738pub(crate) struct UnsafeAttrOutsideUnsafeLint {
37393739 #[label("usage of unsafe attribute")]
......@@ -3751,7 +3751,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
37513751 pub right: Span,
37523752}
37533753
3754#[derive(LintDiagnostic)]
3754#[derive(Diagnostic)]
37553755#[diag("visibility qualifiers have no effect on `const _` declarations")]
37563756#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")]
37573757pub(crate) struct UnusedVisibility {
......@@ -3764,38 +3764,38 @@ pub(crate) struct UnusedVisibility {
37643764 pub span: Span,
37653765}
37663766
3767#[derive(LintDiagnostic)]
3767#[derive(Diagnostic)]
37683768#[diag("doc alias is duplicated")]
37693769pub(crate) struct DocAliasDuplicated {
37703770 #[label("first defined here")]
37713771 pub first_defn: Span,
37723772}
37733773
3774#[derive(LintDiagnostic)]
3774#[derive(Diagnostic)]
37753775#[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")]
37763776pub(crate) struct DocAutoCfgExpectsHideOrShow;
37773777
3778#[derive(LintDiagnostic)]
3778#[derive(Diagnostic)]
37793779#[diag("there exists a built-in attribute with the same name")]
37803780pub(crate) struct AmbiguousDeriveHelpers;
37813781
3782#[derive(LintDiagnostic)]
3782#[derive(Diagnostic)]
37833783#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items")]
37843784pub(crate) struct DocAutoCfgHideShowUnexpectedItem {
37853785 pub attr_name: Symbol,
37863786}
37873787
3788#[derive(LintDiagnostic)]
3788#[derive(Diagnostic)]
37893789#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items")]
37903790pub(crate) struct DocAutoCfgHideShowExpectsList {
37913791 pub attr_name: Symbol,
37923792}
37933793
3794#[derive(LintDiagnostic)]
3794#[derive(Diagnostic)]
37953795#[diag("invalid `doc` attribute")]
37963796pub(crate) struct DocInvalid;
37973797
3798#[derive(LintDiagnostic)]
3798#[derive(Diagnostic)]
37993799#[diag("unknown `doc` attribute `include`")]
38003800pub(crate) struct DocUnknownInclude {
38013801 pub inner: &'static str,
......@@ -3807,7 +3807,7 @@ pub(crate) struct DocUnknownInclude {
38073807 pub sugg: (Span, Applicability),
38083808}
38093809
3810#[derive(LintDiagnostic)]
3810#[derive(Diagnostic)]
38113811#[diag("unknown `doc` attribute `spotlight`")]
38123812#[note("`doc(spotlight)` was renamed to `doc(notable_trait)`")]
38133813#[note("`doc(spotlight)` is now a no-op")]
......@@ -3821,7 +3821,7 @@ pub(crate) struct DocUnknownSpotlight {
38213821 pub sugg_span: Span,
38223822}
38233823
3824#[derive(LintDiagnostic)]
3824#[derive(Diagnostic)]
38253825#[diag("unknown `doc` attribute `{$name}`")]
38263826#[note(
38273827 "`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 {
38333833 pub note_span: Span,
38343834}
38353835
3836#[derive(LintDiagnostic)]
3836#[derive(Diagnostic)]
38373837#[diag("unknown `doc` attribute `plugins`")]
38383838#[note(
38393839 "`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 {
38443844 pub label_span: Span,
38453845}
38463846
3847#[derive(LintDiagnostic)]
3847#[derive(Diagnostic)]
38483848#[diag("unknown `doc` attribute `{$name}`")]
38493849pub(crate) struct DocUnknownAny {
38503850 pub name: Symbol,
38513851}
38523852
3853#[derive(LintDiagnostic)]
3853#[derive(Diagnostic)]
38543854#[diag("expected boolean for `#[doc(auto_cfg = ...)]`")]
38553855pub(crate) struct DocAutoCfgWrongLiteral;
38563856
3857#[derive(LintDiagnostic)]
3857#[derive(Diagnostic)]
38583858#[diag("`#[doc(test(...)]` takes a list of attributes")]
38593859pub(crate) struct DocTestTakesList;
38603860
3861#[derive(LintDiagnostic)]
3861#[derive(Diagnostic)]
38623862#[diag("unknown `doc(test)` attribute `{$name}`")]
38633863pub(crate) struct DocTestUnknown {
38643864 pub name: Symbol,
38653865}
38663866
3867#[derive(LintDiagnostic)]
3867#[derive(Diagnostic)]
38683868#[diag("`#![doc(test(...)]` does not take a literal")]
38693869pub(crate) struct DocTestLiteral;
38703870
3871#[derive(LintDiagnostic)]
3871#[derive(Diagnostic)]
38723872#[diag("this attribute can only be applied at the crate level")]
38733873#[note(
38743874 "read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information"
38753875)]
38763876pub(crate) struct AttrCrateLevelOnly;
38773877
3878#[derive(LintDiagnostic)]
3878#[derive(Diagnostic)]
38793879#[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")]
38803880pub(crate) struct DoNotRecommendDoesNotExpectArgs;
38813881
3882#[derive(LintDiagnostic)]
3882#[derive(Diagnostic)]
38833883#[diag("invalid `crate_type` value")]
38843884pub(crate) struct UnknownCrateTypes {
38853885 #[subdiagnostic]
......@@ -3894,14 +3894,14 @@ pub(crate) struct UnknownCrateTypesSuggestion {
38943894 pub snippet: Symbol,
38953895}
38963896
3897#[derive(LintDiagnostic)]
3897#[derive(Diagnostic)]
38983898#[diag("unreachable configuration predicate")]
38993899pub(crate) struct UnreachableCfgSelectPredicate {
39003900 #[label("this configuration predicate is never reached")]
39013901 pub span: Span,
39023902}
39033903
3904#[derive(LintDiagnostic)]
3904#[derive(Diagnostic)]
39053905#[diag("unreachable configuration predicate")]
39063906pub(crate) struct UnreachableCfgSelectPredicateWildcard {
39073907 #[label("this configuration predicate is never reached")]
......@@ -3911,19 +3911,19 @@ pub(crate) struct UnreachableCfgSelectPredicateWildcard {
39113911 pub wildcard_span: Span,
39123912}
39133913
3914#[derive(LintDiagnostic)]
3914#[derive(Diagnostic)]
39153915#[diag("positional format arguments are not allowed here")]
39163916#[help(
39173917 "only named format arguments with the name of one of the generic types are allowed in this context"
39183918)]
39193919pub(crate) struct DisallowedPositionalArgument;
39203920
3921#[derive(LintDiagnostic)]
3921#[derive(Diagnostic)]
39223922#[diag("invalid format specifier")]
39233923#[help("no format specifier are supported in this position")]
39243924pub(crate) struct InvalidFormatSpecifier;
39253925
3926#[derive(LintDiagnostic)]
3926#[derive(Diagnostic)]
39273927#[diag("{$description}")]
39283928pub(crate) struct WrappedParserError<'a> {
39293929 pub description: &'a str,
......@@ -3932,7 +3932,7 @@ pub(crate) struct WrappedParserError<'a> {
39323932 pub label: &'a str,
39333933}
39343934
3935#[derive(LintDiagnostic)]
3935#[derive(Diagnostic)]
39363936#[diag("`{$option_name}` is ignored due to previous definition of `{$option_name}`")]
39373937pub(crate) struct IgnoredDiagnosticOption {
39383938 pub option_name: Symbol,
......@@ -3942,17 +3942,17 @@ pub(crate) struct IgnoredDiagnosticOption {
39423942 pub later_span: Span,
39433943}
39443944
3945#[derive(LintDiagnostic)]
3945#[derive(Diagnostic)]
39463946#[diag("missing options for `on_unimplemented` attribute")]
39473947#[help("at least one of the `message`, `note` and `label` options are expected")]
39483948pub(crate) struct MissingOptionsForOnUnimplementedAttr;
39493949
3950#[derive(LintDiagnostic)]
3950#[derive(Diagnostic)]
39513951#[diag("missing options for `on_const` attribute")]
39523952#[help("at least one of the `message`, `note` and `label` options are expected")]
39533953pub(crate) struct MissingOptionsForOnConstAttr;
39543954
3955#[derive(LintDiagnostic)]
3955#[derive(Diagnostic)]
39563956#[diag("malformed `on_unimplemented` attribute")]
39573957#[help("only `message`, `note` and `label` are allowed as options")]
39583958pub(crate) struct MalformedOnUnimplementedAttrLint {
......@@ -3960,7 +3960,7 @@ pub(crate) struct MalformedOnUnimplementedAttrLint {
39603960 pub span: Span,
39613961}
39623962
3963#[derive(LintDiagnostic)]
3963#[derive(Diagnostic)]
39643964#[diag("malformed `on_const` attribute")]
39653965#[help("only `message`, `note` and `label` are allowed as options")]
39663966pub(crate) struct MalformedOnConstAttrLint {
compiler/rustc_lint/src/nonstandard_style.rs+21-3
......@@ -1,6 +1,6 @@
11use rustc_abi::ExternAbi;
22use rustc_attr_parsing::AttributeParser;
3use rustc_errors::Applicability;
3use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level};
44use rustc_hir::attrs::{AttributeKind, ReprAttr};
55use rustc_hir::def::{DefKind, Res};
66use rustc_hir::def_id::DefId;
......@@ -461,6 +461,19 @@ declare_lint! {
461461
462462declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]);
463463
464struct NonUpperCaseGlobalGenerator<'a, F: FnOnce() -> NonUpperCaseGlobal<'a>> {
465 callback: F,
466}
467
468impl<'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
464477impl NonUpperCaseGlobals {
465478 fn check_upper_case(cx: &LateContext<'_>, sort: &str, did: Option<LocalDefId>, ident: &Ident) {
466479 let name = ident.name.as_str();
......@@ -517,7 +530,7 @@ impl NonUpperCaseGlobals {
517530 }
518531 }
519532
520 cx.emit_span_lint_lazy(NON_UPPER_CASE_GLOBALS, ident.span, || {
533 let callback = || {
521534 // Compute usages lazily as it can expansive and useless when the lint is allowed.
522535 // cf. https://github.com/rust-lang/rust/pull/142645#issuecomment-2993024625
523536 let usages = if can_change_usages
......@@ -537,7 +550,12 @@ impl NonUpperCaseGlobals {
537550 };
538551
539552 NonUpperCaseGlobal { sort, name, sub, usages }
540 });
553 };
554 cx.emit_span_lint(
555 NON_UPPER_CASE_GLOBALS,
556 ident.span,
557 NonUpperCaseGlobalGenerator { callback },
558 );
541559 }
542560 }
543561}
compiler/rustc_mir_build/src/thir/cx/expr.rs+6-2
......@@ -632,7 +632,8 @@ impl<'tcx> ThirBuildCx<'tcx> {
632632 .collect(),
633633 )
634634 }
635 hir::StructTailExpr::None => AdtExprBase::None,
635 hir::StructTailExpr::None
636 | hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None,
636637 },
637638 }))
638639 }
......@@ -669,7 +670,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
669670 hir::StructTailExpr::Base(base) => {
670671 span_bug!(base.span, "unexpected res: {:?}", res);
671672 }
672 hir::StructTailExpr::None => AdtExprBase::None,
673 hir::StructTailExpr::None
674 | hir::StructTailExpr::NoneWithError(_) => {
675 AdtExprBase::None
676 }
673677 },
674678 }))
675679 }
compiler/rustc_parse/src/parser/expr.rs+13
......@@ -3842,6 +3842,15 @@ impl<'a> Parser<'a> {
38423842 recovered_async = Some(guar);
38433843 }
38443844
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
38453854 // If the next token is a comma, then try to parse
38463855 // what comes next as additional fields, rather than
38473856 // bailing out until next `}`.
......@@ -3892,6 +3901,10 @@ impl<'a> Parser<'a> {
38923901 } else if let Some(f) = field_ident(self, guar) {
38933902 fields.push(f);
38943903 }
3904
3905 // See comment above on this same assignment inside of field parsing.
3906 base = ast::StructRest::NoneWithError(guar);
3907
38953908 self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
38963909 let _ = self.eat(exp!(Comma));
38973910 }
compiler/rustc_privacy/src/lib.rs+1-1
......@@ -1100,7 +1100,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
11001100 qpath.span(),
11011101 );
11021102 }
1103 hir::StructTailExpr::None => {
1103 hir::StructTailExpr::None | hir::StructTailExpr::NoneWithError(_) => {
11041104 let mut failed_fields = vec![];
11051105 for field in fields {
11061106 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> {
50665066 match &se.rest {
50675067 StructRest::Base(expr) => self.visit_expr(expr),
50685068 StructRest::Rest(_span) => {}
5069 StructRest::None => {}
5069 StructRest::None | StructRest::NoneWithError(_) => {}
50705070 }
50715071 }
50725072
compiler/rustc_target/src/callconv/aarch64.rs+3-3
......@@ -3,7 +3,7 @@ use std::iter;
33use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface};
44
55use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
6use crate::spec::{Abi, HasTargetSpec, Target};
6use crate::spec::{HasTargetSpec, RustcAbi, Target};
77
88/// Indicates the variant of the AArch64 ABI we are compiling for.
99/// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
......@@ -34,7 +34,7 @@ where
3434 RegKind::Integer => false,
3535 // The softfloat ABI treats floats like integers, so they
3636 // 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),
3838 RegKind::Vector => size.bits() == 64 || size.bits() == 128,
3939 };
4040
......@@ -43,7 +43,7 @@ where
4343}
4444
4545fn softfloat_float_abi<Ty>(target: &Target, arg: &mut ArgAbi<'_, Ty>) {
46 if target.abi != Abi::SoftFloat {
46 if target.rustc_abi != Some(RustcAbi::Softfloat) {
4747 return;
4848 }
4949 // 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 {
22102210 pub env: Env,
22112211 /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
22122212 /// 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`.
22152217 pub abi: Abi,
22162218 /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
22172219 #[rustc_lint_opt_deny_field_access(
......@@ -3228,8 +3230,8 @@ impl Target {
32283230 ),
32293231 RustcAbi::Softfloat => check_matches!(
32303232 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"
32333235 ),
32343236 }
32353237 }
compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs+3-2
......@@ -8,13 +8,14 @@
88use rustc_abi::Endian;
99
1010use 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,
1313};
1414
1515pub(crate) fn target() -> Target {
1616 let opts = TargetOptions {
1717 abi: Abi::SoftFloat,
18 rustc_abi: Some(RustcAbi::Softfloat),
1819 linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
1920 linker: Some("rust-lld".into()),
2021 features: "+v8a,+strict-align,-neon".into(),
compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs+3-2
......@@ -7,13 +7,14 @@
77// For example, `-C target-cpu=cortex-a53`.
88
99use 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,
1212};
1313
1414pub(crate) fn target() -> Target {
1515 let opts = TargetOptions {
1616 abi: Abi::SoftFloat,
17 rustc_abi: Some(RustcAbi::Softfloat),
1718 linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
1819 linker: Some("rust-lld".into()),
1920 features: "+v8a,+strict-align,-neon".into(),
compiler/rustc_target/src/spec/targets/aarch64v8r_unknown_none_softfloat.rs+3-2
......@@ -1,11 +1,12 @@
11use 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,
44};
55
66pub(crate) fn target() -> Target {
77 let opts = TargetOptions {
88 abi: Abi::SoftFloat,
9 rustc_abi: Some(RustcAbi::Softfloat),
910 linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
1011 linker: Some("rust-lld".into()),
1112 relocation_model: RelocModel::Static,
compiler/rustc_target/src/target_features.rs+16-12
......@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55use rustc_macros::HashStable_Generic;
66use rustc_span::{Symbol, sym};
77
8use crate::spec::{Abi, Arch, FloatAbi, RustcAbi, Target};
8use crate::spec::{Arch, FloatAbi, RustcAbi, Target};
99
1010/// Features that control behaviour of rustc, rather than the codegen.
1111/// These exist globally and are not in the target-specific lists below.
......@@ -1154,17 +1154,21 @@ impl Target {
11541154 Arch::AArch64 | Arch::Arm64EC => {
11551155 // Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force
11561156 // 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:?}"),
11681172 }
11691173 }
11701174 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> {
38833883 err.span_note(assoc_span, msg);
38843884 }
38853885 ObligationCauseCode::TrivialBound => {
3886 err.help("see issue #48214");
38873886 tcx.disabled_nightly_features(err, [(String::new(), sym::trivial_bounds)]);
38883887 }
38893888 ObligationCauseCode::OpaqueReturnType(expr_info) => {
library/core/src/iter/traits/iterator.rs+23-7
......@@ -631,8 +631,15 @@ pub const trait Iterator {
631631 Zip::new(self, other.into_iter())
632632 }
633633
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.
636643 ///
637644 /// In case `separator` does not implement [`Clone`] or needs to be
638645 /// computed every time, use [`intersperse_with`].
......@@ -663,6 +670,7 @@ pub const trait Iterator {
663670 /// ```
664671 ///
665672 /// [`Clone`]: crate::clone::Clone
673 /// [`intersperse`]: Iterator::intersperse
666674 /// [`intersperse_with`]: Iterator::intersperse_with
667675 #[inline]
668676 #[unstable(feature = "iter_intersperse", issue = "79524")]
......@@ -676,12 +684,19 @@ pub const trait Iterator {
676684 }
677685
678686 /// 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.
680688 ///
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.
685700 ///
686701 /// If the iterator's item implements [`Clone`], it may be easier to use
687702 /// [`intersperse`].
......@@ -723,6 +738,7 @@ pub const trait Iterator {
723738 /// ```
724739 /// [`Clone`]: crate::clone::Clone
725740 /// [`intersperse`]: Iterator::intersperse
741 /// [`intersperse_with`]: Iterator::intersperse_with
726742 #[inline]
727743 #[unstable(feature = "iter_intersperse", issue = "79524")]
728744 #[rustc_non_const_trait_method]
library/coretests/tests/iter/adapters/intersperse.rs+200
......@@ -152,3 +152,203 @@ fn test_try_fold_specialization_intersperse_err() {
152152 iter.try_for_each(|item| if item == "b" { None } else { Some(()) });
153153 assert_eq!(iter.next(), None);
154154}
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]
161fn 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]
205fn 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]
261fn 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]
305fn 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
22//!
33//! # Examples
44//!
library/std/src/sys/pal/hermit/mod.rs+3-3
......@@ -1,7 +1,7 @@
1//! System bindings for HermitCore
1//! System bindings for Hermit
22//!
33//! This module contains the facade (aka platform-specific) implementations of
4//! OS level functionality for HermitCore.
4//! OS level functionality for Hermit.
55//!
66//! This is all super highly experimental and not actually intended for
77//! wide/production use yet, it's still all in the experimental category. This
......@@ -30,7 +30,7 @@ pub fn unsupported<T>() -> io::Result<T> {
3030}
3131
3232pub 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")
3434}
3535
3636pub fn abort_internal() -> ! {
src/librustdoc/clean/cfg.rs+1-1
......@@ -429,7 +429,7 @@ impl fmt::Display for Display<'_> {
429429 "freebsd" => "FreeBSD",
430430 "fuchsia" => "Fuchsia",
431431 "haiku" => "Haiku",
432 "hermit" => "HermitCore",
432 "hermit" => "Hermit",
433433 "illumos" => "illumos",
434434 "ios" => "iOS",
435435 "l4re" => "L4Re",
src/librustdoc/core.rs+5-1
......@@ -285,7 +285,11 @@ pub(crate) fn create_config(
285285 crate_check_cfg: check_cfgs,
286286 input,
287287 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 },
289293 file_loader: None,
290294 lint_caps,
291295 psess_created: None,
src/librustdoc/lib.rs+1-18
......@@ -74,7 +74,6 @@ use std::process::ExitCode;
7474
7575use rustc_errors::DiagCtxtHandle;
7676use rustc_hir::def_id::LOCAL_CRATE;
77use rustc_hir::lints::DelayedLint;
7877use rustc_interface::interface;
7978use rustc_middle::ty::TyCtxt;
8079use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
......@@ -910,23 +909,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
910909 for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
911910 if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
912911 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);
930913 }
931914 }
932915 }
src/rustdoc-json-types/lib.rs+33
......@@ -682,6 +682,39 @@ pub enum ItemEnum {
682682 },
683683}
684684
685impl 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
685718/// A module declaration, e.g. `mod foo;` or `mod foo {}`.
686719#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
687720pub 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 {
242242 !expr_ty_has_significant_drop(cx, expr)
243243 && fields.iter().all(|field| has_no_effect(cx, field.expr))
244244 && match &base {
245 StructTailExpr::None | StructTailExpr::DefaultFields(_) => true,
245 StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => true,
246246 StructTailExpr::Base(base) => has_no_effect(cx, base),
247247 }
248248 },
......@@ -353,7 +353,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
353353 } else {
354354 let base = match base {
355355 StructTailExpr::Base(base) => Some(base),
356 StructTailExpr::None | StructTailExpr::DefaultFields(_) => None,
356 StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None,
357357 };
358358 Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect())
359359 }
src/tools/clippy/clippy_lints/src/utils/author.rs+1-1
......@@ -673,7 +673,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
673673 bind!(self, qpath, fields);
674674 let base = OptionPat::new(match base {
675675 StructTailExpr::Base(base) => Some(self.bind("base", base)),
676 StructTailExpr::None | StructTailExpr::DefaultFields(_) => None,
676 StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None,
677677 });
678678 kind!("Struct({qpath}, {fields}, {base})");
679679 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>(
18091809 match struct_rest {
18101810 ast::StructRest::Base(expr) => Some(StructLitField::Base(&**expr)),
18111811 ast::StructRest::Rest(span) => Some(StructLitField::Rest(*span)),
1812 ast::StructRest::None => None,
1812 ast::StructRest::None | ast::StructRest::NoneWithError(_) => None,
18131813 }
18141814 .into_iter(),
18151815 );
tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs+13-17
......@@ -1,7 +1,7 @@
11#![crate_type = "staticlib"]
22#![feature(c_variadic)]
33
4use std::ffi::{CStr, CString, VaList, c_char, c_double, c_int, c_long, c_longlong};
4use core::ffi::{CStr, VaList, c_char, c_double, c_int, c_long, c_longlong};
55
66macro_rules! continue_if {
77 ($cond:expr) => {
......@@ -11,12 +11,8 @@ macro_rules! continue_if {
1111 };
1212}
1313
14unsafe 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 }
14unsafe fn compare_c_str(ptr: *const c_char, val: &CStr) -> bool {
15 val == CStr::from_ptr(ptr)
2016}
2117
2218#[unsafe(no_mangle)]
......@@ -35,42 +31,42 @@ pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
3531 continue_if!(ap.arg::<c_int>() == ';' as c_int);
3632 continue_if!(ap.arg::<c_int>() == 0x32);
3733 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!"));
3935 0
4036}
4137
4238#[unsafe(no_mangle)]
4339pub 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);
4541 continue_if!(ap.arg::<c_long>() == 12);
4642 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"));
4945 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"));
5147 0
5248}
5349
5450#[unsafe(no_mangle)]
5551pub 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);
5753 continue_if!(ap.arg::<c_int>() == 16);
5854 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!"));
6056 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 }
6258}
6359
6460#[unsafe(no_mangle)]
6561pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize {
6662 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!"));
6864 0
6965}
7066
7167#[unsafe(no_mangle)]
7268pub 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);
7470 continue_if!(ap.arg::<c_long>() == 12);
7571 continue_if!(ap.arg::<c_int>() == 'A' as c_int);
7672 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 @@
1010use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
1111
1212fn main() {
13 rustc().input("checkrust.rs").run();
13 rustc().edition("2021").input("checkrust.rs").run();
1414 cc().input("test.c")
1515 .input(static_lib_name("checkrust"))
1616 .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;
77use run_make_support::{path, rfs, rustdoc};
88
99fn main() {
10 rfs::create_dir("doc");
11
1012 // We're only emitting dep info, so we shouldn't be running static analysis to
1113 // figure out that this program is erroneous.
1214 // Ensure that all kinds of input reading flags end up in dep-info.
......@@ -20,7 +22,7 @@ fn main() {
2022 .emit("dep-info")
2123 .run();
2224
23 let content = rfs::read_to_string("foo.d");
25 let content = rfs::read_to_string("doc/foo.d");
2426 assert_contains(&content, "lib.rs:");
2527 assert_contains(&content, "foo.rs:");
2628 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};
55mod scrape;
66
77fn main() {
8 rfs::create_dir("rustdoc");
9
810 scrape::scrape(
911 &["--scrape-tests", "--emit=dep-info"],
1012 &["--emit=dep-info,invocation-specific"],
1113 );
1214
13 let content = rfs::read_to_string("foobar.d").replace(r"\", "/");
15 let content = rfs::read_to_string("rustdoc/foobar.d").replace(r"\", "/");
1416 assert_contains(&content, "lib.rs:");
1517 assert_contains(&content, "rustdoc/ex.calls:");
1618
17 let content = rfs::read_to_string("ex.d").replace(r"\", "/");
19 let content = rfs::read_to_string("rustdoc/ex.d").replace(r"\", "/");
1820 assert_contains(&content, "examples/ex.rs:");
1921}
tests/ui/const-generics/issues/issue-67185-2.stderr-2
......@@ -11,7 +11,6 @@ LL | impl Bar for [u16; 4] {}
1111 | ^^^^^^^^^^^^^^^^^^^^^ `[u16; 4]`
1212LL | impl Bar for [[u16; 3]; 3] {}
1313 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `[[u16; 3]; 3]`
14 = help: see issue #48214
1514help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1615 |
1716LL + #![feature(trivial_bounds)]
......@@ -30,7 +29,6 @@ LL | impl Bar for [u16; 4] {}
3029 | ^^^^^^^^^^^^^^^^^^^^^ `[u16; 4]`
3130LL | impl Bar for [[u16; 3]; 3] {}
3231 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `[[u16; 3]; 3]`
33 = help: see issue #48214
3432help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
3533 |
3634LL + #![feature(trivial_bounds)]
tests/ui/consts/assoc-const-elided-lifetime.stderr+4-4
......@@ -4,13 +4,13 @@ error: `'_` cannot be used here
44LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
55 | ^^
66 |
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>
97note: cannot automatically infer `'static` because of other lifetimes in scope
108 --> $DIR/assoc-const-elided-lifetime.rs:9:6
119 |
1210LL | impl<'a> Foo<'a> {
1311 | ^^
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>
1414note: the lint level is defined here
1515 --> $DIR/assoc-const-elided-lifetime.rs:1:9
1616 |
......@@ -28,13 +28,13 @@ error: `&` without an explicit lifetime name cannot be used here
2828LL | const BAR: &() = &();
2929 | ^
3030 |
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>
3331note: cannot automatically infer `'static` because of other lifetimes in scope
3432 --> $DIR/assoc-const-elided-lifetime.rs:9:6
3533 |
3634LL | impl<'a> Foo<'a> {
3735 | ^^
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>
3838help: use the `'static` lifetime
3939 |
4040LL | const BAR: &'static () = &();
tests/ui/consts/const-eval/ptr_fragments_in_final.rs+1
......@@ -1,4 +1,5 @@
11//! 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
23
34use std::{mem::{self, MaybeUninit}, ptr};
45
tests/ui/consts/const-eval/ptr_fragments_in_final.stderr+3-3
......@@ -1,5 +1,5 @@
11error: 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
33 |
44LL | const MEMCPY_RET: MaybeUninit<*const i32> = unsafe {
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -7,7 +7,7 @@ LL | const MEMCPY_RET: MaybeUninit<*const i32> = unsafe {
77 = 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
88
99error: 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
1111 |
1212LL | const MIXED_PTR: MaybeUninit<*const u8> = {
1313 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -15,7 +15,7 @@ LL | const MIXED_PTR: MaybeUninit<*const u8> = {
1515 = 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
1616
1717error: 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
1919 |
2020LL | const A: Thing = unsafe {
2121 | ^^^^^^^^^^^^^^
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
44LL | const STATIC: &str = "";
55 | ^
66 |
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>
97note: cannot automatically infer `'static` because of other lifetimes in scope
108 --> $DIR/elided-lifetime.rs:5:10
119 |
1210LL | impl Foo<'_> {
1311 | ^^
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>
1414note: the lint level is defined here
1515 --> $DIR/elided-lifetime.rs:1:9
1616 |
......@@ -27,13 +27,13 @@ error: `&` without an explicit lifetime name cannot be used here
2727LL | const STATIC: &str = "";
2828 | ^
2929 |
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>
3230note: cannot automatically infer `'static` because of other lifetimes in scope
3331 --> $DIR/elided-lifetime.rs:15:18
3432 |
3533LL | impl Bar for Foo<'_> {
3634 | ^^
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>
3737help: use the `'static` lifetime
3838 |
3939LL | 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
2424LL | const GAC_LIFETIME<'a>: &str = "";
2525 | ^
2626 |
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>
2927note: cannot automatically infer `'static` because of other lifetimes in scope
3028 --> $DIR/generic-associated-const.rs:8:24
3129 |
3230LL | const GAC_LIFETIME<'a>: &str = "";
3331 | ^^
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>
3434note: the lint level is defined here
3535 --> $DIR/generic-associated-const.rs:1:9
3636 |
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
44LL | const STATIC: &str = "";
55 | ^
66 |
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>
97note: cannot automatically infer `'static` because of other lifetimes in scope
108 --> $DIR/static-trait-impl.rs:8:10
119 |
1210LL | impl Bar<'_> for A {
1311 | ^^
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>
1414note: the lint level is defined here
1515 --> $DIR/static-trait-impl.rs:1:9
1616 |
tests/ui/cross/cross-fn-cache-hole.stderr-1
......@@ -9,7 +9,6 @@ help: this trait has no implementations, consider adding one
99 |
1010LL | trait Bar<X> { }
1111 | ^^^^^^^^^^^^
12 = help: see issue #48214
1312help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1413 |
1514LL + #![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
1414 |
1515LL | trait Trait0 {}
1616 | ^^^^^^^^^^^^
17 = help: see issue #48214
1817help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1918 |
2019LL + #![feature(trivial_bounds)]
tests/ui/feature-gates/feature-gate-trivial_bounds.stderr-11
......@@ -9,7 +9,6 @@ help: the trait `Foo` is implemented for `()`
99 |
1010LL | impl Foo for () where i32: Foo {
1111 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12 = help: see issue #48214
1312help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1413 |
1514LL + #![feature(trivial_bounds)]
......@@ -26,7 +25,6 @@ help: the trait `Foo` is implemented for `()`
2625 |
2726LL | impl Foo for () where i32: Foo {
2827 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29 = help: see issue #48214
3028help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
3129 |
3230LL + #![feature(trivial_bounds)]
......@@ -43,7 +41,6 @@ help: the trait `Foo` is implemented for `()`
4341 |
4442LL | impl Foo for () where i32: Foo {
4543 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46 = help: see issue #48214
4744help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
4845 |
4946LL + #![feature(trivial_bounds)]
......@@ -60,7 +57,6 @@ help: the trait `Foo` is implemented for `()`
6057 |
6158LL | impl Foo for () where i32: Foo {
6259 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
63 = help: see issue #48214
6460help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
6561 |
6662LL + #![feature(trivial_bounds)]
......@@ -77,7 +73,6 @@ help: the trait `Foo` is implemented for `()`
7773 |
7874LL | impl Foo for () where i32: Foo {
7975 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
80 = help: see issue #48214
8176help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
8277 |
8378LL + #![feature(trivial_bounds)]
......@@ -94,7 +89,6 @@ help: the trait `Foo` is implemented for `()`
9489 |
9590LL | impl Foo for () where i32: Foo {
9691 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
97 = help: see issue #48214
9892help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
9993 |
10094LL + #![feature(trivial_bounds)]
......@@ -106,7 +100,6 @@ error[E0277]: the trait bound `String: Neg` is not satisfied
106100LL | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
107101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Neg` is not implemented for `String`
108102 |
109 = help: see issue #48214
110103help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
111104 |
112105LL + #![feature(trivial_bounds)]
......@@ -119,7 +112,6 @@ LL | fn use_for() where i32: Iterator {
119112 | ^^^^^^^^^^^^^ `i32` is not an iterator
120113 |
121114 = help: the trait `Iterator` is not implemented for `i32`
122 = help: see issue #48214
123115help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
124116 |
125117LL + #![feature(trivial_bounds)]
......@@ -132,7 +124,6 @@ LL | struct TwoStrs(str, str) where str: Sized;
132124 | ^^^^^^^^^^ doesn't have a size known at compile-time
133125 |
134126 = help: the trait `Sized` is not implemented for `str`
135 = help: see issue #48214
136127help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
137128 |
138129LL + #![feature(trivial_bounds)]
......@@ -150,7 +141,6 @@ note: required because it appears within the type `Dst<(dyn A + 'static)>`
150141 |
151142LL | struct Dst<X: ?Sized> {
152143 | ^^^
153 = help: see issue #48214
154144help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
155145 |
156146LL + #![feature(trivial_bounds)]
......@@ -163,7 +153,6 @@ LL | fn return_str() -> str where str: Sized {
163153 | ^^^^^^^^^^ doesn't have a size known at compile-time
164154 |
165155 = help: the trait `Sized` is not implemented for `str`
166 = help: see issue #48214
167156help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
168157 |
169158LL + #![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
44LL | String: Copy;
55 | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
66 |
7 = help: see issue #48214
87help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
98 |
109LL + #![feature(trivial_bounds)]
......@@ -16,7 +15,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
1615LL | fn demo() -> impl Foo
1716 | ^^^^^^^^ the trait `Copy` is not implemented for `String`
1817 |
19 = help: see issue #48214
2018help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
2119 |
2220LL + #![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
4pub use src::aliases::B;
5pub use src::hidden_core::make;
6
7mod 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 @@
1pub struct Foo {
2 pub foo: extern "C" fn()
3}
4
5extern "C" fn the_foo() {}
6
7pub 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 @@
1extern crate extern_crate_indirect_fn_ptr_aux_1 as crate1;
2
3pub 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
5pub fn foo() {}
tests/ui/imports/auxiliary/extern-crate-no-prefer-dynamic-aux-2.rs created+3
......@@ -0,0 +1,3 @@
1extern crate extern_crate_no_prefer_dynamic_aux_1;
2
3pub fn bar() {}
tests/ui/imports/auxiliary/extern-transmute-aux.rs created+5
......@@ -0,0 +1,5 @@
1#![crate_type = "lib"]
2
3extern "C" {
4 pub fn transmute();
5}
tests/ui/imports/auxiliary/typeid-cross-crate-aux.rs created+87
......@@ -0,0 +1,87 @@
1pub 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 @@
1pub mod bar {
2 pub fn foo() {}
3}
tests/ui/imports/auxiliary/unused-cross-crate-import-aux-2.rs created+1
......@@ -0,0 +1 @@
1pub fn baz() {}
tests/ui/imports/auxiliary/unused-extern-crate-aux.rs created+16
......@@ -0,0 +1,16 @@
1#![deny(dead_code)]
2
3mod inner {
4 pub trait Trait {
5 fn f(&self) { f(); }
6 }
7
8 impl Trait for isize {}
9
10 fn f() {}
11}
12
13pub 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
8extern crate extern_crate_alias_impl_method_aux as bug_lib;
9
10use bug_lib::B;
11use bug_lib::make;
12
13pub 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
7extern crate extern_crate_indirect_fn_ptr_aux_2 as crate2;
8
9fn 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
7extern crate extern_crate_no_prefer_dynamic_aux_1;
8extern crate extern_crate_no_prefer_dynamic_aux_2;
9
10fn 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
6extern crate extern_transmute_aux as i;
7
8pub 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]
19pub 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
7extern crate typeid_cross_crate_aux;
8use typeid_cross_crate_aux::testtypes;
9
10use std::any::TypeId;
11
12pub 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
34pub 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
8extern crate unused_cross_crate_import_aux_1 as foo;
9extern crate unused_cross_crate_import_aux_2 as bar;
10
11mod test {
12 use bar::baz;
13}
14
15fn 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
6extern crate unused_extern_crate_aux as unused;
7
8pub fn main() {}
tests/ui/issues/auxiliary/issue-11224.rs deleted-16
......@@ -1,16 +0,0 @@
1#![deny(dead_code)]
2
3mod inner {
4 pub trait Trait {
5 fn f(&self) { f(); }
6 }
7
8 impl Trait for isize {}
9
10 fn f() {}
11}
12
13pub 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 @@
1pub struct Closed01<F>(pub F);
2
3pub trait Bar { fn new() -> Self; }
4
5impl<T: Bar> Bar for Closed01<T> {
6 fn new() -> Closed01<T> { Closed01(Bar::new()) }
7}
8impl Bar for f32 { fn new() -> f32 { 1.0 } }
9
10pub fn random<T: Bar>() -> T { Bar::new() }
tests/ui/issues/auxiliary/issue-12612-1.rs deleted-3
......@@ -1,3 +0,0 @@
1pub mod bar {
2 pub fn foo() {}
3}
tests/ui/issues/auxiliary/issue-12612-2.rs deleted-1
......@@ -1 +0,0 @@
1pub fn baz() {}
tests/ui/issues/auxiliary/issue-13507.rs deleted-87
......@@ -1,87 +0,0 @@
1pub 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 @@
1pub struct Foo {
2 pub foo: extern "C" fn()
3}
4
5extern "C" fn the_foo() {}
6
7pub const FOO: Foo = Foo {
8 foo: the_foo
9};
tests/ui/issues/auxiliary/issue-13620-2.rs deleted-3
......@@ -1,3 +0,0 @@
1extern crate issue_13620_1 as crate1;
2
3pub 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
5pub fn foo() {}
tests/ui/issues/auxiliary/issue-14344-2.rs deleted-3
......@@ -1,3 +0,0 @@
1extern crate issue_14344_1;
2
3pub fn bar() {}
tests/ui/issues/auxiliary/issue-14422.rs deleted-25
......@@ -1,25 +0,0 @@
1#![crate_type="lib"]
2#![deny(warnings)]
3
4pub use src::aliases::B;
5pub use src::hidden_core::make;
6
7mod 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
3extern "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
5extern crate issue_11224 as unused;
6
7pub fn main() {}
tests/ui/issues/issue-11508.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ run-pass
2//@ aux-build:issue-11508.rs
3
4extern crate issue_11508 as rand;
5
6use rand::{Closed01, random};
7
8fn 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)]
5enum Noun
6{
7 Atom(isize),
8 Cell(Box<Noun>, Box<Noun>)
9}
10
11fn 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
19pub 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
6mod foo {
7 trait Bar { fn bar(&self) { } }
8 impl Bar for i8 { fn bar(&self) { } }
9}
10
11fn 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
8use std::marker;
9
10trait X<T> {
11 fn dummy(&self) -> T { panic!() }
12}
13
14struct S<T> {f: Box<dyn X<T>+'static>,
15 g: Box<dyn X<T>+'static>}
16
17struct F;
18impl X<isize> for F {
19}
20
21fn 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
7extern crate issue_12612_1 as foo;
8extern crate issue_12612_2 as bar;
9
10mod test {
11 use bar::baz;
12}
13
14fn 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
5extern crate issue_13507;
6use issue_13507::testtypes;
7
8use std::any::TypeId;
9
10pub 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
32pub 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
6extern crate issue_13620_2 as crate2;
7
8fn 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
5extern crate issue_14344_1;
6extern crate issue_14344_2;
7
8fn 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
7extern crate issue_14422 as bug_lib;
8
9use bug_lib::B;
10use bug_lib::make;
11
12pub 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
5extern crate issue_15562 as i;
6
7pub 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]
18pub 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
8mod foo {
9 trait Bar {
10 fn bar(&self) {}
11 }
12 impl Bar for i8 {
13 fn bar(&self) {}
14 }
15}
16
17fn 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
8888LL | type W: Ord where Self: Eq;
8989 | ^^^^^^^^ the trait `Eq` is not implemented for `X`
9090 |
91 = help: see issue #48214
9291help: consider annotating `X` with `#[derive(Eq)]`
9392 |
9493LL + #[derive(Eq)]
......@@ -105,7 +104,6 @@ error[E0277]: the trait bound `X: Eq` is not satisfied
105104LL | type W where Self: Eq;
106105 | ^^^^^^^^ the trait `Eq` is not implemented for `X`
107106 |
108 = help: see issue #48214
109107help: consider annotating `X` with `#[derive(Eq)]`
110108 |
111109LL + #[derive(Eq)]
tests/ui/parser/issues/issue-102806.rs-1
......@@ -16,7 +16,6 @@ fn pz(v: V3) {
1616
1717 let _ = V3 { z: 0.0, ... };
1818 //~^ ERROR expected identifier
19 //~| ERROR missing fields `x` and `y` in initializer of `V3`
2019
2120 let V3 { z: val, ... } = v;
2221 //~^ ERROR expected field pattern
tests/ui/parser/issues/issue-102806.stderr+2-9
......@@ -31,7 +31,7 @@ LL | let _ = V3 { z: 0.0, ... };
3131 | while parsing this struct
3232
3333error: expected field pattern, found `...`
34 --> $DIR/issue-102806.rs:21:22
34 --> $DIR/issue-102806.rs:20:22
3535 |
3636LL | let V3 { z: val, ... } = v;
3737 | ^^^
......@@ -42,12 +42,5 @@ LL - let V3 { z: val, ... } = v;
4242LL + let V3 { z: val, .. } = v;
4343 |
4444
45error[E0063]: missing fields `x` and `y` in initializer of `V3`
46 --> $DIR/issue-102806.rs:17:13
47 |
48LL | let _ = V3 { z: 0.0, ... };
49 | ^^ missing `x` and `y`
50
51error: aborting due to 5 previous errors
45error: aborting due to 4 previous errors
5246
53For more information about this error, try `rustc --explain E0063`.
tests/ui/parser/issues/issue-52496.rs-1
......@@ -7,6 +7,5 @@ fn main() {
77 let bar = 1.5f32;
88 let _ = Foo { bar.into(), bat: -1, . };
99 //~^ ERROR expected one of
10 //~| ERROR missing fields `bar` and `baz` in initializer of `Foo`
1110 //~| ERROR expected identifier, found `.`
1211}
tests/ui/parser/issues/issue-52496.stderr+1-7
......@@ -37,12 +37,6 @@ error[E0063]: missing field `bat` in initializer of `Foo`
3737LL | let _ = Foo { bar: .5, baz: 42 };
3838 | ^^^ missing `bat`
3939
40error[E0063]: missing fields `bar` and `baz` in initializer of `Foo`
41 --> $DIR/issue-52496.rs:8:13
42 |
43LL | let _ = Foo { bar.into(), bat: -1, . };
44 | ^^^ missing `bar` and `baz`
45
46error: aborting due to 5 previous errors
40error: aborting due to 4 previous errors
4741
4842For 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() {
77 let a = S { foo: (), bar: () };
88 let b = S { foo: (), with a };
99 //~^ ERROR expected one of `,`, `:`, or `}`, found `a`
10 //~| ERROR missing field `bar` in initializer of `S`
1110}
tests/ui/parser/removed-syntax/removed-syntax-with-2.stderr+1-8
......@@ -7,12 +7,5 @@ LL | let b = S { foo: (), with a };
77 | | while parsing this struct field
88 | while parsing this struct
99
10error[E0063]: missing field `bar` in initializer of `S`
11 --> $DIR/removed-syntax-with-2.rs:8:13
12 |
13LL | let b = S { foo: (), with a };
14 | ^ missing `bar`
15
16error: aborting due to 2 previous errors
10error: aborting due to 1 previous error
1711
18For more information about this error, try `rustc --explain E0063`.
tests/ui/parser/struct-field-numeric-shorthand.rs-1
......@@ -5,5 +5,4 @@ fn main() {
55 //~^ ERROR expected identifier, found `0`
66 //~| ERROR expected identifier, found `1`
77 //~| ERROR expected identifier, found `2`
8 //~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb`
98}
tests/ui/parser/struct-field-numeric-shorthand.stderr+1-8
......@@ -22,12 +22,5 @@ LL | let _ = Rgb { 0, 1, 2 };
2222 | |
2323 | while parsing this struct
2424
25error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb`
26 --> $DIR/struct-field-numeric-shorthand.rs:4:13
27 |
28LL | let _ = Rgb { 0, 1, 2 };
29 | ^^^ missing `0`, `1` and `2`
30
31error: aborting due to 4 previous errors
25error: aborting due to 3 previous errors
3226
33For 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 @@
1pub struct Closed01<F>(pub F);
2
3pub trait Bar { fn new() -> Self; }
4
5impl<T: Bar> Bar for Closed01<T> {
6 fn new() -> Closed01<T> { Closed01(Bar::new()) }
7}
8impl Bar for f32 { fn new() -> f32 { 1.0 } }
9
10pub 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)]
7enum Noun {
8 Atom(isize),
9 Cell(Box<Noun>, Box<Noun>),
10}
11
12fn 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
19pub 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
6extern crate tuple_struct_cross_crate_aux as rand;
7
8use rand::{Closed01, random};
9
10fn 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
7struct Foo { a: isize, b: isize }
8
9fn make_a() -> isize { 1234 }
10
11fn expr_wrong_separator() {
12 let f = Foo { a: make_a(); b: 2 }; //~ ERROR found `;`
13}
14
15fn expr_missing_separator() {
16 let f = Foo { a: make_a() b: 2 }; //~ ERROR found `b`
17}
18
19fn expr_rest_trailing_comma() {
20 let f = Foo { a: make_a(), ..todo!(), }; //~ ERROR cannot use a comma
21}
22
23fn expr_missing_field_name() {
24 let f = Foo { make_a(), b: 2, }; //~ ERROR found `(`
25}
26
27fn pat_wrong_separator(Foo { a; b }: Foo) { //~ ERROR expected `,`
28 let _ = (a, b);
29}
30
31fn pat_missing_separator(Foo { a b }: Foo) { //~ ERROR expected `,`
32 let _ = (a, b);
33}
34
35fn pat_rest_trailing_comma(Foo { a, .., }: Foo) { //~ ERROR expected `}`, found `,`
36}
37
38fn main() {}
tests/ui/structs/syntax-error-not-missing-field.stderr created+74
......@@ -0,0 +1,74 @@
1error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
2 --> $DIR/syntax-error-not-missing-field.rs:12:30
3 |
4LL | 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
11error: expected one of `,`, `.`, `?`, `}`, or an operator, found `b`
12 --> $DIR/syntax-error-not-missing-field.rs:16:31
13 |
14LL | 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
20error: cannot use a comma after the base struct
21 --> $DIR/syntax-error-not-missing-field.rs:20:32
22 |
23LL | let f = Foo { a: make_a(), ..todo!(), };
24 | ^^^^^^^^^
25 |
26 = note: the base struct must always be the last field
27help: remove this comma
28 |
29LL - let f = Foo { a: make_a(), ..todo!(), };
30LL + let f = Foo { a: make_a(), ..todo!() };
31 |
32
33error: expected one of `,`, `:`, or `}`, found `(`
34 --> $DIR/syntax-error-not-missing-field.rs:24:25
35 |
36LL | 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 |
42help: try naming a field
43 |
44LL | let f = Foo { make_a: make_a(), b: 2, };
45 | +++++++
46
47error: expected `,`
48 --> $DIR/syntax-error-not-missing-field.rs:27:31
49 |
50LL | fn pat_wrong_separator(Foo { a; b }: Foo) {
51 | --- ^
52 | |
53 | while parsing the fields for this pattern
54
55error: expected `,`
56 --> $DIR/syntax-error-not-missing-field.rs:31:34
57 |
58LL | fn pat_missing_separator(Foo { a b }: Foo) {
59 | --- ^
60 | |
61 | while parsing the fields for this pattern
62
63error: expected `}`, found `,`
64 --> $DIR/syntax-error-not-missing-field.rs:35:39
65 |
66LL | 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
73error: aborting due to 7 previous errors
74
tests/ui/suggestions/struct-initializer-comma.fixed-1
......@@ -7,7 +7,6 @@ pub struct Foo {
77
88fn main() {
99 let _ = Foo {
10 //~^ ERROR missing field
1110 first: true,
1211 second: 25
1312 //~^ ERROR expected one of
tests/ui/suggestions/struct-initializer-comma.rs-1
......@@ -7,7 +7,6 @@ pub struct Foo {
77
88fn main() {
99 let _ = Foo {
10 //~^ ERROR missing field
1110 first: true
1211 second: 25
1312 //~^ ERROR expected one of
tests/ui/suggestions/struct-initializer-comma.stderr+2-10
......@@ -1,9 +1,8 @@
11error: expected one of `,`, `.`, `?`, `}`, or an operator, found `second`
2 --> $DIR/struct-initializer-comma.rs:12:9
2 --> $DIR/struct-initializer-comma.rs:11:9
33 |
44LL | let _ = Foo {
55 | --- while parsing this struct
6LL |
76LL | first: true
87 | -
98 | |
......@@ -12,12 +11,5 @@ LL | first: true
1211LL | second: 25
1312 | ^^^^^^ unexpected token
1413
15error[E0063]: missing field `second` in initializer of `Foo`
16 --> $DIR/struct-initializer-comma.rs:9:13
17 |
18LL | let _ = Foo {
19 | ^^^ missing `second`
20
21error: aborting due to 2 previous errors
14error: aborting due to 1 previous error
2215
23For 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
7777 |
7878LL | trait Sub: Super<Assoc = u16> {}
7979 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
80 = help: see issue #48214
8180help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
8281 |
8382LL + #![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
9use std::marker;
10
11trait X<T> {
12 fn dummy(&self) -> T {
13 panic!()
14 }
15}
16
17struct S<T> {
18 f: Box<dyn X<T> + 'static>,
19 g: Box<dyn X<T> + 'static>,
20}
21
22struct F;
23impl X<isize> for F {}
24
25fn main() {
26 S { f: Box::new(F), g: Box::new(F) };
27}