authorbors <bors@rust-lang.org> 2026-04-13 18:32:47 UTC
committerbors <bors@rust-lang.org> 2026-04-13 18:32:47 UTC
log17584a181979f04f2aaad867332c22db1caa511a
tree740d16a404e0af53ad474216d9e824ac8e54472c
parenta72e2a71d8fbcbc46cdd18784e2ab2c32cbd9c93
parent9f11d53cd30e38a02e85c0f046a3f76b2ef6fe96

Auto merge of #155253 - JonathanBrouwer:rollup-lERdTAB, r=JonathanBrouwer

Rollup of 19 pull requests Successful merges: - rust-lang/rust#155162 (relnotes for 1.95) - rust-lang/rust#140763 (Change codegen of LLVM intrinsics to be name-based, and add llvm linkage support for `bf16(xN)` and `i1xN`) - rust-lang/rust#153604 (Fix thread::available_parallelism on WASI targets with threads) - rust-lang/rust#154193 (Implement EII for statics) - rust-lang/rust#154389 (Add more robust handling of nested query cycles) - rust-lang/rust#154435 (resolve: Some import resolution cleanups) - rust-lang/rust#155236 (Normalize individual predicate of `InstantiatedPredicates` inside `predicates_for_generics`) - rust-lang/rust#155243 (cg_ssa: transmute between scalable vectors) - rust-lang/rust#153941 (tests/debuginfo/basic-stepping.rs: Explain why all lines are not steppable) - rust-lang/rust#154587 (Add --verbose-run-make-subprocess-output flag to suppress verbose run-make output for passing tests) - rust-lang/rust#154624 (Make `DerefPure` dyn-incompatible) - rust-lang/rust#154929 (Add `const Default` impls for `LazyCell` and `LazyLock`) - rust-lang/rust#154944 (Small refactor of `arena_cache` query values) - rust-lang/rust#155055 (UI automation) - rust-lang/rust#155062 (Move tests from `tests/ui/issues/` to appropriate directories) - rust-lang/rust#155131 (Stabilize feature `uint_bit_width`) - rust-lang/rust#155147 (Stabilize feature `int_lowest_highest_one`) - rust-lang/rust#155174 (Improve emission of `UnknownDiagnosticAttribute` lint) - rust-lang/rust#155194 (Fix manpage version replacement and use verbose version)

188 files changed, 2658 insertions(+), 782 deletions(-)

RELEASES.md+131
......@@ -1,3 +1,134 @@
1Version 1.95 (2026-04-16)
2==========================
3
4<a id="1.95-Language"></a>
5
6Language
7--------
8- [Stabilize `if let` guards on match arms](https://github.com/rust-lang/rust/pull/141295)
9- [`irrefutable_let_patterns` lint no longer lints on let chains](https://github.com/rust-lang/rust/pull/146832)
10- [Support importing path-segment keywords with renaming](https://github.com/rust-lang/rust/pull/146972)
11- [Stabilize inline assembly for PowerPC and PowerPC64](https://github.com/rust-lang/rust/pull/147996)
12- [const-eval: be more consistent in the behavior of padding during typed copies](https://github.com/rust-lang/rust/pull/148967)
13- [Const blocks are no longer evaluated to determine if expressions involving fallible operations can implicitly be constant-promoted.](https://github.com/rust-lang/rust/pull/150557). Expressions whose ability to implicitly be promoted would depend on the result of a const block are no longer implicitly promoted.
14- [Make operational semantics of pattern matching independent of crate and module](https://github.com/rust-lang/rust/pull/150681)
15
16
17<a id="1.95-Compiler"></a>
18
19Compiler
20--------
21- [Stabilize `--remap-path-scope` for controlling the scoping of how paths get remapped in the resulting binary](https://github.com/rust-lang/rust/pull/147611)
22
23
24<a id="1.95-Platform-Support"></a>
25
26Platform Support
27----------------
28- [Promote `powerpc64-unknown-linux-musl` to Tier 2 with host tools](https://github.com/rust-lang/rust/pull/149962)
29- [Promote `aarch64-apple-tvos` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
30- [Promote `aarch64-apple-tvos-sim` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
31- [Promote `aarch64-apple-watchos` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
32- [Promote `aarch64-apple-watchos-sim` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
33- [Promote `aarch64-apple-visionos` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
34- [Promote `aarch64-apple-visionos-sim` to Tier 2](https://github.com/rust-lang/rust/pull/152021)
35
36
37Refer to Rust's [platform support page][platform-support-doc]
38for more information on Rust's tiered platform support.
39
40[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
41
42<a id="1.95-Libraries"></a>
43
44Libraries
45---------
46- [`thread::scope`: document how join interacts with TLS destructors](https://github.com/rust-lang/rust/pull/149482)
47- [Speed up `str::contains` on aarch64 targets with `neon` target feature enabled by default](https://github.com/rust-lang/rust/pull/152176)
48
49
50<a id="1.95-Stabilized-APIs"></a>
51
52Stabilized APIs
53---------------
54
55- [`MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3CMaybeUninit%3C%5BT;+N%5D%3E%3E-for-%5BMaybeUninit%3CT%3E;+N%5D)
56- [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E)
57- [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E)
58- [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/beta/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E)
59- [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E)
60- [`[MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E)
61- [`Cell<[T; N]>: AsRef<[Cell<T>; N]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E;+N%5D%3E-for-Cell%3C%5BT;+N%5D%3E)
62- [`Cell<[T; N]>: AsRef<[Cell<T>]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT;+N%5D%3E)
63- [`Cell<[T]>: AsRef<[Cell<T>]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT%5D%3E)
64- [`bool: TryFrom<{integer}>`](https://doc.rust-lang.org/stable/std/primitive.bool.html#impl-TryFrom%3Cu128%3E-for-bool)
65- [`AtomicPtr::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.update)
66- [`AtomicPtr::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.try_update)
67- [`AtomicBool::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.update)
68- [`AtomicBool::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.try_update)
69- [`AtomicIn::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.update)
70- [`AtomicIn::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.try_update)
71- [`AtomicUn::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.update)
72- [`AtomicUn::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.try_update)
73- [`cfg_select!`](https://doc.rust-lang.org/stable/std/macro.cfg_select.html)
74- [`mod core::range`](https://doc.rust-lang.org/stable/core/range/index.html)
75- [`core::range::RangeInclusive`](https://doc.rust-lang.org/stable/core/range/struct.RangeInclusive.html)
76- [`core::range::RangeInclusiveIter`](https://doc.rust-lang.org/stable/core/range/struct.RangeInclusiveIter.html)
77- [`core::hint::cold_path`](https://doc.rust-lang.org/stable/core/hint/fn.cold_path.html)
78- [`<*const T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked)
79- [`<*mut T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked-1)
80- [`<*mut T>::as_mut_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_unchecked)
81
82
83These previously stable APIs are now stable in const contexts:
84
85- [`fmt::from_fn`](https://doc.rust-lang.org/stable/std/fmt/fn.from_fn.html)
86- [`ControlFlow::is_break`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_break)
87- [`ControlFlow::is_continue`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_continue)
88
89
90<a id="1.95-Cargo"></a>
91
92Cargo
93-----
94- [docs(report): enhance man pages for `cargo report *`](https://github.com/rust-lang/cargo/pull/16430/)<a id="1.95-Rustdoc"></a>
95
96Rustdoc
97-----
98- [In search results, rank unstable items lower](https://github.com/rust-lang/rust/pull/149460)
99- [Add new "hide deprecated items" setting in rustdoc](https://github.com/rust-lang/rust/pull/151091)
100<a id="1.95-Compatibility-Notes"></a>
101
102Compatibility Notes
103-------------------
104- [Array coercions may now result in less inference constraints than before](https://github.com/rust-lang/rust/pull/140283)
105- Importing `$crate` without renaming, i.e. `use $crate::{self};`, is now no longer permitted due to stricter error checking for `self` imports.
106- [const-eval: be more consistent in the behavior of padding during typed copies.](https://github.com/rust-lang/rust/pull/148967)
107 In very rare cases, this may cause compilation errors due to bytes from parts of a pointer ending up in the padding bytes of a `const` or `static`.
108- [A future-incompatibility warning lint `ambiguous_glob_imported_traits` is now reported when using an ambiguously glob imported trait](https://github.com/rust-lang/rust/pull/149058)
109- [Check lifetime bounds of types mentioning only type parameters](https://github.com/rust-lang/rust/pull/149389)
110- [Report more visibility-related ambiguous import errors](https://github.com/rust-lang/rust/pull/149596)
111- [Deprecate `Eq::assert_receiver_is_total_eq` and emit future compatibility warnings on manual impls](https://github.com/rust-lang/rust/pull/149978)
112- [powerpc64: Use the ELF ABI version set in target spec instead of guessing](https://github.com/rust-lang/rust/pull/150468) (fixes the ELF ABI used by the OpenBSD target)
113- Matching on a `#[non_exhaustive]` enum [now reads the discriminant, even if the enum has only one variant](https://github.com/rust-lang/rust/pull/150681). This can cause closures to capture values that they previously wouldn't.
114- `mut ref` and `mut ref mut` patterns, part of the unstable [Match Ergonomics 2024 RFC](https://github.com/rust-lang/rust/issues/123076), were accidentally allowed on stable within struct pattern field shorthand. These patterns are now correctly feature-gated as unstable in this position.
115- [Add future-compatibility warning for derive helper attributes which conflict with built-in attributes](https://github.com/rust-lang/rust/pull/151152)
116- [JSON target specs](https://doc.rust-lang.org/rustc/targets/custom.html) have been destabilized and now require `-Z unstable-options` to use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for the `build-std` project adding that support, JSON target specs are being proactively gated to ensure they remain unstable even if `build-std` is stabilized. Cargo now includes the `-Z json-target-spec` CLI flag to automatically pass `-Z unstable-options` to the compiler when needed. See [#150151](https://github.com/rust-lang/rust/pull/150151), [#151534](https://github.com/rust-lang/rust/pull/150151), and [rust-lang/cargo#16557](https://github.com/rust-lang/cargo/pull/16557).
117- [The arguments of `#[feature]` attributes on invalid targets are now checked](https://github.com/rust-lang/rust/issues/153764)
118
119
120<a id="1.95-Internal-Changes"></a>
121
122Internal Changes
123----------------
124
125These changes do not affect any public interfaces of Rust, but they represent
126significant improvements to the performance or internals of rustc and related
127tools.
128
129- [Update to LLVM 22](https://github.com/rust-lang/rust/pull/150722)
130
131
1132Version 1.94.1 (2026-03-26)
2133===========================
3134
compiler/rustc_ast/src/ast.rs+7
......@@ -3918,6 +3918,13 @@ pub struct StaticItem {
39183918 pub mutability: Mutability,
39193919 pub expr: Option<Box<Expr>>,
39203920 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3921
3922 /// This static is an implementation of an externally implementable item (EII).
3923 /// This means, there was an EII declared somewhere and this static is the
3924 /// implementation that should be used for the declaration.
3925 ///
3926 /// For statics, there may be at most one `EiiImpl`, but this is a `ThinVec` to make usages of this field nicer.
3927 pub eii_impls: ThinVec<EiiImpl>,
39213928}
39223929
39233930#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
compiler/rustc_ast_lowering/src/item.rs+10-3
......@@ -213,8 +213,14 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
213213 i: &ItemKind,
214214 ) -> Vec<hir::Attribute> {
215215 match i {
216 ItemKind::Fn(box Fn { eii_impls, .. }) if eii_impls.is_empty() => Vec::new(),
217 ItemKind::Fn(box Fn { eii_impls, .. }) => {
216 ItemKind::Fn(box Fn { eii_impls, .. })
217 | ItemKind::Static(box StaticItem { eii_impls, .. })
218 if eii_impls.is_empty() =>
219 {
220 Vec::new()
221 }
222 ItemKind::Fn(box Fn { eii_impls, .. })
223 | ItemKind::Static(box StaticItem { eii_impls, .. }) => {
218224 vec![hir::Attribute::Parsed(AttributeKind::EiiImpls(
219225 eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),
220226 ))]
......@@ -226,7 +232,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
226232
227233 ItemKind::ExternCrate(..)
228234 | ItemKind::Use(..)
229 | ItemKind::Static(..)
230235 | ItemKind::Const(..)
231236 | ItemKind::ConstBlock(..)
232237 | ItemKind::Mod(..)
......@@ -302,6 +307,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
302307 mutability: m,
303308 expr: e,
304309 define_opaque,
310 eii_impls: _,
305311 }) => {
306312 let ident = self.lower_ident(*ident);
307313 let ty = self
......@@ -826,6 +832,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
826832 expr: _,
827833 safety,
828834 define_opaque,
835 eii_impls: _,
829836 }) => {
830837 let ty = self
831838 .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
compiler/rustc_ast_pretty/src/pprust/state/item.rs+26-12
......@@ -43,6 +43,7 @@ impl<'a> State<'a> {
4343 expr,
4444 safety,
4545 define_opaque,
46 eii_impls,
4647 }) => self.print_item_const(
4748 *ident,
4849 Some(*mutability),
......@@ -53,6 +54,7 @@ impl<'a> State<'a> {
5354 *safety,
5455 ast::Defaultness::Implicit,
5556 define_opaque.as_deref(),
57 eii_impls,
5658 ),
5759 ast::ForeignItemKind::TyAlias(box ast::TyAlias {
5860 defaultness,
......@@ -93,8 +95,12 @@ impl<'a> State<'a> {
9395 safety: ast::Safety,
9496 defaultness: ast::Defaultness,
9597 define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
98 eii_impls: &[EiiImpl],
9699 ) {
97100 self.print_define_opaques(define_opaque);
101 for eii_impl in eii_impls {
102 self.print_eii_impl(eii_impl);
103 }
98104 let (cb, ib) = self.head("");
99105 self.print_visibility(vis);
100106 self.print_safety(safety);
......@@ -191,6 +197,7 @@ impl<'a> State<'a> {
191197 mutability: mutbl,
192198 expr: body,
193199 define_opaque,
200 eii_impls,
194201 }) => {
195202 self.print_safety(*safety);
196203 self.print_item_const(
......@@ -203,6 +210,7 @@ impl<'a> State<'a> {
203210 ast::Safety::Default,
204211 ast::Defaultness::Implicit,
205212 define_opaque.as_deref(),
213 eii_impls,
206214 );
207215 }
208216 ast::ItemKind::ConstBlock(ast::ConstBlockItem { id: _, span: _, block }) => {
......@@ -234,6 +242,7 @@ impl<'a> State<'a> {
234242 ast::Safety::Default,
235243 *defaultness,
236244 define_opaque.as_deref(),
245 &[],
237246 );
238247 }
239248 ast::ItemKind::Fn(func) => {
......@@ -602,6 +611,7 @@ impl<'a> State<'a> {
602611 ast::Safety::Default,
603612 *defaultness,
604613 define_opaque.as_deref(),
614 &[],
605615 );
606616 }
607617 ast::AssocItemKind::Type(box ast::TyAlias {
......@@ -703,18 +713,8 @@ impl<'a> State<'a> {
703713
704714 self.print_define_opaques(define_opaque.as_deref());
705715
706 for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls {
707 self.word("#[");
708 if let Safety::Unsafe(..) = impl_safety {
709 self.word("unsafe");
710 self.popen();
711 }
712 self.print_path(eii_macro_path, false, 0);
713 if let Safety::Unsafe(..) = impl_safety {
714 self.pclose();
715 }
716 self.word("]");
717 self.hardbreak();
716 for eii_impl in eii_impls {
717 self.print_eii_impl(eii_impl);
718718 }
719719
720720 let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
......@@ -741,6 +741,20 @@ impl<'a> State<'a> {
741741 }
742742 }
743743
744 fn print_eii_impl(&mut self, eii: &ast::EiiImpl) {
745 self.word("#[");
746 if let Safety::Unsafe(..) = eii.impl_safety {
747 self.word("unsafe");
748 self.popen();
749 }
750 self.print_path(&eii.eii_macro_path, false, 0);
751 if let Safety::Unsafe(..) = eii.impl_safety {
752 self.pclose();
753 }
754 self.word("]");
755 self.hardbreak();
756 }
757
744758 fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
745759 if let Some(define_opaque) = define_opaque {
746760 self.word("#[define_opaque(");
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+2-1
......@@ -709,7 +709,8 @@ pub(crate) struct RustcEiiForeignItemParser;
709709impl<S: Stage> NoArgsAttributeParser<S> for RustcEiiForeignItemParser {
710710 const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
711711 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
712 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
712 const ALLOWED_TARGETS: AllowedTargets =
713 AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
713714 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
714715}
715716
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs+1
......@@ -17,6 +17,7 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
1717 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
1818 |this, cx, args| {
1919 if !cx.features().diagnostic_on_const() {
20 // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2021 return;
2122 }
2223
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs+1
......@@ -24,6 +24,7 @@ impl OnMoveParser {
2424 mode: Mode,
2525 ) {
2626 if !cx.features().diagnostic_on_move() {
27 // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2728 return;
2829 }
2930
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs+1
......@@ -18,6 +18,7 @@ impl OnUnknownParser {
1818 mode: Mode,
1919 ) {
2020 if !cx.features().diagnostic_on_unknown() {
21 // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2122 return;
2223 }
2324 let span = cx.attr_span;
compiler/rustc_builtin_macros/src/eii.rs+119-59
......@@ -1,7 +1,8 @@
11use rustc_ast::token::{Delimiter, TokenKind};
22use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
33use rustc_ast::{
4 Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, StmtKind, Visibility, ast,
4 Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Mutability, Path, StmtKind,
5 Visibility, ast,
56};
67use rustc_ast_pretty::pprust::path_to_string;
78use rustc_expand::base::{Annotatable, ExtCtxt};
......@@ -10,8 +11,9 @@ use thin_vec::{ThinVec, thin_vec};
1011
1112use crate::errors::{
1213 EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe,
13 EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroExpectedFunction,
14 EiiSharedMacroInStatementPosition,
14 EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroInStatementPosition,
15 EiiSharedMacroTarget, EiiStaticArgumentRequired, EiiStaticDefault,
16 EiiStaticMultipleImplementations, EiiStaticMutable,
1517};
1618
1719/// ```rust
......@@ -73,44 +75,72 @@ fn eii_(
7375 });
7476 return vec![orig_item];
7577 } else {
76 ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
78 ecx.dcx().emit_err(EiiSharedMacroTarget {
7779 span: eii_attr_span,
7880 name: path_to_string(&meta_item.path),
7981 });
8082 return vec![orig_item];
8183 };
8284
83 let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } =
84 item.as_ref()
85 else {
86 ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
87 span: eii_attr_span,
88 name: path_to_string(&meta_item.path),
89 });
90 return vec![Annotatable::Item(item)];
85 let ast::Item { attrs, id: _, span: _, vis, kind, tokens: _ } = item.as_ref();
86 let (item_span, foreign_item_name) = match kind {
87 ItemKind::Fn(func) => (func.sig.span, func.ident),
88 ItemKind::Static(stat) => {
89 // Statics with a default are not supported yet
90 if let Some(stat_body) = &stat.expr {
91 ecx.dcx().emit_err(EiiStaticDefault {
92 span: stat_body.span,
93 name: path_to_string(&meta_item.path),
94 });
95 return vec![];
96 }
97 // Statics must have an explicit name for the eii
98 if meta_item.is_word() {
99 ecx.dcx().emit_err(EiiStaticArgumentRequired {
100 span: eii_attr_span,
101 name: path_to_string(&meta_item.path),
102 });
103 return vec![];
104 }
105
106 // Mut statics are currently not supported
107 if stat.mutability == Mutability::Mut {
108 ecx.dcx().emit_err(EiiStaticMutable {
109 span: eii_attr_span,
110 name: path_to_string(&meta_item.path),
111 });
112 }
113
114 (item.span, stat.ident)
115 }
116 _ => {
117 ecx.dcx().emit_err(EiiSharedMacroTarget {
118 span: eii_attr_span,
119 name: path_to_string(&meta_item.path),
120 });
121 return vec![Annotatable::Item(item)];
122 }
91123 };
124
92125 // only clone what we need
93126 let attrs = attrs.clone();
94 let func = (**func).clone();
95127 let vis = vis.clone();
96128
97129 let attrs_from_decl =
98130 filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);
99131
100 let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else {
132 let Ok(macro_name) = name_for_impl_macro(ecx, foreign_item_name, &meta_item) else {
101133 // we don't need to wrap in Annotatable::Stmt conditionally since
102134 // EII can't be used on items in statement position
103135 return vec![Annotatable::Item(item)];
104136 };
105137
106 // span of the declaring item without attributes
107 let item_span = func.sig.span;
108 let foreign_item_name = func.ident;
109
110138 let mut module_items = Vec::new();
111139
112 if func.body.is_some() {
113 module_items.push(generate_default_impl(
140 if let ItemKind::Fn(func) = kind
141 && func.body.is_some()
142 {
143 module_items.push(generate_default_func_impl(
114144 ecx,
115145 &func,
116146 impl_unsafe,
......@@ -125,7 +155,7 @@ fn eii_(
125155 ecx,
126156 eii_attr_span,
127157 item_span,
128 func,
158 kind,
129159 vis,
130160 &attrs_from_decl,
131161 ));
......@@ -148,11 +178,11 @@ fn eii_(
148178/// declaration of the EII.
149179fn name_for_impl_macro(
150180 ecx: &mut ExtCtxt<'_>,
151 func: &ast::Fn,
181 item_ident: Ident,
152182 meta_item: &MetaItem,
153183) -> Result<Ident, ErrorGuaranteed> {
154184 if meta_item.is_word() {
155 Ok(func.ident)
185 Ok(item_ident)
156186 } else if let Some([first]) = meta_item.meta_item_list()
157187 && let Some(m) = first.meta_item()
158188 && m.path.segments.len() == 1
......@@ -190,7 +220,7 @@ fn filter_attrs_for_multiple_eii_attr(
190220 .collect()
191221}
192222
193fn generate_default_impl(
223fn generate_default_func_impl(
194224 ecx: &mut ExtCtxt<'_>,
195225 func: &ast::Fn,
196226 impl_unsafe: bool,
......@@ -257,7 +287,7 @@ fn generate_foreign_item(
257287 ecx: &mut ExtCtxt<'_>,
258288 eii_attr_span: Span,
259289 item_span: Span,
260 mut func: ast::Fn,
290 item_kind: &ItemKind,
261291 vis: Visibility,
262292 attrs_from_decl: &[Attribute],
263293) -> Box<ast::Item> {
......@@ -268,30 +298,21 @@ fn generate_foreign_item(
268298 // This attribute makes sure that we later know that this foreign item's symbol should not be.
269299 foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_foreign_item, eii_attr_span));
270300
271 let abi = match func.sig.header.ext {
272 // extern "X" fn => extern "X" {}
273 ast::Extern::Explicit(lit, _) => Some(lit),
274 // extern fn => extern {}
275 ast::Extern::Implicit(_) => None,
276 // fn => extern "Rust" {}
277 ast::Extern::None => Some(ast::StrLit {
278 symbol: sym::Rust,
279 suffix: None,
280 symbol_unescaped: sym::Rust,
281 style: ast::StrStyle::Cooked,
282 span: eii_attr_span,
283 }),
301 // We set the abi to the default "rust" abi, which can be overridden by `generate_foreign_func`,
302 // if a specific abi was specified on the EII function
303 let mut abi = Some(ast::StrLit {
304 symbol: sym::Rust,
305 suffix: None,
306 symbol_unescaped: sym::Rust,
307 style: ast::StrStyle::Cooked,
308 span: eii_attr_span,
309 });
310 let foreign_kind = match item_kind {
311 ItemKind::Fn(func) => generate_foreign_func(func.clone(), &mut abi),
312 ItemKind::Static(stat) => generate_foreign_static(stat.clone()),
313 _ => unreachable!("Target was checked earlier"),
284314 };
285315
286 // ABI has been moved to the extern {} block, so we remove it from the fn item.
287 func.sig.header.ext = ast::Extern::None;
288 func.body = None;
289
290 // And mark safe functions explicitly as `safe fn`.
291 if func.sig.header.safety == ast::Safety::Default {
292 func.sig.header.safety = ast::Safety::Safe(func.sig.span);
293 }
294
295316 ecx.item(
296317 eii_attr_span,
297318 ThinVec::new(),
......@@ -304,13 +325,46 @@ fn generate_foreign_item(
304325 id: ast::DUMMY_NODE_ID,
305326 span: item_span,
306327 vis,
307 kind: ast::ForeignItemKind::Fn(Box::new(func.clone())),
328 kind: foreign_kind,
308329 tokens: None,
309330 })]),
310331 }),
311332 )
312333}
313334
335fn generate_foreign_func(
336 mut func: Box<ast::Fn>,
337 abi: &mut Option<ast::StrLit>,
338) -> ast::ForeignItemKind {
339 match func.sig.header.ext {
340 // extern "X" fn => extern "X" {}
341 ast::Extern::Explicit(lit, _) => *abi = Some(lit),
342 // extern fn => extern {}
343 ast::Extern::Implicit(_) => *abi = None,
344 // no abi was specified, so we keep the default
345 ast::Extern::None => {}
346 };
347
348 // ABI has been moved to the extern {} block, so we remove it from the fn item.
349 func.sig.header.ext = ast::Extern::None;
350 func.body = None;
351
352 // And mark safe functions explicitly as `safe fn`.
353 if func.sig.header.safety == ast::Safety::Default {
354 func.sig.header.safety = ast::Safety::Safe(func.sig.span);
355 }
356
357 ast::ForeignItemKind::Fn(func)
358}
359
360fn generate_foreign_static(mut stat: Box<ast::StaticItem>) -> ast::ForeignItemKind {
361 if stat.safety == ast::Safety::Default {
362 stat.safety = ast::Safety::Safe(stat.ident.span);
363 }
364
365 ast::ForeignItemKind::Static(stat)
366}
367
314368/// Generate a stub macro (a bit like in core) that will roughly look like:
315369///
316370/// ```rust, ignore, example
......@@ -453,19 +507,25 @@ pub(crate) fn eii_shared_macro(
453507 {
454508 item
455509 } else {
456 ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
457 span,
458 name: path_to_string(&meta_item.path),
459 });
510 ecx.dcx().emit_err(EiiSharedMacroTarget { span, name: path_to_string(&meta_item.path) });
460511 return vec![item];
461512 };
462513
463 let ItemKind::Fn(f) = &mut i.kind else {
464 ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
465 span,
466 name: path_to_string(&meta_item.path),
467 });
468 return vec![item];
514 let eii_impls = match &mut i.kind {
515 ItemKind::Fn(func) => &mut func.eii_impls,
516 ItemKind::Static(stat) => {
517 if !stat.eii_impls.is_empty() {
518 // Reject multiple implementations on one static item
519 // because it might be unintuitive for libraries defining statics the defined statics may alias
520 ecx.dcx().emit_err(EiiStaticMultipleImplementations { span });
521 }
522 &mut stat.eii_impls
523 }
524 _ => {
525 ecx.dcx()
526 .emit_err(EiiSharedMacroTarget { span, name: path_to_string(&meta_item.path) });
527 return vec![item];
528 }
469529 };
470530
471531 let is_default = if meta_item.is_word() {
......@@ -483,7 +543,7 @@ pub(crate) fn eii_shared_macro(
483543 return vec![item];
484544 };
485545
486 f.eii_impls.push(EiiImpl {
546 eii_impls.push(EiiImpl {
487547 node_id: DUMMY_NODE_ID,
488548 inner_span: meta_item.path.span,
489549 eii_macro_path: meta_item.path.clone(),
compiler/rustc_builtin_macros/src/errors.rs+36-2
......@@ -1117,8 +1117,42 @@ pub(crate) struct EiiExternTargetExpectedUnsafe {
11171117}
11181118
11191119#[derive(Diagnostic)]
1120#[diag("`#[{$name}]` is only valid on functions")]
1121pub(crate) struct EiiSharedMacroExpectedFunction {
1120#[diag("`#[{$name}]` is only valid on functions and statics")]
1121pub(crate) struct EiiSharedMacroTarget {
1122 #[primary_span]
1123 pub span: Span,
1124 pub name: String,
1125}
1126
1127#[derive(Diagnostic)]
1128#[diag("static cannot implement multiple EIIs")]
1129#[note(
1130 "this is not allowed because multiple externally implementable statics that alias may be unintuitive"
1131)]
1132pub(crate) struct EiiStaticMultipleImplementations {
1133 #[primary_span]
1134 pub span: Span,
1135}
1136
1137#[derive(Diagnostic)]
1138#[diag("`#[{$name}]` cannot be used on statics with a value")]
1139pub(crate) struct EiiStaticDefault {
1140 #[primary_span]
1141 pub span: Span,
1142 pub name: String,
1143}
1144
1145#[derive(Diagnostic)]
1146#[diag("`#[{$name}]` requires the name as an explicit argument when used on a static")]
1147pub(crate) struct EiiStaticArgumentRequired {
1148 #[primary_span]
1149 pub span: Span,
1150 pub name: String,
1151}
1152
1153#[derive(Diagnostic)]
1154#[diag("`#[{$name}]` cannot be used on mutable statics")]
1155pub(crate) struct EiiStaticMutable {
11221156 #[primary_span]
11231157 pub span: Span,
11241158 pub name: String,
compiler/rustc_codegen_llvm/src/errors.rs+29
......@@ -211,3 +211,32 @@ pub(crate) struct FixedX18InvalidArch<'a> {
211211 "enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes"
212212)]
213213pub(crate) struct PackedStackBackchainNeedsSoftfloat;
214
215#[derive(Diagnostic)]
216#[diag(
217 "intrinsic signature mismatch for `{$name}`: expected signature `{$llvm_fn_ty}`, found `{$rust_fn_ty}`"
218)]
219pub(crate) struct IntrinsicSignatureMismatch<'a> {
220 pub name: &'a str,
221 pub llvm_fn_ty: &'a str,
222 pub rust_fn_ty: &'a str,
223 #[primary_span]
224 pub span: Span,
225}
226
227#[derive(Diagnostic)]
228#[diag("unknown LLVM intrinsic `{$name}`")]
229pub(crate) struct UnknownIntrinsic<'a> {
230 pub name: &'a str,
231 #[primary_span]
232 pub span: Span,
233}
234
235#[derive(Diagnostic)]
236#[diag("intrinsic `{$name}` cannot be used with target arch `{$target_arch}`")]
237pub(crate) struct IntrinsicWrongArch<'a> {
238 pub name: &'a str,
239 pub target_arch: &'a str,
240 #[primary_span]
241 pub span: Span,
242}
compiler/rustc_codegen_llvm/src/intrinsic.rs+263-27
......@@ -1,6 +1,6 @@
11use std::cmp::Ordering;
22use std::ffi::c_uint;
3use std::{assert_matches, ptr};
3use std::{assert_matches, iter, ptr};
44
55use rustc_abi::{
66 Align, BackendRepr, ExternAbi, Float, HasDataLayout, NumScalableVectors, Primitive, Size,
......@@ -21,10 +21,11 @@ use rustc_middle::ty::offload_meta::OffloadMetadata;
2121use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv};
2222use rustc_middle::{bug, span_bug};
2323use rustc_session::config::CrateType;
24use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC;
2425use rustc_span::{Span, Symbol, sym};
2526use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
2627use rustc_target::callconv::PassMode;
27use rustc_target::spec::Os;
28use rustc_target::spec::{Arch, Os};
2829use tracing::debug;
2930
3031use crate::abi::FnAbiLlvmExt;
......@@ -36,7 +37,8 @@ use crate::builder::gpu_offload::{
3637use crate::context::CodegenCx;
3738use crate::declare::declare_raw_fn;
3839use crate::errors::{
39 AutoDiffWithoutEnable, AutoDiffWithoutLto, OffloadWithoutEnable, OffloadWithoutFatLTO,
40 AutoDiffWithoutEnable, AutoDiffWithoutLto, IntrinsicSignatureMismatch, IntrinsicWrongArch,
41 OffloadWithoutEnable, OffloadWithoutFatLTO, UnknownIntrinsic,
4042};
4143use crate::llvm::{self, Type, Value};
4244use crate::type_of::LayoutLlvmExt;
......@@ -797,7 +799,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
797799 &mut self,
798800 instance: ty::Instance<'tcx>,
799801 args: &[OperandRef<'tcx, Self::Value>],
800 is_cleanup: bool,
802 _is_cleanup: bool,
801803 ) -> Self::Value {
802804 let tcx = self.tcx();
803805
......@@ -826,42 +828,29 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
826828 llargument_tys.push(arg_layout.immediate_llvm_type(self));
827829 }
828830
829 let fn_ty = self.type_func(&llargument_tys, llreturn_ty);
830
831831 let fn_ptr = if let Some(&llfn) = self.intrinsic_instances.borrow().get(&instance) {
832832 llfn
833833 } else {
834834 let sym = tcx.symbol_name(instance).name;
835835
836 // FIXME use get_intrinsic
837836 let llfn = if let Some(llfn) = self.get_declared_value(sym) {
838837 llfn
839838 } else {
840 // Function addresses in Rust are never significant, allowing functions to
841 // be merged.
842 let llfn = declare_raw_fn(
843 self,
844 sym,
845 llvm::CCallConv,
846 llvm::UnnamedAddr::Global,
847 llvm::Visibility::Default,
848 fn_ty,
849 );
850
851 llfn
839 intrinsic_fn(self, sym, llreturn_ty, llargument_tys, instance)
852840 };
853841
854842 self.intrinsic_instances.borrow_mut().insert(instance, llfn);
855843
856844 llfn
857845 };
846 let fn_ty = self.get_type_of_global(fn_ptr);
858847
859848 let mut llargs = vec![];
860849
861850 for arg in args {
862851 match arg.val {
863852 OperandValue::ZeroSized => {}
864 OperandValue::Immediate(_) => llargs.push(arg.immediate()),
853 OperandValue::Immediate(a) => llargs.push(a),
865854 OperandValue::Pair(a, b) => {
866855 llargs.push(a);
867856 llargs.push(b);
......@@ -887,24 +876,38 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
887876 }
888877
889878 debug!("call intrinsic {:?} with args ({:?})", instance, llargs);
890 let args = self.check_call("call", fn_ty, fn_ptr, &llargs);
879
880 for (dest_ty, arg) in iter::zip(self.func_params_types(fn_ty), &mut llargs) {
881 let src_ty = self.val_ty(arg);
882 assert!(
883 can_autocast(self, src_ty, dest_ty),
884 "Cannot match `{dest_ty:?}` (expected) with {src_ty:?} (found) in `{fn_ptr:?}"
885 );
886
887 *arg = autocast(self, arg, src_ty, dest_ty);
888 }
889
891890 let llret = unsafe {
892891 llvm::LLVMBuildCallWithOperandBundles(
893892 self.llbuilder,
894893 fn_ty,
895894 fn_ptr,
896 args.as_ptr() as *const &llvm::Value,
897 args.len() as c_uint,
895 llargs.as_ptr(),
896 llargs.len() as c_uint,
898897 ptr::dangling(),
899898 0,
900899 c"".as_ptr(),
901900 )
902901 };
903 if is_cleanup {
904 self.apply_attrs_to_cleanup_callsite(llret);
905 }
906902
907 llret
903 let src_ty = self.val_ty(llret);
904 let dest_ty = llreturn_ty;
905 assert!(
906 can_autocast(self, dest_ty, src_ty),
907 "Cannot match `{src_ty:?}` (expected) with `{dest_ty:?}` (found) in `{fn_ptr:?}`"
908 );
909
910 autocast(self, llret, src_ty, dest_ty)
908911 }
909912
910913 fn abort(&mut self) {
......@@ -955,6 +958,239 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
955958 }
956959}
957960
961fn llvm_arch_for(rust_arch: &Arch) -> Option<&'static str> {
962 Some(match rust_arch {
963 Arch::AArch64 | Arch::Arm64EC => "aarch64",
964 Arch::AmdGpu => "amdgcn",
965 Arch::Arm => "arm",
966 Arch::Bpf => "bpf",
967 Arch::Hexagon => "hexagon",
968 Arch::LoongArch32 | Arch::LoongArch64 => "loongarch",
969 Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => "mips",
970 Arch::Nvptx64 => "nvvm",
971 Arch::PowerPC | Arch::PowerPC64 => "ppc",
972 Arch::RiscV32 | Arch::RiscV64 => "riscv",
973 Arch::S390x => "s390",
974 Arch::SpirV => "spv",
975 Arch::Wasm32 | Arch::Wasm64 => "wasm",
976 Arch::X86 | Arch::X86_64 => "x86",
977 _ => return None, // fallback for unknown archs
978 })
979}
980
981fn can_autocast<'ll>(cx: &CodegenCx<'ll, '_>, rust_ty: &'ll Type, llvm_ty: &'ll Type) -> bool {
982 if rust_ty == llvm_ty {
983 return true;
984 }
985
986 match cx.type_kind(llvm_ty) {
987 // Some LLVM intrinsics return **non-packed** structs, but they can't be mimicked from Rust
988 // due to auto field-alignment in non-packed structs (packed structs are represented in LLVM
989 // as, well, packed structs, so they won't match with those either)
990 TypeKind::Struct if cx.type_kind(rust_ty) == TypeKind::Struct => {
991 let rust_element_tys = cx.struct_element_types(rust_ty);
992 let llvm_element_tys = cx.struct_element_types(llvm_ty);
993
994 if rust_element_tys.len() != llvm_element_tys.len() {
995 return false;
996 }
997
998 iter::zip(rust_element_tys, llvm_element_tys).all(
999 |(rust_element_ty, llvm_element_ty)| {
1000 can_autocast(cx, rust_element_ty, llvm_element_ty)
1001 },
1002 )
1003 }
1004 TypeKind::Vector => {
1005 let llvm_element_ty = cx.element_type(llvm_ty);
1006 let element_count = cx.vector_length(llvm_ty) as u64;
1007
1008 if llvm_element_ty == cx.type_bf16() {
1009 rust_ty == cx.type_vector(cx.type_i16(), element_count)
1010 } else if llvm_element_ty == cx.type_i1() {
1011 let int_width = element_count.next_power_of_two().max(8);
1012 rust_ty == cx.type_ix(int_width)
1013 } else {
1014 false
1015 }
1016 }
1017 TypeKind::BFloat => rust_ty == cx.type_i16(),
1018 _ => false,
1019 }
1020}
1021
1022fn autocast<'ll>(
1023 bx: &mut Builder<'_, 'll, '_>,
1024 val: &'ll Value,
1025 src_ty: &'ll Type,
1026 dest_ty: &'ll Type,
1027) -> &'ll Value {
1028 if src_ty == dest_ty {
1029 return val;
1030 }
1031 match (bx.type_kind(src_ty), bx.type_kind(dest_ty)) {
1032 // re-pack structs
1033 (TypeKind::Struct, TypeKind::Struct) => {
1034 let mut ret = bx.const_poison(dest_ty);
1035 for (idx, (src_element_ty, dest_element_ty)) in
1036 iter::zip(bx.struct_element_types(src_ty), bx.struct_element_types(dest_ty))
1037 .enumerate()
1038 {
1039 let elt = bx.extract_value(val, idx as u64);
1040 let casted_elt = autocast(bx, elt, src_element_ty, dest_element_ty);
1041 ret = bx.insert_value(ret, casted_elt, idx as u64);
1042 }
1043 ret
1044 }
1045 // cast from the i1xN vector type to the primitive type
1046 (TypeKind::Vector, TypeKind::Integer) if bx.element_type(src_ty) == bx.type_i1() => {
1047 let vector_length = bx.vector_length(src_ty) as u64;
1048 let int_width = vector_length.next_power_of_two().max(8);
1049
1050 let val = if vector_length == int_width {
1051 val
1052 } else {
1053 // zero-extends vector
1054 let shuffle_indices = match vector_length {
1055 0 => unreachable!("zero length vectors are not allowed"),
1056 1 => vec![0, 1, 1, 1, 1, 1, 1, 1],
1057 2 => vec![0, 1, 2, 2, 2, 2, 2, 2],
1058 3 => vec![0, 1, 2, 3, 3, 3, 3, 3],
1059 4.. => (0..int_width as i32).collect(),
1060 };
1061 let shuffle_mask =
1062 shuffle_indices.into_iter().map(|i| bx.const_i32(i)).collect::<Vec<_>>();
1063 bx.shuffle_vector(val, bx.const_null(src_ty), bx.const_vector(&shuffle_mask))
1064 };
1065 bx.bitcast(val, dest_ty)
1066 }
1067 // cast from the primitive type to the i1xN vector type
1068 (TypeKind::Integer, TypeKind::Vector) if bx.element_type(dest_ty) == bx.type_i1() => {
1069 let vector_length = bx.vector_length(dest_ty) as u64;
1070 let int_width = vector_length.next_power_of_two().max(8);
1071
1072 let intermediate_ty = bx.type_vector(bx.type_i1(), int_width);
1073 let intermediate = bx.bitcast(val, intermediate_ty);
1074
1075 if vector_length == int_width {
1076 intermediate
1077 } else {
1078 let shuffle_mask: Vec<_> =
1079 (0..vector_length).map(|i| bx.const_i32(i as i32)).collect();
1080 bx.shuffle_vector(
1081 intermediate,
1082 bx.const_poison(intermediate_ty),
1083 bx.const_vector(&shuffle_mask),
1084 )
1085 }
1086 }
1087 _ => bx.bitcast(val, dest_ty), // for `bf16(xN)` <-> `u16(xN)`
1088 }
1089}
1090
1091fn intrinsic_fn<'ll, 'tcx>(
1092 bx: &Builder<'_, 'll, 'tcx>,
1093 name: &str,
1094 rust_return_ty: &'ll Type,
1095 rust_argument_tys: Vec<&'ll Type>,
1096 instance: ty::Instance<'tcx>,
1097) -> &'ll Value {
1098 let tcx = bx.tcx;
1099
1100 let rust_fn_ty = bx.type_func(&rust_argument_tys, rust_return_ty);
1101
1102 let intrinsic = llvm::Intrinsic::lookup(name.as_bytes());
1103
1104 if let Some(intrinsic) = intrinsic
1105 && intrinsic.is_target_specific()
1106 {
1107 let (llvm_arch, _) = name[5..].split_once('.').unwrap();
1108 let rust_arch = &tcx.sess.target.arch;
1109
1110 if let Some(correct_llvm_arch) = llvm_arch_for(rust_arch)
1111 && llvm_arch != correct_llvm_arch
1112 {
1113 tcx.dcx().emit_fatal(IntrinsicWrongArch {
1114 name,
1115 target_arch: rust_arch.desc(),
1116 span: tcx.def_span(instance.def_id()),
1117 });
1118 }
1119 }
1120
1121 if let Some(intrinsic) = intrinsic
1122 && !intrinsic.is_overloaded()
1123 {
1124 // FIXME: also do this for overloaded intrinsics
1125 let llfn = intrinsic.get_declaration(bx.llmod, &[]);
1126 let llvm_fn_ty = bx.get_type_of_global(llfn);
1127
1128 let llvm_return_ty = bx.get_return_type(llvm_fn_ty);
1129 let llvm_argument_tys = bx.func_params_types(llvm_fn_ty);
1130 let llvm_is_variadic = bx.func_is_variadic(llvm_fn_ty);
1131
1132 let is_correct_signature = !llvm_is_variadic
1133 && rust_argument_tys.len() == llvm_argument_tys.len()
1134 && iter::once((rust_return_ty, llvm_return_ty))
1135 .chain(iter::zip(rust_argument_tys, llvm_argument_tys))
1136 .all(|(rust_ty, llvm_ty)| can_autocast(bx, rust_ty, llvm_ty));
1137
1138 if !is_correct_signature {
1139 tcx.dcx().emit_fatal(IntrinsicSignatureMismatch {
1140 name,
1141 llvm_fn_ty: &format!("{llvm_fn_ty:?}"),
1142 rust_fn_ty: &format!("{rust_fn_ty:?}"),
1143 span: tcx.def_span(instance.def_id()),
1144 });
1145 }
1146
1147 return llfn;
1148 }
1149
1150 // Function addresses in Rust are never significant, allowing functions to be merged.
1151 let llfn = declare_raw_fn(
1152 bx,
1153 name,
1154 llvm::CCallConv,
1155 llvm::UnnamedAddr::Global,
1156 llvm::Visibility::Default,
1157 rust_fn_ty,
1158 );
1159
1160 if intrinsic.is_none() {
1161 let mut new_llfn = None;
1162 let can_upgrade = unsafe { llvm::LLVMRustUpgradeIntrinsicFunction(llfn, &mut new_llfn) };
1163
1164 if !can_upgrade {
1165 // This is either plain wrong, or this can be caused by incompatible LLVM versions
1166 tcx.dcx().emit_fatal(UnknownIntrinsic { name, span: tcx.def_span(instance.def_id()) });
1167 } else if let Some(def_id) = instance.def_id().as_local() {
1168 // we can emit diagnostics only for local crates
1169 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1170
1171 // not all intrinsics are upgraded to some other intrinsics, most are upgraded to instruction sequences
1172 let msg = if let Some(new_llfn) = new_llfn {
1173 format!(
1174 "using deprecated intrinsic `{name}`, `{}` can be used instead",
1175 str::from_utf8(&llvm::get_value_name(new_llfn)).unwrap()
1176 )
1177 } else {
1178 format!("using deprecated intrinsic `{name}`")
1179 };
1180
1181 tcx.emit_node_lint(
1182 DEPRECATED_LLVM_INTRINSIC,
1183 hir_id,
1184 rustc_errors::DiagDecorator(|d| {
1185 d.primary_message(msg).span(tcx.hir_span(hir_id));
1186 }),
1187 );
1188 }
1189 }
1190
1191 llfn
1192}
1193
9581194fn catch_unwind_intrinsic<'ll, 'tcx>(
9591195 bx: &mut Builder<'_, 'll, 'tcx>,
9601196 try_func: &'ll Value,
compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs-1
......@@ -73,7 +73,6 @@ unsafe extern "C" {
7373 pub(crate) fn LLVMDumpModule(M: &Module);
7474 pub(crate) fn LLVMDumpValue(V: &Value);
7575 pub(crate) fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
76 pub(crate) fn LLVMGetReturnType(T: &Type) -> &Type;
7776 pub(crate) fn LLVMGetParams(Fnc: &Value, params: *mut &Value);
7877 pub(crate) fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> Option<&Value>;
7978}
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+14
......@@ -921,6 +921,9 @@ unsafe extern "C" {
921921 pub(crate) fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
922922 pub(crate) fn LLVMFP128TypeInContext(C: &Context) -> &Type;
923923
924 // Operations on non-IEEE real types
925 pub(crate) fn LLVMBFloatTypeInContext(C: &Context) -> &Type;
926
924927 // Operations on function types
925928 pub(crate) fn LLVMFunctionType<'a>(
926929 ReturnType: &'a Type,
......@@ -930,6 +933,8 @@ unsafe extern "C" {
930933 ) -> &'a Type;
931934 pub(crate) fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint;
932935 pub(crate) fn LLVMGetParamTypes<'a>(FunctionTy: &'a Type, Dest: *mut &'a Type);
936 pub(crate) fn LLVMGetReturnType(FunctionTy: &Type) -> &Type;
937 pub(crate) fn LLVMIsFunctionVarArg(FunctionTy: &Type) -> Bool;
933938
934939 // Operations on struct types
935940 pub(crate) fn LLVMStructTypeInContext<'a>(
......@@ -1084,12 +1089,18 @@ unsafe extern "C" {
10841089
10851090 // Operations about llvm intrinsics
10861091 pub(crate) fn LLVMLookupIntrinsicID(Name: *const c_char, NameLen: size_t) -> c_uint;
1092 pub(crate) fn LLVMIntrinsicIsOverloaded(ID: NonZero<c_uint>) -> Bool;
10871093 pub(crate) fn LLVMGetIntrinsicDeclaration<'a>(
10881094 Mod: &'a Module,
10891095 ID: NonZero<c_uint>,
10901096 ParamTypes: *const &'a Type,
10911097 ParamCount: size_t,
10921098 ) -> &'a Value;
1099 pub(crate) fn LLVMRustUpgradeIntrinsicFunction<'a>(
1100 Fn: &'a Value,
1101 NewFn: &mut Option<&'a Value>,
1102 ) -> bool;
1103 pub(crate) fn LLVMRustIsTargetIntrinsic(ID: NonZero<c_uint>) -> bool;
10931104
10941105 // Operations on parameters
10951106 pub(crate) fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;
......@@ -1605,6 +1616,9 @@ unsafe extern "C" {
16051616 Packed: Bool,
16061617 );
16071618
1619 pub(crate) fn LLVMCountStructElementTypes(StructTy: &Type) -> c_uint;
1620 pub(crate) fn LLVMGetStructElementTypes<'a>(StructTy: &'a Type, Dest: *mut &'a Type);
1621
16081622 pub(crate) safe fn LLVMMetadataAsValue<'a>(C: &'a Context, MD: &'a Metadata) -> &'a Value;
16091623
16101624 pub(crate) safe fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr);
compiler/rustc_codegen_llvm/src/llvm/mod.rs+8
......@@ -323,6 +323,14 @@ impl Intrinsic {
323323 NonZero::new(id).map(|id| Self { id })
324324 }
325325
326 pub(crate) fn is_overloaded(self) -> bool {
327 unsafe { LLVMIntrinsicIsOverloaded(self.id).is_true() }
328 }
329
330 pub(crate) fn is_target_specific(self) -> bool {
331 unsafe { LLVMRustIsTargetIntrinsic(self.id) }
332 }
333
326334 pub(crate) fn get_declaration<'ll>(
327335 self,
328336 llmod: &'ll Module,
compiler/rustc_codegen_llvm/src/mono_item.rs+9-1
......@@ -135,7 +135,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
135135 let ty = self.get_type_of_global(aliasee);
136136
137137 for (alias, linkage, visibility) in aliases {
138 let symbol_name = self.tcx.symbol_name(Instance::mono(self.tcx, *alias));
138 let instance = Instance::mono(self.tcx, *alias);
139 let symbol_name = self.tcx.symbol_name(instance);
139140 tracing::debug!("STATIC ALIAS: {alias:?} {linkage:?} {visibility:?}");
140141
141142 let lldecl = llvm::add_alias(
......@@ -145,6 +146,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
145146 aliasee,
146147 &CString::new(symbol_name.name).unwrap(),
147148 );
149 // Add the alias name to the set of cached items, so there is no duplicate
150 // instance added to it during the normal `external static` codegen
151 let prev_entry = self.instances.borrow_mut().insert(instance, lldecl);
152
153 // If there already was a previous entry, then `add_static_aliases` was called multiple times for the same `alias`
154 // which would result in incorrect codegen
155 assert!(prev_entry.is_none(), "An instance was already present for {instance:?}");
148156
149157 llvm::set_visibility(lldecl, base::visibility_to_llvm(*visibility));
150158 llvm::set_linkage(lldecl, base::linkage_to_llvm(*linkage));
compiler/rustc_codegen_llvm/src/type_.rs+22
......@@ -77,6 +77,10 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
7777 unsafe { llvm::LLVMAddFunction(self.llmod(), name.as_ptr(), ty) }
7878 }
7979
80 pub(crate) fn get_return_type(&self, ty: &'ll Type) -> &'ll Type {
81 unsafe { llvm::LLVMGetReturnType(ty) }
82 }
83
8084 pub(crate) fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> {
8185 unsafe {
8286 let n_args = llvm::LLVMCountParamTypes(ty) as usize;
......@@ -86,6 +90,20 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
8690 args
8791 }
8892 }
93
94 pub(crate) fn func_is_variadic(&self, ty: &'ll Type) -> bool {
95 unsafe { llvm::LLVMIsFunctionVarArg(ty).is_true() }
96 }
97
98 pub(crate) fn struct_element_types(&self, ty: &'ll Type) -> Vec<&'ll Type> {
99 unsafe {
100 let n_args = llvm::LLVMCountStructElementTypes(ty) as usize;
101 let mut args = Vec::with_capacity(n_args);
102 llvm::LLVMGetStructElementTypes(ty, args.as_mut_ptr());
103 args.set_len(n_args);
104 args
105 }
106 }
89107}
90108impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
91109 pub(crate) fn type_bool(&self) -> &'ll Type {
......@@ -165,6 +183,10 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
165183 )
166184 }
167185 }
186
187 pub(crate) fn type_bf16(&self) -> &'ll Type {
188 unsafe { llvm::LLVMBFloatTypeInContext(self.llcx()) }
189 }
168190}
169191
170192impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
compiler/rustc_codegen_ssa/src/mir/rvalue.rs+8
......@@ -302,6 +302,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
302302 let to_backend_ty = bx.cx().immediate_backend_type(cast);
303303 OperandValue::Immediate(bx.bitcast(imm, to_backend_ty))
304304 }
305 (
306 OperandValue::Immediate(imm),
307 abi::BackendRepr::SimdScalableVector { element: from_scalar, .. },
308 abi::BackendRepr::SimdScalableVector { element: to_scalar, .. },
309 ) if vector_can_bitcast(from_scalar) && vector_can_bitcast(to_scalar) => {
310 let to_backend_ty = bx.cx().immediate_backend_type(cast);
311 OperandValue::Immediate(bx.bitcast(imm, to_backend_ty))
312 }
305313 (
306314 OperandValue::Pair(imm_a, imm_b),
307315 abi::BackendRepr::ScalarPair(in_a, in_b),
compiler/rustc_expand/src/build.rs+1
......@@ -715,6 +715,7 @@ impl<'a> ExtCtxt<'a> {
715715 mutability,
716716 expr: Some(expr),
717717 define_opaque: None,
718 eii_impls: Default::default(),
718719 }
719720 .into(),
720721 ),
compiler/rustc_hir_analysis/src/check/compare_eii.rs+118-14
......@@ -15,7 +15,7 @@ use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr};
1515use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1616use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
1717use rustc_middle::ty::error::{ExpectedFound, TypeError};
18use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode};
18use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypingMode};
1919use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
2020use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2121use rustc_trait_selection::regions::InferCtxtRegionExt;
......@@ -26,7 +26,10 @@ use super::potentially_plural_count;
2626use crate::check::compare_impl_item::{
2727 CheckNumberOfEarlyBoundRegionsError, check_number_of_early_bound_regions,
2828};
29use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii};
29use crate::errors::{
30 EiiDefkindMismatch, EiiDefkindMismatchStaticMutability, EiiDefkindMismatchStaticSafety,
31 EiiWithGenerics, LifetimesOrBoundsMismatchOnEii,
32};
3033
3134/// Checks whether the signature of some `external_impl`, matches
3235/// the signature of `declaration`, which it is supposed to be compatible
......@@ -38,14 +41,7 @@ pub(crate) fn compare_eii_function_types<'tcx>(
3841 eii_name: Symbol,
3942 eii_attr_span: Span,
4043) -> Result<(), ErrorGuaranteed> {
41 // Error recovery can resolve the EII target to another value item with the same name,
42 // such as a tuple-struct constructor. Skip the comparison in that case and rely on the
43 // earlier name-resolution error instead of ICEing while building EII diagnostics.
44 // See <https://github.com/rust-lang/rust/issues/153502>.
45 if !is_foreign_function(tcx, foreign_item) {
46 return Ok(());
47 }
48
44 check_eii_target(tcx, external_impl, foreign_item, eii_name, eii_attr_span)?;
4945 check_is_structurally_compatible(tcx, external_impl, foreign_item, eii_name, eii_attr_span)?;
5046
5147 let external_impl_span = tcx.def_span(external_impl);
......@@ -152,6 +148,118 @@ pub(crate) fn compare_eii_function_types<'tcx>(
152148 Ok(())
153149}
154150
151pub(crate) fn compare_eii_statics<'tcx>(
152 tcx: TyCtxt<'tcx>,
153 external_impl: LocalDefId,
154 external_impl_ty: Ty<'tcx>,
155 foreign_item: DefId,
156 eii_name: Symbol,
157 eii_attr_span: Span,
158) -> Result<(), ErrorGuaranteed> {
159 check_eii_target(tcx, external_impl, foreign_item, eii_name, eii_attr_span)?;
160
161 let external_impl_span = tcx.def_span(external_impl);
162 let cause = ObligationCause::new(
163 external_impl_span,
164 external_impl,
165 ObligationCauseCode::CompareEii { external_impl, declaration: foreign_item },
166 );
167
168 let param_env = ParamEnv::empty();
169
170 let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
171 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
172
173 let declaration_ty = tcx.type_of(foreign_item).instantiate_identity();
174 debug!(?declaration_ty);
175
176 // FIXME: Copied over from compare impl items, same issue:
177 // We'd want to keep more accurate spans than "the method signature" when
178 // processing the comparison between the trait and impl fn, but we sadly lose them
179 // and point at the whole signature when a trait bound or specific input or output
180 // type would be more appropriate. In other places we have a `Vec<Span>`
181 // corresponding to their `Vec<Predicate>`, but we don't have that here.
182 // Fixing this would improve the output of test `issue-83765.rs`.
183 let result = ocx.sup(&cause, param_env, declaration_ty, external_impl_ty);
184
185 if let Err(terr) = result {
186 debug!(?external_impl_ty, ?declaration_ty, ?terr, "sub_types failed");
187
188 let mut diag = struct_span_code_err!(
189 tcx.dcx(),
190 cause.span,
191 E0806,
192 "static `{}` has a type that is incompatible with the declaration of `#[{eii_name}]`",
193 tcx.item_name(external_impl)
194 );
195 diag.span_note(eii_attr_span, "expected this because of this attribute");
196
197 return Err(diag.emit());
198 }
199
200 // Check that all obligations are satisfied by the implementation's
201 // version.
202 let errors = ocx.evaluate_obligations_error_on_ambiguity();
203 if !errors.is_empty() {
204 let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
205 return Err(reported);
206 }
207
208 // Finally, resolve all regions. This catches wily misuses of
209 // lifetime parameters.
210 let errors = infcx.resolve_regions(external_impl, param_env, []);
211 if !errors.is_empty() {
212 return Err(infcx
213 .tainted_by_errors()
214 .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(external_impl, &errors)));
215 }
216
217 Ok(())
218}
219
220fn check_eii_target(
221 tcx: TyCtxt<'_>,
222 external_impl: LocalDefId,
223 foreign_item: DefId,
224 eii_name: Symbol,
225 eii_attr_span: Span,
226) -> Result<(), ErrorGuaranteed> {
227 // Error recovery can resolve the EII target to another value item with the same name,
228 // such as a tuple-struct constructor. Skip the comparison in that case and rely on the
229 // earlier name-resolution error instead of ICEing while building EII diagnostics.
230 // See <https://github.com/rust-lang/rust/issues/153502>.
231 if !tcx.is_foreign_item(foreign_item) {
232 return Err(tcx.dcx().delayed_bug("EII is a foreign item"));
233 }
234 let expected_kind = tcx.def_kind(foreign_item);
235 let actual_kind = tcx.def_kind(external_impl);
236
237 match expected_kind {
238 // Correct target
239 _ if expected_kind == actual_kind => Ok(()),
240 DefKind::Static { mutability: m1, safety: s1, .. }
241 if let DefKind::Static { mutability: m2, safety: s2, .. } = actual_kind =>
242 {
243 Err(if s1 != s2 {
244 tcx.dcx().emit_err(EiiDefkindMismatchStaticSafety { span: eii_attr_span, eii_name })
245 } else if m1 != m2 {
246 tcx.dcx()
247 .emit_err(EiiDefkindMismatchStaticMutability { span: eii_attr_span, eii_name })
248 } else {
249 unreachable!()
250 })
251 }
252 // Not checked by attr target checking
253 DefKind::Fn | DefKind::Static { .. } => Err(tcx.dcx().emit_err(EiiDefkindMismatch {
254 span: eii_attr_span,
255 eii_name,
256 expected_kind: expected_kind.descr(foreign_item),
257 })),
258 // Checked by attr target checking
259 _ => Err(tcx.dcx().delayed_bug("Attribute should not be allowed by target checking")),
260 }
261}
262
155263/// Checks a bunch of different properties of the impl/trait methods for
156264/// compatibility, such as asyncness, number of argument, self receiver kind,
157265/// and number of early- and late-bound generics.
......@@ -451,7 +559,3 @@ fn get_declaration_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option<&'
451559 let hir_id: HirId = tcx.local_def_id_to_hir_id(def_id);
452560 tcx.hir_fn_sig_by_hir_id(hir_id)
453561}
454
455fn is_foreign_function(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
456 tcx.is_foreign_item(def_id) && matches!(tcx.def_kind(def_id), DefKind::Fn)
457}
compiler/rustc_hir_analysis/src/check/wfcheck.rs+34-3
......@@ -41,7 +41,7 @@ use rustc_trait_selection::traits::{
4141};
4242use tracing::{debug, instrument};
4343
44use super::compare_eii::compare_eii_function_types;
44use super::compare_eii::{compare_eii_function_types, compare_eii_statics};
4545use crate::autoderef::Autoderef;
4646use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
4747use crate::errors;
......@@ -1208,7 +1208,7 @@ fn check_item_fn(
12081208 decl: &hir::FnDecl<'_>,
12091209) -> Result<(), ErrorGuaranteed> {
12101210 enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
1211 check_eiis(tcx, def_id);
1211 check_eiis_fn(tcx, def_id);
12121212
12131213 let sig = tcx.fn_sig(def_id).instantiate_identity();
12141214 check_fn_or_method(wfcx, sig, decl, def_id);
......@@ -1216,7 +1216,7 @@ fn check_item_fn(
12161216 })
12171217}
12181218
1219fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1219fn check_eiis_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) {
12201220 // does the function have an EiiImpl attribute? that contains the defid of a *macro*
12211221 // that was used to mark the implementation. This is a two step process.
12221222 for EiiImpl { resolution, span, .. } in
......@@ -1243,6 +1243,33 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) {
12431243 }
12441244}
12451245
1246fn check_eiis_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, ty: Ty<'tcx>) {
1247 // does the function have an EiiImpl attribute? that contains the defid of a *macro*
1248 // that was used to mark the implementation. This is a two step process.
1249 for EiiImpl { resolution, span, .. } in
1250 find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_iter().flatten()
1251 {
1252 let (foreign_item, name) = match resolution {
1253 EiiImplResolution::Macro(def_id) => {
1254 // we expect this macro to have the `EiiMacroFor` attribute, that points to a function
1255 // signature that we'd like to compare the function we're currently checking with
1256 if let Some(foreign_item) =
1257 find_attr!(tcx, *def_id, EiiDeclaration(EiiDecl {foreign_item: t, ..}) => *t)
1258 {
1259 (foreign_item, tcx.item_name(*def_id))
1260 } else {
1261 tcx.dcx().span_delayed_bug(*span, "resolved to something that's not an EII");
1262 continue;
1263 }
1264 }
1265 EiiImplResolution::Known(decl) => (decl.foreign_item, decl.name.name),
1266 EiiImplResolution::Error(_eg) => continue,
1267 };
1268
1269 let _ = compare_eii_statics(tcx, def_id, ty, foreign_item, name, *span);
1270 }
1271}
1272
12461273#[instrument(level = "debug", skip(tcx))]
12471274pub(crate) fn check_static_item<'tcx>(
12481275 tcx: TyCtxt<'tcx>,
......@@ -1251,6 +1278,10 @@ pub(crate) fn check_static_item<'tcx>(
12511278 should_check_for_sync: bool,
12521279) -> Result<(), ErrorGuaranteed> {
12531280 enter_wf_checking_ctxt(tcx, item_id, |wfcx| {
1281 if should_check_for_sync {
1282 check_eiis_static(tcx, item_id, ty);
1283 }
1284
12541285 let span = tcx.ty_span(item_id);
12551286 let loc = Some(WellFormedLoc::Ty(item_id));
12561287 let item_ty = wfcx.deeply_normalize(span, loc, ty);
compiler/rustc_hir_analysis/src/errors.rs+25
......@@ -1933,3 +1933,28 @@ pub(crate) struct ImplUnpinForPinProjectedType {
19331933 pub adt_span: Span,
19341934 pub adt_name: Symbol,
19351935}
1936
1937#[derive(Diagnostic)]
1938#[diag("`#[{$eii_name}]` must be used on a {$expected_kind}")]
1939pub(crate) struct EiiDefkindMismatch {
1940 #[primary_span]
1941 pub span: Span,
1942 pub eii_name: Symbol,
1943 pub expected_kind: &'static str,
1944}
1945
1946#[derive(Diagnostic)]
1947#[diag("mutability does not match with the definition of`#[{$eii_name}]`")]
1948pub(crate) struct EiiDefkindMismatchStaticMutability {
1949 #[primary_span]
1950 pub span: Span,
1951 pub eii_name: Symbol,
1952}
1953
1954#[derive(Diagnostic)]
1955#[diag("safety does not match with the definition of`#[{$eii_name}]`")]
1956pub(crate) struct EiiDefkindMismatchStaticSafety {
1957 #[primary_span]
1958 pub span: Span,
1959 pub eii_name: Symbol,
1960}
compiler/rustc_hir_typeck/src/expr.rs+4-1
......@@ -3557,6 +3557,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35573557 // Register the impl's predicates. One of these predicates
35583558 // must be unsatisfied, or else we wouldn't have gotten here
35593559 // in the first place.
3560 let unnormalized_predicates =
3561 self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args);
35603562 ocx.register_obligations(traits::predicates_for_generics(
35613563 |idx, span| {
35623564 cause.clone().derived_cause(
......@@ -3574,8 +3576,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35743576 },
35753577 )
35763578 },
3579 |pred| ocx.normalize(&cause, self.param_env, pred),
35773580 self.param_env,
3578 self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args),
3581 unnormalized_predicates,
35793582 ));
35803583
35813584 // Normalize the output type, which we can use later on as the
compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs+2-15
......@@ -423,20 +423,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
423423 }
424424 }
425425
426 /// Instantiates and normalizes the bounds for a given item
427 pub(crate) fn instantiate_bounds(
428 &self,
429 span: Span,
430 def_id: DefId,
431 args: GenericArgsRef<'tcx>,
432 ) -> ty::InstantiatedPredicates<'tcx> {
433 let bounds = self.tcx.predicates_of(def_id);
434 let result = bounds.instantiate(self.tcx, args);
435 let result = self.normalize(span, result);
436 debug!("instantiate_bounds(bounds={:?}, args={:?}) = {:?}", bounds, args, result);
437 result
438 }
439
440426 pub(crate) fn normalize<T>(&self, span: Span, value: T) -> T
441427 where
442428 T: TypeFoldable<TyCtxt<'tcx>>,
......@@ -1426,10 +1412,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14261412 ) {
14271413 let param_env = self.param_env;
14281414
1429 let bounds = self.instantiate_bounds(span, def_id, args);
1415 let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, args);
14301416
14311417 for obligation in traits::predicates_for_generics(
14321418 |idx, predicate_span| self.cause(span, code(idx, predicate_span)),
1419 |pred| self.normalize(span, pred),
14331420 param_env,
14341421 bounds,
14351422 ) {
compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs+1-1
......@@ -339,9 +339,9 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
339339
340340 // Check whether the impl imposes obligations we have to worry about.
341341 let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
342 let impl_bounds = ocx.normalize(&ObligationCause::dummy(), self.param_env, impl_bounds);
343342 let impl_obligations = traits::predicates_for_generics(
344343 |_, _| ObligationCause::dummy(),
344 |pred| ocx.normalize(&ObligationCause::dummy(), self.param_env, pred),
345345 self.param_env,
346346 impl_bounds,
347347 );
compiler/rustc_hir_typeck/src/method/confirm.rs+2-2
......@@ -144,8 +144,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
144144 );
145145 self.unify_receivers(self_ty, method_sig_rcvr, pick);
146146
147 let (method_sig, method_predicates) =
148 self.normalize(self.span, (method_sig, method_predicates));
147 let method_sig = self.normalize(self.span, method_sig);
149148
150149 // Make sure nobody calls `drop()` explicitly.
151150 self.check_for_illegal_method_calls(pick);
......@@ -626,6 +625,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
626625 );
627626 self.cause(self.span, code)
628627 },
628 |pred| self.normalize(self.call_expr.span, pred),
629629 self.param_env,
630630 method_predicates,
631631 ) {
compiler/rustc_hir_typeck/src/method/mod.rs+9-5
......@@ -442,17 +442,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
442442 // any late-bound regions appearing in its bounds.
443443 let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, args);
444444
445 let InferOk { value: bounds, obligations: o } =
446 self.at(&obligation.cause, self.param_env).normalize(bounds);
447 obligations.extend(o);
448 assert!(!bounds.has_escaping_bound_vars());
449
450445 let predicates_cause = obligation.cause.clone();
446 let mut normalization_obligations = PredicateObligations::new();
451447 obligations.extend(traits::predicates_for_generics(
452448 move |_, _| predicates_cause.clone(),
449 |pred| {
450 let InferOk { value: pred, obligations: o } =
451 self.at(&obligation.cause, self.param_env).normalize(pred);
452 normalization_obligations.extend(o);
453 assert!(!pred.has_escaping_bound_vars());
454 pred
455 },
453456 self.param_env,
454457 bounds,
455458 ));
459 obligations.extend(normalization_obligations);
456460
457461 // Also add an obligation for the method type being well-formed.
458462 debug!(
compiler/rustc_hir_typeck/src/method/probe.rs+1-1
......@@ -1989,7 +1989,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
19891989 let impl_def_id = probe.item.container_id(self.tcx);
19901990 let impl_bounds =
19911991 self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args);
1992 let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds);
19931992 // Convert the bounds into obligations.
19941993 ocx.register_obligations(traits::predicates_for_generics(
19951994 |idx, span| {
......@@ -2001,6 +2000,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
20012000 );
20022001 self.cause(self.span, code)
20032002 },
2003 |pred| ocx.normalize(cause, self.param_env, pred),
20042004 self.param_env,
20052005 impl_bounds,
20062006 ));
compiler/rustc_lint_defs/src/builtin.rs+46
......@@ -37,6 +37,7 @@ declare_lint_pass! {
3737 DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
3838 DEPRECATED,
3939 DEPRECATED_IN_FUTURE,
40 DEPRECATED_LLVM_INTRINSIC,
4041 DEPRECATED_SAFE_2024,
4142 DEPRECATED_WHERE_CLAUSE_LOCATION,
4243 DUPLICATE_FEATURES,
......@@ -5597,3 +5598,48 @@ declare_lint! {
55975598 report_in_deps: false,
55985599 };
55995600}
5601
5602declare_lint! {
5603 /// The `deprecated_llvm_intrinsic` lint detects usage of deprecated LLVM intrinsics.
5604 ///
5605 /// ### Example
5606 ///
5607 /// ```rust,ignore (requires x86)
5608 /// #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
5609 /// #![feature(link_llvm_intrinsics, abi_unadjusted)]
5610 /// #![deny(deprecated_llvm_intrinsic)]
5611 ///
5612 /// unsafe extern "unadjusted" {
5613 /// #[link_name = "llvm.x86.addcarryx.u32"]
5614 /// fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5615 /// }
5616 ///
5617 /// #[inline(never)]
5618 /// #[target_feature(enable = "adx")]
5619 /// pub fn bar(a: u8, b: u32, c: u32, d: &mut u32) -> u8 {
5620 /// unsafe { foo(a, b, c, d) }
5621 /// }
5622 /// ```
5623 ///
5624 /// This will produce:
5625 ///
5626 /// ```text
5627 /// error: Using deprecated intrinsic `llvm.x86.addcarryx.u32`
5628 /// --> example.rs:7:5
5629 /// |
5630 /// 7 | fn foo(a: u8, b: u32, c: u32, d: &mut u32) -> u8;
5631 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5632 /// |
5633 /// ```
5634 ///
5635 /// ### Explanation
5636 ///
5637 /// LLVM periodically updates its list of intrinsics. Deprecated intrinsics are unlikely
5638 /// to be removed, but they may optimize less well than their new versions, so it's
5639 /// best to use the new version. Also, some deprecated intrinsics might have buggy
5640 /// behavior
5641 pub DEPRECATED_LLVM_INTRINSIC,
5642 Allow,
5643 "detects uses of deprecated LLVM intrinsics",
5644 @feature_gate = link_llvm_intrinsics;
5645}
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp+14
......@@ -9,6 +9,7 @@
99#include "llvm/ADT/StringRef.h"
1010#include "llvm/BinaryFormat/Magic.h"
1111#include "llvm/Bitcode/BitcodeWriter.h"
12#include "llvm/IR/AutoUpgrade.h"
1213#include "llvm/IR/DIBuilder.h"
1314#include "llvm/IR/DebugInfoMetadata.h"
1415#include "llvm/IR/DiagnosticHandler.h"
......@@ -1815,6 +1816,19 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
18151816 GV.setSanitizerMetadata(MD);
18161817}
18171818
1819extern "C" bool LLVMRustUpgradeIntrinsicFunction(LLVMValueRef Fn,
1820 LLVMValueRef *NewFn) {
1821 Function *F = unwrap<Function>(Fn);
1822 Function *NewF = nullptr;
1823 bool CanUpgrade = UpgradeIntrinsicFunction(F, NewF, false);
1824 *NewFn = wrap(NewF);
1825 return CanUpgrade;
1826}
1827
1828extern "C" bool LLVMRustIsTargetIntrinsic(unsigned ID) {
1829 return Intrinsic::isTargetIntrinsic(ID);
1830}
1831
18181832// Statically assert that the fixed metadata kind IDs declared in
18191833// `metadata_kind.rs` match the ones actually used by LLVM.
18201834#define FIXED_MD_KIND(VARIANT, VALUE) \
compiler/rustc_middle/src/queries.rs+3-3
......@@ -60,7 +60,7 @@ use rustc_data_structures::sorted_map::SortedMap;
6060use rustc_data_structures::steal::Steal;
6161use rustc_data_structures::svh::Svh;
6262use rustc_data_structures::unord::{UnordMap, UnordSet};
63use rustc_errors::ErrorGuaranteed;
63use rustc_errors::{ErrorGuaranteed, catch_fatal_errors};
6464use rustc_hir as hir;
6565use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem};
6666use rustc_hir::def::{DefKind, DocLinkResMap};
......@@ -1202,7 +1202,7 @@ rustc_queries! {
12021202 /// Return the live symbols in the crate for dead code check.
12031203 ///
12041204 /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone).
1205 query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx Result<(
1205 query live_symbols_and_ignored_derived_traits(_: ()) -> Result<&'tcx (
12061206 LocalDefIdSet,
12071207 LocalDefIdMap<FxIndexSet<DefId>>,
12081208 ), ErrorGuaranteed> {
......@@ -1292,7 +1292,7 @@ rustc_queries! {
12921292
12931293 /// Return the set of (transitive) callees that may result in a recursive call to `key`,
12941294 /// if we were able to walk all callees.
1295 query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option<UnordSet<LocalDefId>> {
1295 query mir_callgraph_cyclic(key: LocalDefId) -> Option<&'tcx UnordSet<LocalDefId>> {
12961296 arena_cache
12971297 desc {
12981298 "computing (transitive) callees of `{}` that may recurse",
compiler/rustc_middle/src/query/arena_cached.rs+16
......@@ -1,6 +1,7 @@
11use std::mem;
22
33use rustc_arena::TypedArena;
4use rustc_span::ErrorGuaranteed;
45
56use crate::ty::TyCtxt;
67
......@@ -51,6 +52,21 @@ impl<'tcx, T> ArenaCached<'tcx> for Option<&'tcx T> {
5152 }
5253}
5354
55impl<'tcx, T> ArenaCached<'tcx> for Result<&'tcx T, ErrorGuaranteed> {
56 type Provided = Result<T, ErrorGuaranteed>;
57 /// The provide value is `Result<T, ErrorGuaranteed>`, but we only store `T` in the arena.
58 type Allocated = T;
59
60 fn alloc_in_arena(
61 tcx: TyCtxt<'tcx>,
62 typed_arena: &'tcx TypedArena<T>,
63 value: Result<T, ErrorGuaranteed>,
64 ) -> Self {
65 // Don't store Err(ErrorGuaranteed) in the arena, and wrap the allocated reference in Ok.
66 try { do_alloc(tcx, typed_arena, value?) }
67 }
68}
69
5470/// Allocates a value in either its dedicated arena, or in the common dropless
5571/// arena, depending on whether it needs to be dropped.
5672fn do_alloc<'tcx, T>(tcx: TyCtxt<'tcx>, typed_arena: &'tcx TypedArena<T>, value: T) -> &'tcx T {
compiler/rustc_middle/src/query/plumbing.rs+12
......@@ -166,6 +166,8 @@ pub struct QuerySystem<'tcx> {
166166 pub extern_providers: ExternProviders,
167167
168168 pub jobs: AtomicU64,
169
170 pub cycle_handler_nesting: Lock<u8>,
169171}
170172
171173#[derive(Copy, Clone)]
......@@ -446,6 +448,11 @@ macro_rules! define_callbacks {
446448 }
447449 }
448450
451 /// Calls `self.description` or returns a fallback if there was a fatal error
452 pub fn catch_description(&self, tcx: TyCtxt<'tcx>) -> String {
453 catch_fatal_errors(|| self.description(tcx)).unwrap_or_else(|_| format!("<error describing {}>", self.query_name()))
454 }
455
449456 /// Returns the default span for this query if `span` is a dummy span.
450457 pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
451458 if !span.is_dummy() {
......@@ -463,6 +470,11 @@ macro_rules! define_callbacks {
463470 )*
464471 }
465472 }
473
474 /// Calls `self.default_span` or returns `DUMMY_SP` if there was a fatal error
475 pub fn catch_default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span {
476 catch_fatal_errors(|| self.default_span(tcx, span)).unwrap_or(DUMMY_SP)
477 }
466478 }
467479
468480 /// Holds a `QueryVTable` for each query.
compiler/rustc_middle/src/ty/mod.rs+1-1
......@@ -689,7 +689,7 @@ impl<'tcx> TermKind<'tcx> {
689689/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
690690/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
691691/// [usize:Bar<isize>]]`.
692#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
692#[derive(Clone, Debug)]
693693pub struct InstantiatedPredicates<'tcx> {
694694 pub predicates: Vec<Clause<'tcx>>,
695695 pub spans: Vec<Span>,
compiler/rustc_parse/src/parser/item.rs+11-1
......@@ -1235,6 +1235,7 @@ impl<'a> Parser<'a> {
12351235 mutability: _,
12361236 expr,
12371237 define_opaque,
1238 eii_impls: _,
12381239 }) => {
12391240 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
12401241 AssocItemKind::Const(Box::new(ConstItem {
......@@ -1503,6 +1504,7 @@ impl<'a> Parser<'a> {
15031504 },
15041505 safety: Safety::Default,
15051506 define_opaque: None,
1507 eii_impls: ThinVec::default(),
15061508 }))
15071509 }
15081510 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
......@@ -1636,7 +1638,15 @@ impl<'a> Parser<'a> {
16361638
16371639 self.expect_semi()?;
16381640
1639 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1641 let item = StaticItem {
1642 ident,
1643 ty,
1644 safety,
1645 mutability,
1646 expr,
1647 define_opaque: None,
1648 eii_impls: ThinVec::default(),
1649 };
16401650 Ok(ItemKind::Static(Box::new(item)))
16411651 }
16421652
compiler/rustc_passes/src/check_attr.rs+2-2
......@@ -552,9 +552,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
552552 fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) {
553553 for EiiImpl { span, inner_span, resolution, impl_marked_unsafe, is_default: _ } in impls {
554554 match target {
555 Target::Fn => {}
555 Target::Fn | Target::Static => {}
556556 _ => {
557 self.dcx().emit_err(errors::EiiImplNotFunction { span: *span });
557 self.dcx().emit_err(errors::EiiImplTarget { span: *span });
558558 }
559559 }
560560
compiler/rustc_passes/src/errors.rs+2-2
......@@ -1189,8 +1189,8 @@ pub(crate) struct ReprAlignShouldBeAlignStatic {
11891189}
11901190
11911191#[derive(Diagnostic)]
1192#[diag("`eii_macro_for` is only valid on functions")]
1193pub(crate) struct EiiImplNotFunction {
1192#[diag("`eii_macro_for` is only valid on functions and statics")]
1193pub(crate) struct EiiImplTarget {
11941194 #[primary_span]
11951195 pub span: Span,
11961196}
compiler/rustc_query_impl/src/error.rs+25
......@@ -79,3 +79,28 @@ pub(crate) struct Cycle {
7979 )]
8080 pub note_span: (),
8181}
82
83#[derive(Subdiagnostic)]
84#[note("...when {$stack_bottom}")]
85pub(crate) struct NestedCycleBottom {
86 pub stack_bottom: String,
87}
88
89#[derive(Diagnostic)]
90#[diag("internal compiler error: query cycle when printing cycle detected")]
91pub(crate) struct NestedCycle {
92 #[primary_span]
93 pub span: Span,
94 #[subdiagnostic]
95 pub stack_bottom: NestedCycleBottom,
96 #[subdiagnostic]
97 pub cycle_stack: Vec<CycleStack>,
98 #[subdiagnostic]
99 pub stack_count: StackCount,
100 #[subdiagnostic]
101 pub cycle_usage: Option<CycleUsage>,
102 #[note(
103 "see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information"
104 )]
105 pub note_span: (),
106}
compiler/rustc_query_impl/src/execution.rs+25-3
......@@ -4,7 +4,7 @@ use std::mem::ManuallyDrop;
44use rustc_data_structures::hash_table::{Entry, HashTable};
55use rustc_data_structures::stack::ensure_sufficient_stack;
66use rustc_data_structures::sync::{DynSend, DynSync};
7use rustc_data_structures::{outline, sharded, sync};
7use rustc_data_structures::{defer, outline, sharded, sync};
88use rustc_errors::FatalError;
99use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex};
1010use rustc_middle::query::{
......@@ -17,6 +17,7 @@ use rustc_span::{DUMMY_SP, Span};
1717use tracing::warn;
1818
1919use crate::dep_graph::{DepNode, DepNodeIndex};
20use crate::handle_cycle_error;
2021use crate::job::{QueryJobInfo, QueryJobMap, create_cycle_error, find_cycle_in_stack};
2122use crate::plumbing::{current_query_job, loadable_from_disk, next_job_id, start_query};
2223use crate::query_impl::for_each_query_vtable;
......@@ -114,8 +115,29 @@ fn handle_cycle<'tcx, C: QueryCache>(
114115 key: C::Key,
115116 cycle: Cycle<'tcx>,
116117) -> C::Value {
117 let error = create_cycle_error(tcx, &cycle);
118 (query.handle_cycle_error_fn)(tcx, key, cycle, error)
118 let nested;
119 {
120 let mut nesting = tcx.query_system.cycle_handler_nesting.lock();
121 nested = match *nesting {
122 0 => false,
123 1 => true,
124 _ => {
125 // Don't print further nested errors to avoid cases of infinite recursion
126 tcx.dcx().delayed_bug("doubly nested cycle error").raise_fatal()
127 }
128 };
129 *nesting += 1;
130 }
131 let _guard = defer(|| *tcx.query_system.cycle_handler_nesting.lock() -= 1);
132
133 let error = create_cycle_error(tcx, &cycle, nested);
134
135 if nested {
136 // Avoid custom handlers and only use the robust `create_cycle_error` for nested cycle errors
137 handle_cycle_error::default(error)
138 } else {
139 (query.handle_cycle_error_fn)(tcx, key, cycle, error)
140 }
119141}
120142
121143/// Guard object representing the responsibility to execute a query job and
compiler/rustc_query_impl/src/handle_cycle_error.rs+1-1
......@@ -210,7 +210,7 @@ pub(crate) fn layout_of<'tcx>(
210210 ControlFlow::Continue(())
211211 }
212212 },
213 || create_cycle_error(tcx, &cycle),
213 || create_cycle_error(tcx, &cycle, false),
214214 );
215215
216216 diag.emit().raise_fatal()
compiler/rustc_query_impl/src/job.rs+35-21
......@@ -413,15 +413,16 @@ pub fn print_query_stack<'tcx>(
413413pub(crate) fn create_cycle_error<'tcx>(
414414 tcx: TyCtxt<'tcx>,
415415 Cycle { usage, frames }: &Cycle<'tcx>,
416 nested: bool,
416417) -> Diag<'tcx> {
417418 assert!(!frames.is_empty());
418419
419 let span = frames[0].tagged_key.default_span(tcx, frames[1 % frames.len()].span);
420 let span = frames[0].tagged_key.catch_default_span(tcx, frames[1 % frames.len()].span);
420421
421422 let mut cycle_stack = Vec::new();
422423
423424 use crate::error::StackCount;
424 let stack_bottom = frames[0].tagged_key.description(tcx);
425 let stack_bottom = frames[0].tagged_key.catch_description(tcx);
425426 let stack_count = if frames.len() == 1 {
426427 StackCount::Single { stack_bottom: stack_bottom.clone() }
427428 } else {
......@@ -430,14 +431,14 @@ pub(crate) fn create_cycle_error<'tcx>(
430431
431432 for i in 1..frames.len() {
432433 let frame = &frames[i];
433 let span = frame.tagged_key.default_span(tcx, frames[(i + 1) % frames.len()].span);
434 let span = frame.tagged_key.catch_default_span(tcx, frames[(i + 1) % frames.len()].span);
434435 cycle_stack
435 .push(crate::error::CycleStack { span, desc: frame.tagged_key.description(tcx) });
436 .push(crate::error::CycleStack { span, desc: frame.tagged_key.catch_description(tcx) });
436437 }
437438
438439 let cycle_usage = usage.as_ref().map(|usage| crate::error::CycleUsage {
439 span: usage.tagged_key.default_span(tcx, usage.span),
440 usage: usage.tagged_key.description(tcx),
440 span: usage.tagged_key.catch_default_span(tcx, usage.span),
441 usage: usage.tagged_key.catch_description(tcx),
441442 });
442443
443444 let is_all_def_kind = |def_kind| {
......@@ -454,23 +455,36 @@ pub(crate) fn create_cycle_error<'tcx>(
454455 })
455456 };
456457
457 let alias = if is_all_def_kind(DefKind::TyAlias) {
458 Some(crate::error::Alias::Ty)
459 } else if is_all_def_kind(DefKind::TraitAlias) {
460 Some(crate::error::Alias::Trait)
458 let alias = if !nested {
459 if is_all_def_kind(DefKind::TyAlias) {
460 Some(crate::error::Alias::Ty)
461 } else if is_all_def_kind(DefKind::TraitAlias) {
462 Some(crate::error::Alias::Trait)
463 } else {
464 None
465 }
461466 } else {
462467 None
463468 };
464469
465 let cycle_diag = crate::error::Cycle {
466 span,
467 cycle_stack,
468 stack_bottom,
469 alias,
470 cycle_usage,
471 stack_count,
472 note_span: (),
473 };
474
475 tcx.sess.dcx().create_err(cycle_diag)
470 if nested {
471 tcx.sess.dcx().create_err(crate::error::NestedCycle {
472 span,
473 cycle_stack,
474 stack_bottom: crate::error::NestedCycleBottom { stack_bottom },
475 cycle_usage,
476 stack_count,
477 note_span: (),
478 })
479 } else {
480 tcx.sess.dcx().create_err(crate::error::Cycle {
481 span,
482 cycle_stack,
483 stack_bottom,
484 alias,
485 cycle_usage,
486 stack_count,
487 note_span: (),
488 })
489 }
476490}
compiler/rustc_query_impl/src/lib.rs+2-1
......@@ -8,7 +8,7 @@
88#![feature(try_blocks)]
99// tidy-alphabetical-end
1010
11use rustc_data_structures::sync::AtomicU64;
11use rustc_data_structures::sync::{AtomicU64, Lock};
1212use rustc_middle::dep_graph;
1313use rustc_middle::queries::{ExternProviders, Providers};
1414use rustc_middle::query::on_disk_cache::OnDiskCache;
......@@ -56,6 +56,7 @@ pub fn query_system<'tcx>(
5656 local_providers,
5757 extern_providers,
5858 jobs: AtomicU64::new(1),
59 cycle_handler_nesting: Lock::new(0),
5960 }
6061}
6162
compiler/rustc_resolve/src/def_collector.rs+1
......@@ -274,6 +274,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
274274 expr: _,
275275 safety,
276276 define_opaque: _,
277 eii_impls: _,
277278 }) => {
278279 let safety = match safety {
279280 ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe,
compiler/rustc_resolve/src/diagnostics.rs+1-1
......@@ -2983,7 +2983,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
29832983 }
29842984
29852985 let binding_key = BindingKey::new(IdentKey::new(ident), MacroNS);
2986 let binding = self.resolution(crate_module, binding_key)?.binding()?;
2986 let binding = self.resolution(crate_module, binding_key)?.best_decl()?;
29872987 let Res::Def(DefKind::Macro(kinds), _) = binding.res() else {
29882988 return None;
29892989 };
compiler/rustc_resolve/src/effective_visibilities.rs+1-1
......@@ -114,7 +114,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
114114 fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
115115 let module = self.r.expect_module(module_id.to_def_id());
116116 for (_, name_resolution) in self.r.resolutions(module).borrow().iter() {
117 let Some(mut decl) = name_resolution.borrow().binding() else {
117 let Some(mut decl) = name_resolution.borrow().best_decl() else {
118118 continue;
119119 };
120120 // Set the given effective visibility level to `Level::Direct` and
compiler/rustc_resolve/src/errors.rs+15-11
......@@ -1521,20 +1521,24 @@ pub(crate) struct RedundantImportVisibility {
15211521#[diag("unknown diagnostic attribute")]
15221522pub(crate) struct UnknownDiagnosticAttribute {
15231523 #[subdiagnostic]
1524 pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
1524 pub help: Option<UnknownDiagnosticAttributeHelp>,
15251525}
15261526
15271527#[derive(Subdiagnostic)]
1528#[suggestion(
1529 "an attribute with a similar name exists",
1530 style = "verbose",
1531 code = "{typo_name}",
1532 applicability = "machine-applicable"
1533)]
1534pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
1535 #[primary_span]
1536 pub span: Span,
1537 pub typo_name: Symbol,
1528pub(crate) enum UnknownDiagnosticAttributeHelp {
1529 #[suggestion(
1530 "an attribute with a similar name exists",
1531 style = "verbose",
1532 code = "{typo_name}",
1533 applicability = "machine-applicable"
1534 )]
1535 Typo {
1536 #[primary_span]
1537 span: Span,
1538 typo_name: Symbol,
1539 },
1540 #[help("add `#![feature({$feature})]` to the crate attributes to enable")]
1541 UseFeature { feature: Symbol },
15381542}
15391543
15401544// FIXME: Make this properly translatable.
compiler/rustc_resolve/src/imports.rs+41-51
......@@ -289,15 +289,22 @@ impl<'ra> NameResolution<'ra> {
289289 NameResolution { single_imports: FxIndexSet::default(), orig_ident_span, .. }
290290 }
291291
292 /// Returns the binding for the name if it is known or None if it not known.
293 pub(crate) fn binding(&self) -> Option<Decl<'ra>> {
294 self.best_decl().and_then(|binding| {
295 if !binding.is_glob_import() || self.single_imports.is_empty() {
296 Some(binding)
297 } else {
298 None
299 }
300 })
292 /// Returns the best declaration if it is not going to change, and `None` if the best
293 /// declaration may still change to something else.
294 /// FIXME: this function considers `single_imports`, but not `unexpanded_invocations`, so
295 /// the returned declaration may actually change after expanding macros in the same module,
296 /// because of this fact we have glob overwriting (`select_glob_decl`). Consider using
297 /// `unexpanded_invocations` here and avoiding glob overwriting entirely, if it doesn't cause
298 /// code breakage in practice.
299 /// FIXME: relationship between this function and similar `DeclData::determined` is unclear.
300 pub(crate) fn determined_decl(&self) -> Option<Decl<'ra>> {
301 if self.non_glob_decl.is_some() {
302 self.non_glob_decl
303 } else if self.glob_decl.is_some() && self.single_imports.is_empty() {
304 self.glob_decl
305 } else {
306 None
307 }
301308 }
302309
303310 pub(crate) fn best_decl(&self) -> Option<Decl<'ra>> {
......@@ -482,41 +489,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
482489 orig_ident_span,
483490 warn_ambiguity,
484491 |this, resolution| {
485 if let Some(old_decl) = resolution.best_decl() {
486 assert_ne!(decl, old_decl);
487 assert!(!decl.warn_ambiguity.get());
488 if res == Res::Err && old_decl.res() != Res::Err {
489 // Do not override real declarations with `Res::Err`s from error recovery.
490 return Ok(());
491 }
492 match (old_decl.is_glob_import(), decl.is_glob_import()) {
493 (true, true) => {
494 resolution.glob_decl =
495 Some(this.select_glob_decl(old_decl, decl, warn_ambiguity));
496 }
497 (old_glob @ true, false) | (old_glob @ false, true) => {
498 let (glob_decl, non_glob_decl) =
499 if old_glob { (old_decl, decl) } else { (decl, old_decl) };
500 resolution.non_glob_decl = Some(non_glob_decl);
501 if let Some(old_glob_decl) = resolution.glob_decl
502 && old_glob_decl != glob_decl
503 {
504 resolution.glob_decl =
505 Some(this.select_glob_decl(old_glob_decl, glob_decl, false));
506 } else {
507 resolution.glob_decl = Some(glob_decl);
508 }
509 }
510 (false, false) => {
511 return Err(old_decl);
512 }
513 }
492 assert!(!decl.warn_ambiguity.get());
493 if decl.is_glob_import() {
494 resolution.glob_decl = Some(match resolution.glob_decl {
495 Some(old_decl) => this.select_glob_decl(
496 old_decl,
497 decl,
498 warn_ambiguity && resolution.non_glob_decl.is_none(),
499 ),
500 None => decl,
501 })
514502 } else {
515 if decl.is_glob_import() {
516 resolution.glob_decl = Some(decl);
517 } else {
518 resolution.non_glob_decl = Some(decl);
519 }
503 resolution.non_glob_decl = Some(match resolution.non_glob_decl {
504 Some(old_decl) => return Err(old_decl),
505 None => decl,
506 })
520507 }
521508
522509 Ok(())
......@@ -543,11 +530,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
543530 let resolution = &mut *self
544531 .resolution_or_default(module, key, orig_ident_span)
545532 .borrow_mut_unchecked();
546 let old_decl = resolution.binding();
533 let old_decl = resolution.determined_decl();
547534
548535 let t = f(self, resolution);
549536
550 if let Some(binding) = resolution.binding()
537 if let Some(binding) = resolution.determined_decl()
551538 && old_decl != Some(binding)
552539 {
553540 (binding, t, warn_ambiguity || old_decl.is_some())
......@@ -573,13 +560,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
573560 };
574561 if self.is_accessible_from(binding.vis(), scope) {
575562 let import_decl = self.new_import_decl(binding, *import);
576 let _ = self.try_plant_decl_into_local_module(
563 self.try_plant_decl_into_local_module(
577564 ident,
578565 orig_ident_span,
579566 key.ns,
580567 import_decl,
581568 warn_ambiguity,
582 );
569 )
570 .expect("planting a glob cannot fail");
583571 }
584572 }
585573
......@@ -598,6 +586,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
598586 self.per_ns(|this, ns| {
599587 let module = import.parent_scope.module;
600588 let ident = IdentKey::new(target);
589 // This can fail, dummies are inserted only in non-occupied slots.
601590 let _ = this.try_plant_decl_into_local_module(
602591 ident,
603592 target.span,
......@@ -1676,7 +1665,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16761665 .iter()
16771666 .filter_map(|(key, resolution)| {
16781667 let resolution = resolution.borrow();
1679 resolution.binding().map(|binding| (*key, binding, resolution.orig_ident_span))
1668 resolution.determined_decl().map(|decl| (*key, decl, resolution.orig_ident_span))
16801669 })
16811670 .collect::<Vec<_>>();
16821671 for (mut key, binding, orig_ident_span) in bindings {
......@@ -1692,15 +1681,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16921681 let import_decl = self.new_import_decl(binding, import);
16931682 let warn_ambiguity = self
16941683 .resolution(import.parent_scope.module, key)
1695 .and_then(|r| r.binding())
1684 .and_then(|r| r.determined_decl())
16961685 .is_some_and(|binding| binding.warn_ambiguity_recursive());
1697 let _ = self.try_plant_decl_into_local_module(
1686 self.try_plant_decl_into_local_module(
16981687 key.ident,
16991688 orig_ident_span,
17001689 key.ns,
17011690 import_decl,
17021691 warn_ambiguity,
1703 );
1692 )
1693 .expect("planting a glob cannot fail");
17041694 }
17051695 }
17061696
compiler/rustc_resolve/src/late.rs+36-20
......@@ -530,9 +530,8 @@ impl PathSource<'_, '_, '_> {
530530 },
531531 _ => "value",
532532 },
533 PathSource::ReturnTypeNotation
534 | PathSource::Delegation
535 | PathSource::ExternItemImpl => "function",
533 PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
534 PathSource::ExternItemImpl => "function or static",
536535 PathSource::PreciseCapturingArg(..) => "type or const parameter",
537536 PathSource::Macro => "macro",
538537 PathSource::Module => "module",
......@@ -625,7 +624,13 @@ impl PathSource<'_, '_, '_> {
625624 },
626625 PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
627626 PathSource::ExternItemImpl => {
628 matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..), _))
627 matches!(
628 res,
629 Res::Def(
630 DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Static { .. },
631 _
632 )
633 )
629634 }
630635 PathSource::PreciseCapturingArg(ValueNS) => {
631636 matches!(res, Res::Def(DefKind::ConstParam, _))
......@@ -1095,21 +1100,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
10951100 debug!("(resolving function) entering function");
10961101
10971102 if let FnKind::Fn(_, _, f) = fn_kind {
1098 for EiiImpl { node_id, eii_macro_path, known_eii_macro_resolution, .. } in &f.eii_impls
1099 {
1100 // See docs on the `known_eii_macro_resolution` field:
1101 // if we already know the resolution statically, don't bother resolving it.
1102 if let Some(target) = known_eii_macro_resolution {
1103 self.smart_resolve_path(
1104 *node_id,
1105 &None,
1106 &target.foreign_item,
1107 PathSource::ExternItemImpl,
1108 );
1109 } else {
1110 self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro);
1111 }
1112 }
1103 self.resolve_eii(&f.eii_impls);
11131104 }
11141105
11151106 // Create a value rib for the function.
......@@ -2905,7 +2896,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
29052896 self.parent_scope.module = orig_module;
29062897 }
29072898
2908 ItemKind::Static(box ast::StaticItem { ident, ty, expr, define_opaque, .. }) => {
2899 ItemKind::Static(box ast::StaticItem {
2900 ident,
2901 ty,
2902 expr,
2903 define_opaque,
2904 eii_impls,
2905 ..
2906 }) => {
29092907 self.with_static_rib(def_kind, |this| {
29102908 this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
29112909 this.visit_ty(ty);
......@@ -2917,6 +2915,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
29172915 }
29182916 });
29192917 self.resolve_define_opaques(define_opaque);
2918 self.resolve_eii(&eii_impls);
29202919 }
29212920
29222921 ItemKind::Const(box ast::ConstItem {
......@@ -5496,6 +5495,23 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
54965495 }
54975496 }
54985497 }
5498
5499 fn resolve_eii(&mut self, eii_impls: &[EiiImpl]) {
5500 for EiiImpl { node_id, eii_macro_path, known_eii_macro_resolution, .. } in eii_impls {
5501 // See docs on the `known_eii_macro_resolution` field:
5502 // if we already know the resolution statically, don't bother resolving it.
5503 if let Some(target) = known_eii_macro_resolution {
5504 self.smart_resolve_path(
5505 *node_id,
5506 &None,
5507 &target.foreign_item,
5508 PathSource::ExternItemImpl,
5509 );
5510 } else {
5511 self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro);
5512 }
5513 }
5514 }
54995515}
55005516
55015517/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
compiler/rustc_resolve/src/lib.rs+5-3
......@@ -1101,9 +1101,11 @@ impl<'ra> DeclData<'ra> {
11011101 !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
11021102 }
11031103
1104 // Its purpose is to postpone the determination of a single binding because
1105 // we can't predict whether it will be overwritten by recently expanded macros.
1106 // FIXME: How can we integrate it with the `update_resolution`?
1104 /// Returns whether this declaration may be shadowed or overwritten by something else later.
1105 /// FIXME: this function considers `unexpanded_invocations`, but not `single_imports`, so
1106 /// the declaration may not be as "determined" as we think.
1107 /// FIXME: relationship between this function and similar `NameResolution::determined_decl`
1108 /// is unclear.
11071109 fn determined(&self) -> bool {
11081110 match &self.kind {
11091111 DeclKind::Import { source_decl, import, .. } if import.is_glob() => {
compiler/rustc_resolve/src/macros.rs+37-16
......@@ -712,34 +712,55 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
712712 feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
713713 }
714714
715 let diagnostic_attributes: &[(Symbol, bool)] = &[
716 (sym::on_unimplemented, true),
717 (sym::do_not_recommend, true),
718 (sym::on_move, true),
719 (sym::on_const, self.tcx.features().diagnostic_on_const()),
720 (sym::on_unknown, self.tcx.features().diagnostic_on_unknown()),
715 const DIAGNOSTIC_ATTRIBUTES: &[(Symbol, Option<Symbol>)] = &[
716 (sym::on_unimplemented, None),
717 (sym::do_not_recommend, None),
718 (sym::on_move, Some(sym::diagnostic_on_move)),
719 (sym::on_const, Some(sym::diagnostic_on_const)),
720 (sym::on_unknown, Some(sym::diagnostic_on_unknown)),
721721 ];
722722
723723 if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
724724 && let [namespace, attribute, ..] = &*path.segments
725725 && namespace.ident.name == sym::diagnostic
726 && !diagnostic_attributes
727 .iter()
728 .any(|(attr, stable)| *stable && attribute.ident.name == *attr)
726 && !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| {
727 attribute.ident.name == *attr
728 && feature.is_none_or(|f| self.tcx.features().enabled(f))
729 })
729730 {
731 let name = attribute.ident.name;
730732 let span = attribute.span();
731 let candidates = diagnostic_attributes
732 .iter()
733 .filter_map(|(sym, stable)| stable.then_some(*sym))
734 .collect::<Vec<_>>();
735 let typo = find_best_match_for_name(&candidates, attribute.ident.name, Some(5))
736 .map(|typo_name| errors::UnknownDiagnosticAttributeTypoSugg { span, typo_name });
733
734 let help = 'help: {
735 if self.tcx.sess.is_nightly_build() {
736 for (attr, feature) in DIAGNOSTIC_ATTRIBUTES {
737 if let Some(feature) = *feature
738 && *attr == name
739 {
740 break 'help Some(errors::UnknownDiagnosticAttributeHelp::UseFeature {
741 feature,
742 });
743 }
744 }
745 }
746
747 let candidates = DIAGNOSTIC_ATTRIBUTES
748 .iter()
749 .filter_map(|(attr, feature)| {
750 feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr)
751 })
752 .collect::<Vec<_>>();
753
754 find_best_match_for_name(&candidates, name, None).map(|typo_name| {
755 errors::UnknownDiagnosticAttributeHelp::Typo { span, typo_name }
756 })
757 };
737758
738759 self.tcx.sess.psess.buffer_lint(
739760 UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
740761 span,
741762 node_id,
742 errors::UnknownDiagnosticAttribute { typo },
763 errors::UnknownDiagnosticAttribute { help },
743764 );
744765 }
745766
compiler/rustc_trait_selection/src/traits/mod.rs+5-4
......@@ -34,8 +34,8 @@ use rustc_middle::query::Providers;
3434use rustc_middle::span_bug;
3535use rustc_middle::ty::error::{ExpectedFound, TypeError};
3636use rustc_middle::ty::{
37 self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
38 TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Upcast,
37 self, Clause, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder,
38 TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Upcast,
3939};
4040use rustc_span::Span;
4141use rustc_span::def_id::DefId;
......@@ -177,9 +177,10 @@ pub enum TraitQueryMode {
177177}
178178
179179/// Creates predicate obligations from the generic bounds.
180#[instrument(level = "debug", skip(cause, param_env))]
180#[instrument(level = "debug", skip(cause, param_env, normalize_predicate))]
181181pub fn predicates_for_generics<'tcx>(
182182 cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
183 mut normalize_predicate: impl FnMut(Clause<'tcx>) -> Clause<'tcx>,
183184 param_env: ty::ParamEnv<'tcx>,
184185 generic_bounds: ty::InstantiatedPredicates<'tcx>,
185186) -> impl Iterator<Item = PredicateObligation<'tcx>> {
......@@ -187,7 +188,7 @@ pub fn predicates_for_generics<'tcx>(
187188 cause: cause(idx, span),
188189 recursion_depth: 0,
189190 param_env,
190 predicate: clause.as_predicate(),
191 predicate: normalize_predicate(clause).as_predicate(),
191192 })
192193}
193194
compiler/rustc_trait_selection/src/traits/specialize/mod.rs+11-8
......@@ -185,12 +185,13 @@ fn fulfill_implication<'tcx>(
185185 // Now check that the source trait ref satisfies all the where clauses of the target impl.
186186 // This is not just for correctness; we also need this to constrain any params that may
187187 // only be referenced via projection predicates.
188 let predicates = ocx.normalize(
189 cause,
188 let predicates = infcx.tcx.predicates_of(target_impl).instantiate(infcx.tcx, target_args);
189 let obligations = predicates_for_generics(
190 |_, _| cause.clone(),
191 |pred| ocx.normalize(cause, param_env, pred),
190192 param_env,
191 infcx.tcx.predicates_of(target_impl).instantiate(infcx.tcx, target_args),
193 predicates,
192194 );
193 let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates);
194195 ocx.register_obligations(obligations);
195196
196197 let errors = ocx.evaluate_obligations_error_on_ambiguity();
......@@ -315,12 +316,14 @@ pub(super) fn specializes(
315316 // Now check that the source trait ref satisfies all the where clauses of the target impl.
316317 // This is not just for correctness; we also need this to constrain any params that may
317318 // only be referenced via projection predicates.
318 let predicates = ocx.normalize(
319 cause,
319 let predicates =
320 infcx.tcx.predicates_of(parent_impl_def_id).instantiate(infcx.tcx, parent_args);
321 let obligations = predicates_for_generics(
322 |_, _| cause.clone(),
323 |pred| ocx.normalize(cause, param_env, pred),
320324 param_env,
321 infcx.tcx.predicates_of(parent_impl_def_id).instantiate(infcx.tcx, parent_args),
325 predicates,
322326 );
323 let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates);
324327 ocx.register_obligations(obligations);
325328
326329 let errors = ocx.evaluate_obligations_error_on_ambiguity();
library/core/src/cell/lazy.rs+2-1
......@@ -346,7 +346,8 @@ impl<T, F: FnOnce() -> T> DerefMut for LazyCell<T, F> {
346346}
347347
348348#[stable(feature = "lazy_cell", since = "1.80.0")]
349impl<T: Default> Default for LazyCell<T> {
349#[rustc_const_unstable(feature = "const_default", issue = "143894")]
350impl<T: Default> const Default for LazyCell<T> {
350351 /// Creates a new lazy value using `Default` as the initializing function.
351352 #[inline]
352353 fn default() -> LazyCell<T> {
library/core/src/num/int_macros.rs+4-6
......@@ -213,14 +213,13 @@ macro_rules! int_impl {
213213 /// # Examples
214214 ///
215215 /// ```
216 /// #![feature(int_lowest_highest_one)]
217 ///
218216 #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".highest_one(), None);")]
219217 #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".highest_one(), Some(0));")]
220218 #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".highest_one(), Some(4));")]
221219 #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".highest_one(), Some(4));")]
222220 /// ```
223 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
221 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
222 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
224223 #[must_use = "this returns the result of the operation, \
225224 without modifying the original"]
226225 #[inline(always)]
......@@ -234,14 +233,13 @@ macro_rules! int_impl {
234233 /// # Examples
235234 ///
236235 /// ```
237 /// #![feature(int_lowest_highest_one)]
238 ///
239236 #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".lowest_one(), None);")]
240237 #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".lowest_one(), Some(0));")]
241238 #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".lowest_one(), Some(4));")]
242239 #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".lowest_one(), Some(0));")]
243240 /// ```
244 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
241 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
242 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
245243 #[must_use = "this returns the result of the operation, \
246244 without modifying the original"]
247245 #[inline(always)]
library/core/src/num/nonzero.rs+6-9
......@@ -711,8 +711,6 @@ macro_rules! nonzero_integer {
711711 /// # Examples
712712 ///
713713 /// ```
714 /// #![feature(int_lowest_highest_one)]
715 ///
716714 /// # use core::num::NonZero;
717715 /// # fn main() { test().unwrap(); }
718716 /// # fn test() -> Option<()> {
......@@ -722,7 +720,8 @@ macro_rules! nonzero_integer {
722720 /// # Some(())
723721 /// # }
724722 /// ```
725 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
723 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
724 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
726725 #[must_use = "this returns the result of the operation, \
727726 without modifying the original"]
728727 #[inline(always)]
......@@ -735,8 +734,6 @@ macro_rules! nonzero_integer {
735734 /// # Examples
736735 ///
737736 /// ```
738 /// #![feature(int_lowest_highest_one)]
739 ///
740737 /// # use core::num::NonZero;
741738 /// # fn main() { test().unwrap(); }
742739 /// # fn test() -> Option<()> {
......@@ -746,7 +743,8 @@ macro_rules! nonzero_integer {
746743 /// # Some(())
747744 /// # }
748745 /// ```
749 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
746 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
747 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
750748 #[must_use = "this returns the result of the operation, \
751749 without modifying the original"]
752750 #[inline(always)]
......@@ -1948,8 +1946,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
19481946 /// # Examples
19491947 ///
19501948 /// ```
1951 /// #![feature(uint_bit_width)]
1952 ///
19531949 /// # use core::num::NonZero;
19541950 /// #
19551951 /// # fn main() { test().unwrap(); }
......@@ -1960,7 +1956,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
19601956 /// # Some(())
19611957 /// # }
19621958 /// ```
1963 #[unstable(feature = "uint_bit_width", issue = "142326")]
1959 #[stable(feature = "uint_bit_width", since = "CURRENT_RUSTC_VERSION")]
1960 #[rustc_const_stable(feature = "uint_bit_width", since = "CURRENT_RUSTC_VERSION")]
19641961 #[must_use = "this returns the result of the operation, \
19651962 without modifying the original"]
19661963 #[inline(always)]
library/core/src/num/uint_macros.rs+6-9
......@@ -232,14 +232,13 @@ macro_rules! uint_impl {
232232 /// # Examples
233233 ///
234234 /// ```
235 /// #![feature(uint_bit_width)]
236 ///
237235 #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".bit_width(), 0);")]
238236 #[doc = concat!("assert_eq!(0b111_", stringify!($SelfT), ".bit_width(), 3);")]
239237 #[doc = concat!("assert_eq!(0b1110_", stringify!($SelfT), ".bit_width(), 4);")]
240238 #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.bit_width(), ", stringify!($BITS), ");")]
241239 /// ```
242 #[unstable(feature = "uint_bit_width", issue = "142326")]
240 #[stable(feature = "uint_bit_width", since = "CURRENT_RUSTC_VERSION")]
241 #[rustc_const_stable(feature = "uint_bit_width", since = "CURRENT_RUSTC_VERSION")]
243242 #[must_use = "this returns the result of the operation, \
244243 without modifying the original"]
245244 #[inline(always)]
......@@ -293,14 +292,13 @@ macro_rules! uint_impl {
293292 /// # Examples
294293 ///
295294 /// ```
296 /// #![feature(int_lowest_highest_one)]
297 ///
298295 #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".highest_one(), None);")]
299296 #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".highest_one(), Some(0));")]
300297 #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".highest_one(), Some(4));")]
301298 #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".highest_one(), Some(4));")]
302299 /// ```
303 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
300 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
301 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
304302 #[must_use = "this returns the result of the operation, \
305303 without modifying the original"]
306304 #[inline(always)]
......@@ -317,14 +315,13 @@ macro_rules! uint_impl {
317315 /// # Examples
318316 ///
319317 /// ```
320 /// #![feature(int_lowest_highest_one)]
321 ///
322318 #[doc = concat!("assert_eq!(0b0_", stringify!($SelfT), ".lowest_one(), None);")]
323319 #[doc = concat!("assert_eq!(0b1_", stringify!($SelfT), ".lowest_one(), Some(0));")]
324320 #[doc = concat!("assert_eq!(0b1_0000_", stringify!($SelfT), ".lowest_one(), Some(4));")]
325321 #[doc = concat!("assert_eq!(0b1_1111_", stringify!($SelfT), ".lowest_one(), Some(0));")]
326322 /// ```
327 #[unstable(feature = "int_lowest_highest_one", issue = "145203")]
323 #[stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
324 #[rustc_const_stable(feature = "int_lowest_highest_one", since = "CURRENT_RUSTC_VERSION")]
328325 #[must_use = "this returns the result of the operation, \
329326 without modifying the original"]
330327 #[inline(always)]
library/core/src/ops/deref.rs+1
......@@ -293,6 +293,7 @@ impl<T: ?Sized> const DerefMut for &mut T {
293293/// unchanged.
294294#[unstable(feature = "deref_pure_trait", issue = "87121")]
295295#[lang = "deref_pure"]
296#[rustc_dyn_incompatible_trait]
296297pub unsafe trait DerefPure: PointeeSized {}
297298
298299#[unstable(feature = "deref_pure_trait", issue = "87121")]
library/coretests/tests/lib.rs-2
......@@ -66,7 +66,6 @@
6666#![feature(hasher_prefixfree_extras)]
6767#![feature(hashmap_internals)]
6868#![feature(int_from_ascii)]
69#![feature(int_lowest_highest_one)]
7069#![feature(int_roundings)]
7170#![feature(ip)]
7271#![feature(is_ascii_octdigit)]
......@@ -120,7 +119,6 @@
120119#![feature(try_find)]
121120#![feature(try_trait_v2)]
122121#![feature(type_info)]
123#![feature(uint_bit_width)]
124122#![feature(uint_carryless_mul)]
125123#![feature(uint_gather_scatter_bits)]
126124#![feature(unicode_internals)]
library/std/src/sync/lazy_lock.rs+2-1
......@@ -375,7 +375,8 @@ impl<T, F: FnOnce() -> T> DerefMut for LazyLock<T, F> {
375375}
376376
377377#[stable(feature = "lazy_cell", since = "1.80.0")]
378impl<T: Default> Default for LazyLock<T> {
378#[rustc_const_unstable(feature = "const_default", issue = "143894")]
379impl<T: Default> const Default for LazyLock<T> {
379380 /// Creates a new lazy value using `Default` as the initializing function.
380381 #[inline]
381382 fn default() -> LazyLock<T> {
library/std/src/sys/thread/unix.rs+1
......@@ -155,6 +155,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
155155 target_os = "aix",
156156 target_vendor = "apple",
157157 target_os = "cygwin",
158 target_os = "wasi",
158159 ) => {
159160 #[allow(unused_assignments)]
160161 #[allow(unused_mut)]
library/std/tests/sync/lazy_lock.rs+9
......@@ -33,6 +33,15 @@ fn lazy_default() {
3333 assert_eq!(CALLED.load(SeqCst), 1);
3434}
3535
36#[test]
37fn const_lazy_default() {
38 // using Box as it cannot be initialized in const contexts
39 const X: LazyLock<Box<u8>> = <_>::default();
40 const Y: LazyCell<Box<u8>> = <_>::default();
41 assert_eq!(**X, 0);
42 assert_eq!(**Y, 0);
43}
44
3645#[test]
3746#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
3847fn sync_lazy_new() {
library/std/tests/sync/lib.rs+2
......@@ -1,3 +1,5 @@
1#![feature(const_default)]
2#![feature(const_trait_impl)]
13#![feature(mapped_lock_guards)]
24#![feature(mpmc_channel)]
35#![feature(oneshot_channel)]
library/std/tests/thread.rs-1
......@@ -85,7 +85,6 @@ fn thread_local_hygeiene() {
8585 target_env = "sgx",
8686 target_os = "solid_asp3",
8787 target_os = "teeos",
88 target_os = "wasi"
8988 ),
9089 should_panic
9190)]
src/bootstrap/src/core/build_steps/dist.rs+2-2
......@@ -636,9 +636,9 @@ impl Step for Rustc {
636636 let page_src = file_entry.path();
637637 let page_dst = man_dst.join(file_entry.file_name());
638638 let src_text = t!(std::fs::read_to_string(&page_src));
639 let new_text = src_text.replace("<INSERT VERSION HERE>", &builder.version);
639 let version = builder.rust_info().version(builder.build, &builder.version);
640 let new_text = src_text.replace("<INSERT VERSION HERE>", &version);
640641 t!(std::fs::write(&page_dst, &new_text));
641 t!(fs::copy(&page_src, &page_dst));
642642 }
643643
644644 // Debugger scripts
src/bootstrap/src/core/build_steps/test.rs+4
......@@ -2334,6 +2334,10 @@ Please disable assertions with `rust.debug-assertions = false`.
23342334 cmd.arg("--verbose");
23352335 }
23362336
2337 if builder.config.cmd.verbose_run_make_subprocess_output() {
2338 cmd.arg("--verbose-run-make-subprocess-output");
2339 }
2340
23372341 if builder.config.rustc_debug_assertions {
23382342 cmd.arg("--with-rustc-debug-assertions");
23392343 }
src/bootstrap/src/core/config/flags.rs+13
......@@ -422,6 +422,10 @@ pub enum Subcommand {
422422 #[arg(long)]
423423 /// don't capture stdout/stderr of tests
424424 no_capture: bool,
425 #[arg(long, default_value_t = true, action = clap::ArgAction::Set, default_missing_value = "true", num_args = 0..=1, require_equals = true)]
426 /// whether to show verbose subprocess output for run-make tests;
427 /// set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)
428 verbose_run_make_subprocess_output: bool,
425429 #[arg(long)]
426430 /// Use a different codegen backend when running tests.
427431 test_codegen_backend: Option<CodegenBackendKind>,
......@@ -631,6 +635,15 @@ impl Subcommand {
631635 }
632636 }
633637
638 pub fn verbose_run_make_subprocess_output(&self) -> bool {
639 match *self {
640 Subcommand::Test { verbose_run_make_subprocess_output, .. } => {
641 verbose_run_make_subprocess_output
642 }
643 _ => true,
644 }
645 }
646
634647 pub fn rustfix_coverage(&self) -> bool {
635648 match *self {
636649 Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage,
src/bootstrap/src/utils/change_tracker.rs+5
......@@ -621,4 +621,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
621621 severity: ChangeSeverity::Info,
622622 summary: "`x.py` stopped accepting partial argument names. Use full names to avoid errors.",
623623 },
624 ChangeInfo {
625 change_id: 154587,
626 severity: ChangeSeverity::Info,
627 summary: "New `--verbose-run-make-subprocess-output` flag for `x.py test` (defaults to true). Set `--verbose-run-make-subprocess-output=false` to suppress verbose subprocess output for passing run-make tests when using `--no-capture`.",
628 },
624629];
src/doc/rustc-dev-guide/src/tests/compiletest.md+9
......@@ -460,6 +460,15 @@ However, revisions or building auxiliary via directives are not currently suppor
460460`rmake.rs` and `run-make-support` may *not* use any nightly/unstable features,
461461as they must be compilable by a stage 0 rustc that may be a beta or even stable rustc.
462462
463By default, run-make tests print each subprocess command and its stdout/stderr.
464When running with `--no-capture` on `panic=abort` test suites (such as `cg_clif`),
465this can flood the terminal. Omit `--verbose-run-make-subprocess-output` to
466suppress this output for passing tests — failing tests always print regardless:
467
468```bash
469./x test tests/run-make --no-capture --verbose-run-make-subprocess-output=false
470```
471
463472#### Quickly check if `rmake.rs` tests can be compiled
464473
465474You can quickly check if `rmake.rs` tests can be compiled without having to
src/etc/completions/x.fish+2
......@@ -420,6 +420,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-sepa
420420complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
421421complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
422422complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
423complete -c x -n "__fish_x_using_subcommand test" -l verbose-run-make-subprocess-output -d 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)' -r -f -a "{true\t'',false\t''}"
423424complete -c x -n "__fish_x_using_subcommand test" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
424425complete -c x -n "__fish_x_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F
425426complete -c x -n "__fish_x_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
......@@ -473,6 +474,7 @@ complete -c x -n "__fish_x_using_subcommand t" -l extra-checks -d 'comma-separat
473474complete -c x -n "__fish_x_using_subcommand t" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
474475complete -c x -n "__fish_x_using_subcommand t" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
475476complete -c x -n "__fish_x_using_subcommand t" -l run -d 'whether to execute run-* tests' -r
477complete -c x -n "__fish_x_using_subcommand t" -l verbose-run-make-subprocess-output -d 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)' -r -f -a "{true\t'',false\t''}"
476478complete -c x -n "__fish_x_using_subcommand t" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
477479complete -c x -n "__fish_x_using_subcommand t" -l config -d 'TOML configuration file for build' -r -F
478480complete -c x -n "__fish_x_using_subcommand t" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
src/etc/completions/x.ps1+2
......@@ -487,6 +487,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
487487 [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
488488 [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
489489 [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
490 [CompletionResult]::new('--verbose-run-make-subprocess-output', '--verbose-run-make-subprocess-output', [CompletionResultType]::ParameterName, 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)')
490491 [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
491492 [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
492493 [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
......@@ -547,6 +548,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
547548 [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
548549 [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
549550 [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
551 [CompletionResult]::new('--verbose-run-make-subprocess-output', '--verbose-run-make-subprocess-output', [CompletionResultType]::ParameterName, 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)')
550552 [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
551553 [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
552554 [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
src/etc/completions/x.py.fish+2
......@@ -420,6 +420,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comm
420420complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
421421complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
422422complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
423complete -c x.py -n "__fish_x.py_using_subcommand test" -l verbose-run-make-subprocess-output -d 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)' -r -f -a "{true\t'',false\t''}"
423424complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
424425complete -c x.py -n "__fish_x.py_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F
425426complete -c x.py -n "__fish_x.py_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
......@@ -473,6 +474,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand t" -l extra-checks -d 'comma-s
473474complete -c x.py -n "__fish_x.py_using_subcommand t" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
474475complete -c x.py -n "__fish_x.py_using_subcommand t" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
475476complete -c x.py -n "__fish_x.py_using_subcommand t" -l run -d 'whether to execute run-* tests' -r
477complete -c x.py -n "__fish_x.py_using_subcommand t" -l verbose-run-make-subprocess-output -d 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)' -r -f -a "{true\t'',false\t''}"
476478complete -c x.py -n "__fish_x.py_using_subcommand t" -l test-codegen-backend -d 'Use a different codegen backend when running tests' -r
477479complete -c x.py -n "__fish_x.py_using_subcommand t" -l config -d 'TOML configuration file for build' -r -F
478480complete -c x.py -n "__fish_x.py_using_subcommand t" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
src/etc/completions/x.py.ps1+2
......@@ -487,6 +487,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
487487 [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
488488 [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
489489 [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
490 [CompletionResult]::new('--verbose-run-make-subprocess-output', '--verbose-run-make-subprocess-output', [CompletionResultType]::ParameterName, 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)')
490491 [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
491492 [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
492493 [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
......@@ -547,6 +548,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
547548 [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
548549 [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
549550 [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
551 [CompletionResult]::new('--verbose-run-make-subprocess-output', '--verbose-run-make-subprocess-output', [CompletionResultType]::ParameterName, 'whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)')
550552 [CompletionResult]::new('--test-codegen-backend', '--test-codegen-backend', [CompletionResultType]::ParameterName, 'Use a different codegen backend when running tests')
551553 [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
552554 [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
src/etc/completions/x.py.sh+10-2
......@@ -4638,7 +4638,7 @@ _x.py() {
46384638 return 0
46394639 ;;
46404640 x.py__test)
4641 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
4641 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose-run-make-subprocess-output --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
46424642 if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
46434643 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
46444644 return 0
......@@ -4668,6 +4668,10 @@ _x.py() {
46684668 COMPREPLY=($(compgen -f "${cur}"))
46694669 return 0
46704670 ;;
4671 --verbose-run-make-subprocess-output)
4672 COMPREPLY=($(compgen -W "true false" -- "${cur}"))
4673 return 0
4674 ;;
46714675 --test-codegen-backend)
46724676 COMPREPLY=($(compgen -f "${cur}"))
46734677 return 0
......@@ -4852,7 +4856,7 @@ _x.py() {
48524856 return 0
48534857 ;;
48544858 x.py__test)
4855 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
4859 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose-run-make-subprocess-output --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
48564860 if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
48574861 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
48584862 return 0
......@@ -4882,6 +4886,10 @@ _x.py() {
48824886 COMPREPLY=($(compgen -f "${cur}"))
48834887 return 0
48844888 ;;
4889 --verbose-run-make-subprocess-output)
4890 COMPREPLY=($(compgen -W "true false" -- "${cur}"))
4891 return 0
4892 ;;
48854893 --test-codegen-backend)
48864894 COMPREPLY=($(compgen -f "${cur}"))
48874895 return 0
src/etc/completions/x.py.zsh+2
......@@ -488,6 +488,7 @@ _arguments "${_arguments_options[@]}" : \
488488'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
489489'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
490490'--run=[whether to execute run-* tests]:auto | always | never:_default' \
491'--verbose-run-make-subprocess-output=[whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)]' \
491492'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
492493'--config=[TOML configuration file for build]:FILE:_files' \
493494'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
......@@ -550,6 +551,7 @@ _arguments "${_arguments_options[@]}" : \
550551'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
551552'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
552553'--run=[whether to execute run-* tests]:auto | always | never:_default' \
554'--verbose-run-make-subprocess-output=[whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)]' \
553555'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
554556'--config=[TOML configuration file for build]:FILE:_files' \
555557'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
src/etc/completions/x.sh+10-2
......@@ -4638,7 +4638,7 @@ _x() {
46384638 return 0
46394639 ;;
46404640 x__test)
4641 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
4641 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose-run-make-subprocess-output --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
46424642 if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
46434643 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
46444644 return 0
......@@ -4668,6 +4668,10 @@ _x() {
46684668 COMPREPLY=($(compgen -f "${cur}"))
46694669 return 0
46704670 ;;
4671 --verbose-run-make-subprocess-output)
4672 COMPREPLY=($(compgen -W "true false" -- "${cur}"))
4673 return 0
4674 ;;
46714675 --test-codegen-backend)
46724676 COMPREPLY=($(compgen -f "${cur}"))
46734677 return 0
......@@ -4852,7 +4856,7 @@ _x() {
48524856 return 0
48534857 ;;
48544858 x__test)
4855 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
4859 opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose-run-make-subprocess-output --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
48564860 if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
48574861 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
48584862 return 0
......@@ -4882,6 +4886,10 @@ _x() {
48824886 COMPREPLY=($(compgen -f "${cur}"))
48834887 return 0
48844888 ;;
4889 --verbose-run-make-subprocess-output)
4890 COMPREPLY=($(compgen -W "true false" -- "${cur}"))
4891 return 0
4892 ;;
48854893 --test-codegen-backend)
48864894 COMPREPLY=($(compgen -f "${cur}"))
48874895 return 0
src/etc/completions/x.zsh+2
......@@ -488,6 +488,7 @@ _arguments "${_arguments_options[@]}" : \
488488'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
489489'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
490490'--run=[whether to execute run-* tests]:auto | always | never:_default' \
491'--verbose-run-make-subprocess-output=[whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)]' \
491492'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
492493'--config=[TOML configuration file for build]:FILE:_files' \
493494'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
......@@ -550,6 +551,7 @@ _arguments "${_arguments_options[@]}" : \
550551'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
551552'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
552553'--run=[whether to execute run-* tests]:auto | always | never:_default' \
554'--verbose-run-make-subprocess-output=[whether to show verbose subprocess output for run-make tests; set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture)]' \
553555'--test-codegen-backend=[Use a different codegen backend when running tests]:TEST_CODEGEN_BACKEND:_default' \
554556'--config=[TOML configuration file for build]:FILE:_files' \
555557'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
src/tools/clippy/clippy_utils/src/ast_utils/mod.rs+4
......@@ -339,6 +339,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
339339 expr: le,
340340 safety: ls,
341341 define_opaque: _,
342 eii_impls: _,
342343 }),
343344 Static(box StaticItem {
344345 ident: ri,
......@@ -347,6 +348,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
347348 expr: re,
348349 safety: rs,
349350 define_opaque: _,
351 eii_impls: _,
350352 }),
351353 ) => eq_id(*li, *ri) && lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_deref(), re.as_deref()),
352354 (
......@@ -540,6 +542,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
540542 expr: le,
541543 safety: ls,
542544 define_opaque: _,
545 eii_impls: _,
543546 }),
544547 Static(box StaticItem {
545548 ident: ri,
......@@ -548,6 +551,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
548551 expr: re,
549552 safety: rs,
550553 define_opaque: _,
554 eii_impls: _,
551555 }),
552556 ) => eq_id(*li, *ri) && eq_ty(lt, rt) && lm == rm && eq_expr_opt(le.as_deref(), re.as_deref()) && ls == rs,
553557 (
src/tools/compiletest/src/common.rs+4
......@@ -603,6 +603,10 @@ pub(crate) struct Config {
603603 /// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.
604604 pub(crate) verbose: bool,
605605
606 /// Whether to enable verbose subprocess output for run-make tests.
607 /// Set to false to suppress output for passing tests (e.g. for cg_clif with --no-capture).
608 pub verbose_run_make_subprocess_output: bool,
609
606610 /// Where to find the remote test client process, if we're using it.
607611 ///
608612 /// Note: this is *only* used for target platform executables created by `run-make` test
src/tools/compiletest/src/lib.rs+7
......@@ -134,6 +134,11 @@ fn parse_config(args: Vec<String>) -> Config {
134134 )
135135 .optflag("", "optimize-tests", "run tests with optimizations enabled")
136136 .optflag("", "verbose", "run tests verbosely, showing all output")
137 .optflag(
138 "",
139 "verbose-run-make-subprocess-output",
140 "show verbose subprocess output for successful run-make tests",
141 )
137142 .optflag(
138143 "",
139144 "bless",
......@@ -471,6 +476,8 @@ fn parse_config(args: Vec<String>) -> Config {
471476 adb_test_dir,
472477 adb_device_status,
473478 verbose: matches.opt_present("verbose"),
479 verbose_run_make_subprocess_output: matches
480 .opt_present("verbose-run-make-subprocess-output"),
474481 only_modified: matches.opt_present("only-modified"),
475482 remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from),
476483 compare_mode,
src/tools/compiletest/src/runtest/run_make.rs+7
......@@ -231,6 +231,13 @@ impl TestCx<'_> {
231231 }
232232
233233 // Guard against externally-set env vars.
234 // Set env var to enable verbose output for successful commands.
235 // Only set when --verbose-run-make-subprocess-output is passed.
236 cmd.env_remove("__RMAKE_VERBOSE_SUBPROCESS_OUTPUT");
237 if self.config.verbose_run_make_subprocess_output {
238 cmd.env("__RMAKE_VERBOSE_SUBPROCESS_OUTPUT", "1");
239 }
240
234241 cmd.env_remove("__RUSTC_DEBUG_ASSERTIONS_ENABLED");
235242 if self.config.with_rustc_debug_assertions {
236243 // Used for `run_make_support::env::rustc_debug_assertions_enabled`.
src/tools/compiletest/src/rustdoc_gui_test.rs+1
......@@ -109,6 +109,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
109109 adb_test_dir: Default::default(),
110110 adb_device_status: Default::default(),
111111 verbose: Default::default(),
112 verbose_run_make_subprocess_output: Default::default(),
112113 remote_test_client: Default::default(),
113114 compare_mode: Default::default(),
114115 rustfix_coverage: Default::default(),
src/tools/run-make-support/src/util.rs+11-2
......@@ -4,7 +4,7 @@ use crate::command::{Command, CompletedProcess};
44use crate::env::env_var;
55use crate::path_helpers::cwd;
66
7pub(crate) fn verbose_print_command(cmd: &Command, output: &CompletedProcess) {
7fn print_command_output(cmd: &Command, output: &CompletedProcess) {
88 cmd.inspect(|std_cmd| {
99 eprintln!("{std_cmd:?}");
1010 });
......@@ -16,6 +16,15 @@ pub(crate) fn verbose_print_command(cmd: &Command, output: &CompletedProcess) {
1616 }
1717}
1818
19pub(crate) fn verbose_print_command(cmd: &Command, output: &CompletedProcess) {
20 // Only prints when `--verbose-run-make-subprocess-output` is active (env var set),
21 // so that passing tests don't flood the terminal when using `--no-capture`.
22 if std::env::var_os("__RMAKE_VERBOSE_SUBPROCESS_OUTPUT").is_none() {
23 return;
24 }
25 print_command_output(cmd, output);
26}
27
1928/// If a given [`Command`] failed (as indicated by its [`CompletedProcess`]), verbose print the
2029/// executed command, failure location, output status and stdout/stderr, and abort the process with
2130/// exit code `1`.
......@@ -29,7 +38,7 @@ pub(crate) fn handle_failed_output(
2938 } else {
3039 eprintln!("command failed at line {caller_line_number}");
3140 }
32 verbose_print_command(cmd, &output);
41 print_command_output(cmd, &output);
3342 std::process::exit(1)
3443}
3544
tests/codegen-llvm/inject-autocast.rs created+93
......@@ -0,0 +1,93 @@
1//@ compile-flags: -C opt-level=0 -C target-feature=+kl,+avx512vp2intersect,+avx512vl,+avxneconvert
2//@ only-x86_64
3
4#![feature(link_llvm_intrinsics, abi_unadjusted, simd_ffi, portable_simd)]
5#![crate_type = "lib"]
6
7use std::simd::{f32x4, i16x8, i64x2};
8
9#[repr(C, packed)]
10pub struct Bar(u32, i64x2, i64x2, i64x2, i64x2, i64x2, i64x2);
11// CHECK: %Bar = type <{ i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> }>
12
13// CHECK-LABEL: @struct_autocast
14#[no_mangle]
15pub unsafe fn struct_autocast(key_metadata: u32, key: i64x2) -> Bar {
16 extern "unadjusted" {
17 #[link_name = "llvm.x86.encodekey128"]
18 fn foo(key_metadata: u32, key: i64x2) -> Bar;
19 }
20
21 // CHECK: [[A:%[0-9]+]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 {{.*}}, <2 x i64> {{.*}})
22 // CHECK: [[B:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 0
23 // CHECK: [[C:%[0-9]+]] = insertvalue %Bar poison, i32 [[B]], 0
24 // CHECK: [[D:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 1
25 // CHECK: [[E:%[0-9]+]] = insertvalue %Bar [[C]], <2 x i64> [[D]], 1
26 // CHECK: [[F:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 2
27 // CHECK: [[G:%[0-9]+]] = insertvalue %Bar [[E]], <2 x i64> [[F]], 2
28 // CHECK: [[H:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 3
29 // CHECK: [[I:%[0-9]+]] = insertvalue %Bar [[G]], <2 x i64> [[H]], 3
30 // CHECK: [[J:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 4
31 // CHECK: [[K:%[0-9]+]] = insertvalue %Bar [[I]], <2 x i64> [[J]], 4
32 // CHECK: [[L:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 5
33 // CHECK: [[M:%[0-9]+]] = insertvalue %Bar [[K]], <2 x i64> [[L]], 5
34 // CHECK: [[N:%[0-9]+]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[A]], 6
35 // CHECK: insertvalue %Bar [[M]], <2 x i64> [[N]], 6
36 foo(key_metadata, key)
37}
38
39// CHECK-LABEL: @struct_with_i1_vector_autocast
40#[no_mangle]
41pub unsafe fn struct_with_i1_vector_autocast(a: i64x2, b: i64x2) -> (u8, u8) {
42 extern "unadjusted" {
43 #[link_name = "llvm.x86.avx512.vp2intersect.q.128"]
44 fn foo(a: i64x2, b: i64x2) -> (u8, u8);
45 }
46
47 // CHECK: [[A:%[0-9]+]] = call { <2 x i1>, <2 x i1> } @llvm.x86.avx512.vp2intersect.q.128(<2 x i64> {{.*}}, <2 x i64> {{.*}})
48 // CHECK: [[B:%[0-9]+]] = extractvalue { <2 x i1>, <2 x i1> } [[A]], 0
49 // CHECK: [[C:%[0-9]+]] = shufflevector <2 x i1> [[B]], <2 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
50 // CHECK: [[D:%[0-9]+]] = bitcast <8 x i1> [[C]] to i8
51 // CHECK: [[E:%[0-9]+]] = insertvalue { i8, i8 } poison, i8 [[D]], 0
52 // CHECK: [[F:%[0-9]+]] = extractvalue { <2 x i1>, <2 x i1> } [[A]], 1
53 // CHECK: [[G:%[0-9]+]] = shufflevector <2 x i1> [[F]], <2 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
54 // CHECK: [[H:%[0-9]+]] = bitcast <8 x i1> [[G]] to i8
55 // CHECK: insertvalue { i8, i8 } [[E]], i8 [[H]], 1
56 foo(a, b)
57}
58
59// CHECK-LABEL: @i1_vector_autocast
60#[no_mangle]
61pub unsafe fn i1_vector_autocast(a: u8, b: u8) -> u8 {
62 extern "unadjusted" {
63 #[link_name = "llvm.x86.avx512.kadd.b"]
64 fn foo(a: u8, b: u8) -> u8;
65 }
66
67 // CHECK: [[A:%[0-9]+]] = bitcast i8 {{.*}} to <8 x i1>
68 // CHECK: [[B:%[0-9]+]] = bitcast i8 {{.*}} to <8 x i1>
69 // CHECK: [[C:%[0-9]+]] = call <8 x i1> @llvm.x86.avx512.kadd.b(<8 x i1> [[A]], <8 x i1> [[B]])
70 // CHECK: bitcast <8 x i1> [[C]] to i8
71 foo(a, b)
72}
73
74// CHECK-LABEL: @bf16_vector_autocast
75#[no_mangle]
76pub unsafe fn bf16_vector_autocast(a: f32x4) -> i16x8 {
77 extern "unadjusted" {
78 #[link_name = "llvm.x86.vcvtneps2bf16128"]
79 fn foo(a: f32x4) -> i16x8;
80 }
81
82 // CHECK: [[A:%[0-9]+]] = call <8 x bfloat> @llvm.x86.vcvtneps2bf16128(<4 x float> {{.*}})
83 // CHECK: bitcast <8 x bfloat> [[A]] to <8 x i16>
84 foo(a)
85}
86
87// CHECK: declare { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32, <2 x i64>)
88
89// CHECK: declare { <2 x i1>, <2 x i1> } @llvm.x86.avx512.vp2intersect.q.128(<2 x i64>, <2 x i64>)
90
91// CHECK: declare <8 x i1> @llvm.x86.avx512.kadd.b(<8 x i1>, <8 x i1>)
92
93// CHECK: declare <8 x bfloat> @llvm.x86.vcvtneps2bf16128(<4 x float>)
tests/debuginfo/basic-stepping.rs+35-24
......@@ -9,9 +9,20 @@
99// Debugger tests need debuginfo
1010//@ compile-flags: -g
1111
12// FIXME(#128945): SingleUseConsts shouldn't need to be disabled.
13//@ revisions: default-mir-passes no-SingleUseConsts-mir-pass
14//@ [no-SingleUseConsts-mir-pass] compile-flags: -Zmir-enable-passes=-SingleUseConsts
12// Some optimization passes _improve_ compile times [1]. So we want to run some
13// passes even with `-Copt-level=0`. That means that some of the lines below can
14// be optimized away. To make regression testing more robust, we also want to
15// run this test with such passes disabled. The solution is to use two
16// revisions. One with default `-Copt-level=0` passes, and one "even less
17// optimized", with enough optimization passes disabled to keep the maximum
18// number of lines steppable.
19//
20// If `-Zmir-enable-passes=-...` ends up being annoying to maintain, we can try
21// switching to `-Zmir-opt-level=0` instead.
22//
23// [1]: https://github.com/rust-lang/compiler-team/issues/319
24//@ revisions: opt-level-0 maximally-steppable
25//@ [maximally-steppable] compile-flags: -Zmir-enable-passes=-SingleUseConsts
1526
1627// === GDB TESTS ===================================================================================
1728
......@@ -20,12 +31,12 @@
2031//@ gdb-command: next
2132//@ gdb-check: let d = c = 99;
2233//@ gdb-command: next
23//@ [no-SingleUseConsts-mir-pass] gdb-check: let e = "hi bob";
24//@ [no-SingleUseConsts-mir-pass] gdb-command: next
25//@ [no-SingleUseConsts-mir-pass] gdb-check: let f = b"hi bob";
26//@ [no-SingleUseConsts-mir-pass] gdb-command: next
27//@ [no-SingleUseConsts-mir-pass] gdb-check: let g = b'9';
28//@ [no-SingleUseConsts-mir-pass] gdb-command: next
34//@ [maximally-steppable] gdb-check: let e = "hi bob";
35//@ [maximally-steppable] gdb-command: next
36//@ [maximally-steppable] gdb-check: let f = b"hi bob";
37//@ [maximally-steppable] gdb-command: next
38//@ [maximally-steppable] gdb-check: let g = b'9';
39//@ [maximally-steppable] gdb-command: next
2940//@ gdb-check: let h = ["whatever"; 8];
3041//@ gdb-command: next
3142//@ gdb-check: let i = [1,2,3,4];
......@@ -61,15 +72,15 @@
6172//@ lldb-check: [...]let d = c = 99;[...]
6273//@ lldb-command: next
6374//@ lldb-command: frame select
64//@ [no-SingleUseConsts-mir-pass] lldb-check: [...]let e = "hi bob";[...]
65//@ [no-SingleUseConsts-mir-pass] lldb-command: next
66//@ [no-SingleUseConsts-mir-pass] lldb-command: frame select
67//@ [no-SingleUseConsts-mir-pass] lldb-check: [...]let f = b"hi bob";[...]
68//@ [no-SingleUseConsts-mir-pass] lldb-command: next
69//@ [no-SingleUseConsts-mir-pass] lldb-command: frame select
70//@ [no-SingleUseConsts-mir-pass] lldb-check: [...]let g = b'9';[...]
71//@ [no-SingleUseConsts-mir-pass] lldb-command: next
72//@ [no-SingleUseConsts-mir-pass] lldb-command: frame select
75//@ [maximally-steppable] lldb-check: [...]let e = "hi bob";[...]
76//@ [maximally-steppable] lldb-command: next
77//@ [maximally-steppable] lldb-command: frame select
78//@ [maximally-steppable] lldb-check: [...]let f = b"hi bob";[...]
79//@ [maximally-steppable] lldb-command: next
80//@ [maximally-steppable] lldb-command: frame select
81//@ [maximally-steppable] lldb-check: [...]let g = b'9';[...]
82//@ [maximally-steppable] lldb-command: next
83//@ [maximally-steppable] lldb-command: frame select
7384//@ lldb-check: [...]let h = ["whatever"; 8];[...]
7485//@ lldb-command: next
7586//@ lldb-command: frame select
......@@ -107,12 +118,12 @@
107118//@ cdb-check: [...]: let mut c = 27;
108119//@ cdb-command: p
109120//@ cdb-check: [...]: let d = c = 99;
110//@ [no-SingleUseConsts-mir-pass] cdb-command: p
111//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let e = "hi bob";
112//@ [no-SingleUseConsts-mir-pass] cdb-command: p
113//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let f = b"hi bob";
114//@ [no-SingleUseConsts-mir-pass] cdb-command: p
115//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let g = b'9';
121//@ [maximally-steppable] cdb-command: p
122//@ [maximally-steppable] cdb-check: [...]: let e = "hi bob";
123//@ [maximally-steppable] cdb-command: p
124//@ [maximally-steppable] cdb-check: [...]: let f = b"hi bob";
125//@ [maximally-steppable] cdb-command: p
126//@ [maximally-steppable] cdb-check: [...]: let g = b'9';
116127//@ cdb-command: p
117128//@ cdb-check: [...]: let h = ["whatever"; 8];
118129//@ cdb-command: p
tests/debuginfo/macro-stepping.rs+4-4
......@@ -16,9 +16,9 @@
1616extern crate macro_stepping; // exports new_scope!()
1717
1818//@ compile-flags: -g
19// FIXME(#128945): SingleUseConsts shouldn't need to be disabled.
20//@ revisions: default-mir-passes no-SingleUseConsts-mir-pass
21//@ [no-SingleUseConsts-mir-pass] compile-flags: -Zmir-enable-passes=-SingleUseConsts
19// See explanation in `tests/debuginfo/basic-stepping.rs`.
20//@ revisions: opt-level-0 maximally-steppable
21//@ [maximally-steppable] compile-flags: -Zmir-enable-passes=-SingleUseConsts
2222
2323// === GDB TESTS ===================================================================================
2424
......@@ -51,7 +51,7 @@ extern crate macro_stepping; // exports new_scope!()
5151//@ gdb-check:[...]#inc-loc2[...]
5252//@ gdb-command:next
5353//@ gdb-command:frame
54//@ [no-SingleUseConsts-mir-pass] gdb-check:[...]#inc-loc3[...]
54//@ [maximally-steppable] gdb-check:[...]#inc-loc3[...]
5555
5656// === LLDB TESTS ==================================================================================
5757
tests/run-make/simd-ffi/simd.rs+1-1
......@@ -35,7 +35,7 @@ extern "C" {
3535 fn integer(a: i32x4, b: i32x4) -> i32x4;
3636 // vmaxq_s32
3737 #[cfg(target_arch = "aarch64")]
38 #[link_name = "llvm.aarch64.neon.maxs.v4i32"]
38 #[link_name = "llvm.aarch64.neon.smax.v4i32"]
3939 fn integer(a: i32x4, b: i32x4) -> i32x4;
4040
4141 // Use a generic LLVM intrinsic to do type checking on other platforms
tests/ui/associated-types/hr-associated-type-bound-param-6.stderr+12-12
......@@ -9,18 +9,6 @@ help: consider restricting type parameter `T` with trait `X`
99LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) {
1010 | ++++++++++++++++++
1111
12error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
13 --> $DIR/hr-associated-type-bound-param-6.rs:18:5
14 |
15LL | <(i32,) as X<i32>>::f("abc");
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32`
17 |
18help: the trait `X<'_, T>` is implemented for `(S,)`
19 --> $DIR/hr-associated-type-bound-param-6.rs:12:1
20 |
21LL | impl<S, T> X<'_, T> for (S,) {
22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23
2412error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
2513 --> $DIR/hr-associated-type-bound-param-6.rs:18:18
2614 |
......@@ -41,6 +29,18 @@ LL | for<'b> T: X<'b, T>,
4129LL | fn f(x: &<T as X<'_, T>>::U) {
4230 | - required by a bound in this associated function
4331
32error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
33 --> $DIR/hr-associated-type-bound-param-6.rs:18:5
34 |
35LL | <(i32,) as X<i32>>::f("abc");
36 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32`
37 |
38help: the trait `X<'_, T>` is implemented for `(S,)`
39 --> $DIR/hr-associated-type-bound-param-6.rs:12:1
40 |
41LL | impl<S, T> X<'_, T> for (S,) {
42 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43
4444error[E0277]: the trait bound `i32: X<'_, i32>` is not satisfied
4545 --> $DIR/hr-associated-type-bound-param-6.rs:18:27
4646 |
tests/ui/auto-traits/distinct-type-tuple-by-negative-impl.rs created+21
......@@ -0,0 +1,21 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/29516>
2//@ check-pass
3#![feature(auto_traits)]
4#![feature(negative_impls)]
5
6auto trait NotSame {}
7
8impl<A> !NotSame for (A, A) {}
9
10trait OneOfEach {}
11
12impl<A> OneOfEach for (A,) {}
13
14impl<A, B> OneOfEach for (A, B)
15where
16 (B,): OneOfEach,
17 (A, B): NotSame,
18{
19}
20
21fn main() {}
tests/ui/binding/ref-in-let-lhs-in-field.rs created+12
......@@ -0,0 +1,12 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3874>
2//@ build-pass
3#![allow(dead_code)]
4
5enum PureCounter { PureCounterVariant(usize) }
6
7fn each<F>(thing: PureCounter, blk: F) where F: FnOnce(&usize) {
8 let PureCounter::PureCounterVariant(ref x) = thing;
9 blk(x);
10}
11
12pub fn main() {}
tests/ui/codegen/deprecated-llvm-intrinsic.rs created+28
......@@ -0,0 +1,28 @@
1//@ add-minicore
2//@ build-fail
3//@ compile-flags: --target aarch64-unknown-linux-gnu
4//@ needs-llvm-components: aarch64
5//@ ignore-backends: gcc
6#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted, repr_simd, simd_ffi)]
7#![no_std]
8#![no_core]
9#![allow(internal_features, non_camel_case_types, improper_ctypes)]
10#![crate_type = "lib"]
11
12extern crate minicore;
13use minicore::*;
14
15#[repr(simd)]
16pub struct i8x8([i8; 8]);
17
18extern "unadjusted" {
19 #[deny(deprecated_llvm_intrinsic)]
20 #[link_name = "llvm.aarch64.neon.rbit.v8i8"]
21 fn foo(a: i8x8) -> i8x8;
22 //~^ ERROR: using deprecated intrinsic `llvm.aarch64.neon.rbit.v8i8`, `llvm.bitreverse.v8i8` can be used instead
23}
24
25#[target_feature(enable = "neon")]
26pub unsafe fn bar(a: i8x8) -> i8x8 {
27 foo(a)
28}
tests/ui/codegen/deprecated-llvm-intrinsic.stderr created+14
......@@ -0,0 +1,14 @@
1error: using deprecated intrinsic `llvm.aarch64.neon.rbit.v8i8`, `llvm.bitreverse.v8i8` can be used instead
2 --> $DIR/deprecated-llvm-intrinsic.rs:21:5
3 |
4LL | fn foo(a: i8x8) -> i8x8;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: the lint level is defined here
8 --> $DIR/deprecated-llvm-intrinsic.rs:19:12
9 |
10LL | #[deny(deprecated_llvm_intrinsic)]
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^
12
13error: aborting due to 1 previous error
14
tests/ui/codegen/incorrect-arch-intrinsic.rs created+18
......@@ -0,0 +1,18 @@
1//@ build-fail
2//@ ignore-s390x
3//@ normalize-stderr: "target arch `(.*)`" -> "target arch `TARGET_ARCH`"
4//@ ignore-backends: gcc
5
6#![feature(link_llvm_intrinsics, abi_unadjusted)]
7
8extern "unadjusted" {
9 #[link_name = "llvm.s390.sfpc"]
10 fn foo(a: i32);
11 //~^ ERROR: intrinsic `llvm.s390.sfpc` cannot be used with target arch
12}
13
14pub fn main() {
15 unsafe {
16 foo(0);
17 }
18}
tests/ui/codegen/incorrect-arch-intrinsic.stderr created+8
......@@ -0,0 +1,8 @@
1error: intrinsic `llvm.s390.sfpc` cannot be used with target arch `TARGET_ARCH`
2 --> $DIR/incorrect-arch-intrinsic.rs:10:5
3 |
4LL | fn foo(a: i32);
5 | ^^^^^^^^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/codegen/incorrect-llvm-intrinsic-signature.rs created+14
......@@ -0,0 +1,14 @@
1//@ build-fail
2//@ ignore-backends: gcc
3
4#![feature(link_llvm_intrinsics, abi_unadjusted)]
5
6extern "unadjusted" {
7 #[link_name = "llvm.assume"]
8 fn foo();
9 //~^ ERROR: intrinsic signature mismatch for `llvm.assume`: expected signature `void (i1)`, found `void ()`
10}
11
12pub fn main() {
13 unsafe { foo() }
14}
tests/ui/codegen/incorrect-llvm-intrinsic-signature.stderr created+8
......@@ -0,0 +1,8 @@
1error: intrinsic signature mismatch for `llvm.assume`: expected signature `void (i1)`, found `void ()`
2 --> $DIR/incorrect-llvm-intrinsic-signature.rs:8:5
3 |
4LL | fn foo();
5 | ^^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/codegen/unknown-llvm-intrinsic.rs created+14
......@@ -0,0 +1,14 @@
1//@ build-fail
2//@ ignore-backends: gcc
3
4#![feature(link_llvm_intrinsics, abi_unadjusted)]
5
6extern "unadjusted" {
7 #[link_name = "llvm.abcde"]
8 fn foo();
9 //~^ ERROR: unknown LLVM intrinsic `llvm.abcde`
10}
11
12pub fn main() {
13 unsafe { foo() }
14}
tests/ui/codegen/unknown-llvm-intrinsic.stderr created+8
......@@ -0,0 +1,8 @@
1error: unknown LLVM intrinsic `llvm.abcde`
2 --> $DIR/unknown-llvm-intrinsic.rs:8:5
3 |
4LL | fn foo();
5 | ^^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/deref/derefmut-closure-drop-order.rs created+47
......@@ -0,0 +1,47 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/16774
2
3//@ run-pass
4#![feature(box_patterns)]
5
6use std::ops::{Deref, DerefMut};
7
8struct X(Box<isize>);
9
10static mut DESTRUCTOR_RAN: bool = false;
11
12impl Drop for X {
13 fn drop(&mut self) {
14 unsafe {
15 assert!(!DESTRUCTOR_RAN);
16 DESTRUCTOR_RAN = true;
17 }
18 }
19}
20
21impl Deref for X {
22 type Target = isize;
23
24 fn deref(&self) -> &isize {
25 let &X(box ref x) = self;
26 x
27 }
28}
29
30impl DerefMut for X {
31 fn deref_mut(&mut self) -> &mut isize {
32 let &mut X(box ref mut x) = self;
33 x
34 }
35}
36
37fn main() {
38 {
39 let mut test = X(Box::new(5));
40 {
41 let mut change = || { *test = 10 };
42 change();
43 }
44 assert_eq!(*test, 10);
45 }
46 assert!(unsafe { DESTRUCTOR_RAN });
47}
tests/ui/eii/attribute_targets.stderr+18-18
......@@ -1,106 +1,106 @@
1error: `#[foo]` is only valid on functions
1error: `#[foo]` is only valid on functions and statics
22 --> $DIR/attribute_targets.rs:7:1
33 |
44LL | #[foo]
55 | ^^^^^^
66
7error: `#[eii]` is only valid on functions
7error: `#[eii]` is only valid on functions and statics
88 --> $DIR/attribute_targets.rs:9:1
99 |
1010LL | #[eii]
1111 | ^^^^^^
1212
13error: `#[foo]` is only valid on functions
13error: `#[foo]` is only valid on functions and statics
1414 --> $DIR/attribute_targets.rs:13:1
1515 |
1616LL | #[foo]
1717 | ^^^^^^
1818
19error: `#[eii]` is only valid on functions
19error: `#[eii]` is only valid on functions and statics
2020 --> $DIR/attribute_targets.rs:15:1
2121 |
2222LL | #[eii]
2323 | ^^^^^^
2424
25error: `#[foo]` is only valid on functions
25error: `#[foo]` is only valid on functions and statics
2626 --> $DIR/attribute_targets.rs:21:1
2727 |
2828LL | #[foo]
2929 | ^^^^^^
3030
31error: `#[eii]` is only valid on functions
31error: `#[eii]` is only valid on functions and statics
3232 --> $DIR/attribute_targets.rs:23:1
3333 |
3434LL | #[eii]
3535 | ^^^^^^
3636
37error: `#[foo]` is only valid on functions
37error: `#[foo]` is only valid on functions and statics
3838 --> $DIR/attribute_targets.rs:27:1
3939 |
4040LL | #[foo]
4141 | ^^^^^^
4242
43error: `#[eii]` is only valid on functions
43error: `#[eii]` is only valid on functions and statics
4444 --> $DIR/attribute_targets.rs:29:1
4545 |
4646LL | #[eii]
4747 | ^^^^^^
4848
49error: `#[foo]` is only valid on functions
49error: `#[foo]` is only valid on functions and statics
5050 --> $DIR/attribute_targets.rs:32:5
5151 |
5252LL | #[foo]
5353 | ^^^^^^
5454
55error: `#[eii]` is only valid on functions
55error: `#[eii]` is only valid on functions and statics
5656 --> $DIR/attribute_targets.rs:34:5
5757 |
5858LL | #[eii]
5959 | ^^^^^^
6060
61error: `#[foo]` is only valid on functions
61error: `#[foo]` is only valid on functions and statics
6262 --> $DIR/attribute_targets.rs:39:1
6363 |
6464LL | #[foo]
6565 | ^^^^^^
6666
67error: `#[eii]` is only valid on functions
67error: `#[eii]` is only valid on functions and statics
6868 --> $DIR/attribute_targets.rs:41:1
6969 |
7070LL | #[eii]
7171 | ^^^^^^
7272
73error: `#[foo]` is only valid on functions
73error: `#[foo]` is only valid on functions and statics
7474 --> $DIR/attribute_targets.rs:44:5
7575 |
7676LL | #[foo]
7777 | ^^^^^^
7878
79error: `#[eii]` is only valid on functions
79error: `#[eii]` is only valid on functions and statics
8080 --> $DIR/attribute_targets.rs:46:5
8181 |
8282LL | #[eii]
8383 | ^^^^^^
8484
85error: `#[foo]` is only valid on functions
85error: `#[foo]` is only valid on functions and statics
8686 --> $DIR/attribute_targets.rs:51:1
8787 |
8888LL | #[foo]
8989 | ^^^^^^
9090
91error: `#[eii]` is only valid on functions
91error: `#[eii]` is only valid on functions and statics
9292 --> $DIR/attribute_targets.rs:53:1
9393 |
9494LL | #[eii]
9595 | ^^^^^^
9696
97error: `#[foo]` is only valid on functions
97error: `#[foo]` is only valid on functions and statics
9898 --> $DIR/attribute_targets.rs:56:5
9999 |
100100LL | #[foo]
101101 | ^^^^^^
102102
103error: `#[eii]` is only valid on functions
103error: `#[eii]` is only valid on functions and statics
104104 --> $DIR/attribute_targets.rs:58:5
105105 |
106106LL | #[eii]
tests/ui/eii/default/call_default.rs+1-1
......@@ -3,7 +3,7 @@
33//@ run-pass
44//@ check-run-results
55//@ ignore-backends: gcc
6// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
6// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
77//@ ignore-windows
88// Tests EIIs with default implementations.
99// When there's no explicit declaration, the default should be called from the declaring crate.
tests/ui/eii/default/call_default_panics.rs+1-1
......@@ -5,7 +5,7 @@
55//@ needs-unwind
66//@ exec-env:RUST_BACKTRACE=1
77//@ ignore-backends: gcc
8// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
8// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
99//@ ignore-windows
1010// A small test to make sure that unwinding works properly.
1111//
tests/ui/eii/default/call_impl.rs+1-1
......@@ -4,7 +4,7 @@
44//@ run-pass
55//@ check-run-results
66//@ ignore-backends: gcc
7// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
7// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
88//@ ignore-windows
99// Tests EIIs with default implementations.
1010// When an explicit implementation is given in one dependency, and the declaration is in another,
tests/ui/eii/default/local_crate.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ check-run-results
33//@ ignore-backends: gcc
4// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
55//@ ignore-windows
66// Tests EIIs with default implementations.
77// In the same crate, when there's no explicit declaration, the default should be called.
tests/ui/eii/default/local_crate_explicit.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ check-run-results
33//@ ignore-backends: gcc
4// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
55//@ ignore-windows
66// Tests EIIs with default implementations.
77// In the same crate, the explicit implementation should get priority.
tests/ui/eii/duplicate/duplicate1.rs+1-1
......@@ -2,7 +2,7 @@
22//@ aux-build: impl1.rs
33//@ aux-build: impl2.rs
44//@ ignore-backends: gcc
5// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
5// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
66//@ ignore-windows
77// tests that EIIs error properly, even if the conflicting implementations live in another crate.
88#![feature(extern_item_impls)]
tests/ui/eii/duplicate/duplicate2.rs+1-1
......@@ -3,7 +3,7 @@
33//@ aux-build: impl2.rs
44//@ aux-build: impl3.rs
55//@ ignore-backends: gcc
6// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
6// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
77//@ ignore-windows
88// Tests the error message when there are multiple implementations of an EII in many crates.
99#![feature(extern_item_impls)]
tests/ui/eii/duplicate/duplicate3.rs+1-1
......@@ -4,7 +4,7 @@
44//@ aux-build: impl3.rs
55//@ aux-build: impl4.rs
66//@ ignore-backends: gcc
7// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
7// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
88//@ ignore-windows
99// Tests the error message when there are multiple implementations of an EII in many crates.
1010#![feature(extern_item_impls)]
tests/ui/eii/duplicate/multiple_impls.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ check-run-results
33//@ ignore-backends: gcc
4// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
55//@ ignore-windows
66// Tests whether one function could implement two EIIs.
77#![feature(extern_item_impls)]
tests/ui/eii/eii-declaration-not-fn-issue-152337.rs+2-2
......@@ -6,7 +6,7 @@
66const A: () = ();
77#[eii]
88fn A() {} //~ ERROR the name `A` is defined multiple times
9//~^ ERROR expected function, found constant
10//~| ERROR expected function, found constant
9//~^ ERROR expected function or static, found constant
10//~| ERROR expected function or static, found constant
1111
1212fn main() {}
tests/ui/eii/eii-declaration-not-fn-issue-152337.stderr+4-4
......@@ -9,17 +9,17 @@ LL | fn A() {}
99 |
1010 = note: `A` must be defined only once in the value namespace of this module
1111
12error[E0423]: expected function, found constant `self::A`
12error[E0423]: expected function or static, found constant `self::A`
1313 --> $DIR/eii-declaration-not-fn-issue-152337.rs:8:4
1414 |
1515LL | fn A() {}
16 | ^ not a function
16 | ^ not a function or static
1717
18error[E0423]: expected function, found constant `A`
18error[E0423]: expected function or static, found constant `A`
1919 --> $DIR/eii-declaration-not-fn-issue-152337.rs:8:4
2020 |
2121LL | fn A() {}
22 | ^ not a function
22 | ^ not a function or static
2323
2424error: aborting due to 3 previous errors
2525
tests/ui/eii/error_statement_position.stderr+1-1
......@@ -1,4 +1,4 @@
1error: `#[eii]` is only valid on functions
1error: `#[eii]` is only valid on functions and statics
22 --> $DIR/error_statement_position.rs:8:5
33 |
44LL | #[eii]
tests/ui/eii/errors.rs+2-4
......@@ -25,11 +25,9 @@ unsafe extern "Rust" {
2525 safe fn bar(x: u64) -> u64;
2626}
2727
28#[foo] //~ ERROR `#[foo]` is only valid on functions
29static X: u64 = 4;
30#[foo] //~ ERROR `#[foo]` is only valid on functions
28#[foo] //~ ERROR `#[foo]` is only valid on functions and statics
3129const Y: u64 = 4;
32#[foo] //~ ERROR `#[foo]` is only valid on functions
30#[foo] //~ ERROR `#[foo]` is only valid on functions and statics
3331macro bar() {}
3432
3533#[foo()]
tests/ui/eii/errors.stderr+7-13
......@@ -52,47 +52,41 @@ error: `#[eii_declaration(...)]` expects a list of one or two elements
5252LL | #[eii_declaration = "unsafe"]
5353 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5454
55error: `#[foo]` is only valid on functions
55error: `#[foo]` is only valid on functions and statics
5656 --> $DIR/errors.rs:28:1
5757 |
5858LL | #[foo]
5959 | ^^^^^^
6060
61error: `#[foo]` is only valid on functions
61error: `#[foo]` is only valid on functions and statics
6262 --> $DIR/errors.rs:30:1
6363 |
6464LL | #[foo]
6565 | ^^^^^^
6666
67error: `#[foo]` is only valid on functions
68 --> $DIR/errors.rs:32:1
69 |
70LL | #[foo]
71 | ^^^^^^
72
7367error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]`
74 --> $DIR/errors.rs:35:1
68 --> $DIR/errors.rs:33:1
7569 |
7670LL | #[foo()]
7771 | ^^^^^^^^
7872
7973error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]`
80 --> $DIR/errors.rs:37:1
74 --> $DIR/errors.rs:35:1
8175 |
8276LL | #[foo(default, bar)]
8377 | ^^^^^^^^^^^^^^^^^^^^
8478
8579error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]`
86 --> $DIR/errors.rs:39:1
80 --> $DIR/errors.rs:37:1
8781 |
8882LL | #[foo("default")]
8983 | ^^^^^^^^^^^^^^^^^
9084
9185error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]`
92 --> $DIR/errors.rs:41:1
86 --> $DIR/errors.rs:39:1
9387 |
9488LL | #[foo = "default"]
9589 | ^^^^^^^^^^^^^^^^^^
9690
97error: aborting due to 15 previous errors
91error: aborting due to 14 previous errors
9892
tests/ui/eii/linking/codegen_cross_crate.rs+1-1
......@@ -3,7 +3,7 @@
33//@ aux-build: codegen_cross_crate_other_crate.rs
44//@ compile-flags: -O
55//@ ignore-backends: gcc
6// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
6// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
77//@ ignore-windows
88// Tests whether calling EIIs works with the declaration in another crate.
99
tests/ui/eii/linking/codegen_single_crate.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ check-run-results
33//@ ignore-backends: gcc
4// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
55//@ ignore-windows
66// Tests whether calling EIIs works with the declaration in the same crate.
77#![feature(extern_item_impls)]
tests/ui/eii/linking/same-symbol.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ check-run-results
33//@ ignore-backends: gcc
4// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
55//@ ignore-windows
66#![feature(extern_item_impls)]
77
tests/ui/eii/shadow_builtin.rs created+17
......@@ -0,0 +1,17 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether calling EIIs works with the declaration in the same crate.
5#![feature(extern_item_impls)]
6
7#[eii(inline)]
8//~^ ERROR `#[inline]` required, but not found
9fn test(x: u64);
10
11#[inline]
12//~^ ERROR `inline` is ambiguous
13fn test_impl(x: u64) {
14 println!("{x:?}")
15}
16
17fn main() { }
tests/ui/eii/shadow_builtin.stderr created+26
......@@ -0,0 +1,26 @@
1error[E0659]: `inline` is ambiguous
2 --> $DIR/shadow_builtin.rs:11:3
3 |
4LL | #[inline]
5 | ^^^^^^ ambiguous name
6 |
7 = note: ambiguous because of a name conflict with a builtin attribute
8 = note: `inline` could refer to a built-in attribute
9note: `inline` could also refer to the attribute macro defined here
10 --> $DIR/shadow_builtin.rs:7:1
11 |
12LL | #[eii(inline)]
13 | ^^^^^^^^^^^^^^
14 = help: use `crate::inline` to refer to this attribute macro unambiguously
15
16error: `#[inline]` required, but not found
17 --> $DIR/shadow_builtin.rs:7:7
18 |
19LL | #[eii(inline)]
20 | ^^^^^^ expected because `#[inline]` was declared here in crate `shadow_builtin`
21 |
22 = help: expected at least one implementation in crate `shadow_builtin` or any of its dependencies
23
24error: aborting due to 2 previous errors
25
26For more information about this error, try `rustc --explain E0659`.
tests/ui/eii/static/argument_required.rs created+11
......@@ -0,0 +1,11 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii]
8//~^ ERROR `#[eii]` requires the name as an explicit argument when used on a static
9static HELLO: u64;
10
11fn main() { }
tests/ui/eii/static/argument_required.stderr created+8
......@@ -0,0 +1,8 @@
1error: `#[eii]` requires the name as an explicit argument when used on a static
2 --> $DIR/argument_required.rs:7:1
3 |
4LL | #[eii]
5 | ^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/auxiliary/cross_crate_decl.rs created+6
......@@ -0,0 +1,6 @@
1//@ no-prefer-dynamic
2#![crate_type = "rlib"]
3#![feature(extern_item_impls)]
4
5#[eii(eii1)]
6pub static DECL1: u64;
tests/ui/eii/static/auxiliary/cross_crate_def.rs created+9
......@@ -0,0 +1,9 @@
1//@ no-prefer-dynamic
2#![crate_type = "rlib"]
3#![feature(extern_item_impls)]
4
5#[eii(eii1)]
6pub static DECL1: u64;
7
8#[eii1]
9pub static EII1_IMPL: u64 = 5;
tests/ui/eii/static/cross_crate_decl.rs created+21
......@@ -0,0 +1,21 @@
1//@ run-pass
2//@ check-run-results
3//@ aux-build: cross_crate_decl.rs
4//@ compile-flags: -O
5//@ ignore-backends: gcc
6// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
7//@ ignore-windows
8// Tests whether calling EIIs works with the declaration in another crate.
9
10extern crate cross_crate_decl as codegen;
11
12#[codegen::eii1]
13static EII1_IMPL: u64 = 5;
14
15// what you would write:
16fn main() {
17 // directly
18 println!("{}", EII1_IMPL);
19 // through the alias
20 println!("{}", codegen::DECL1);
21}
tests/ui/eii/static/cross_crate_decl.run.stdout created+2
......@@ -0,0 +1,2 @@
15
25
tests/ui/eii/static/cross_crate_def.rs created+18
......@@ -0,0 +1,18 @@
1//@ run-pass
2//@ check-run-results
3//@ aux-build: cross_crate_def.rs
4//@ compile-flags: -O
5//@ ignore-backends: gcc
6// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
7//@ ignore-windows
8// Tests whether calling EIIs works with the declaration and definition in another crate.
9
10extern crate cross_crate_def as codegen;
11
12// what you would write:
13fn main() {
14 // directly
15 println!("{}", codegen::EII1_IMPL);
16 // through the alias
17 println!("{}", codegen::DECL1);
18}
tests/ui/eii/static/cross_crate_def.run.stdout created+2
......@@ -0,0 +1,2 @@
15
25
tests/ui/eii/static/duplicate.rs created+25
......@@ -0,0 +1,25 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8static HELLO: u64;
9
10#[hello]
11static HELLO_IMPL1: u64 = 5;
12//~^ ERROR multiple implementations of `#[hello]`
13
14#[hello]
15static HELLO_IMPL2: u64 = 6;
16
17// what you would write:
18fn main() {
19 // directly
20 println!("{HELLO_IMPL1}");
21 println!("{HELLO_IMPL2}");
22
23 // through the alias
24 println!("{HELLO}");
25}
tests/ui/eii/static/duplicate.stderr created+13
......@@ -0,0 +1,13 @@
1error: multiple implementations of `#[hello]`
2 --> $DIR/duplicate.rs:11:1
3 |
4LL | static HELLO_IMPL1: u64 = 5;
5 | ^^^^^^^^^^^^^^^^^^^^^^^ first implemented here in crate `duplicate`
6...
7LL | static HELLO_IMPL2: u64 = 6;
8 | ----------------------- also implemented here in crate `duplicate`
9 |
10 = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict
11
12error: aborting due to 1 previous error
13
tests/ui/eii/static/mismatch_fn_static.rs created+14
......@@ -0,0 +1,14 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8fn hello() -> u64;
9
10#[hello]
11//~^ ERROR `#[hello]` must be used on a function
12static HELLO_IMPL: u64 = 5;
13
14fn main() { }
tests/ui/eii/static/mismatch_fn_static.stderr created+8
......@@ -0,0 +1,8 @@
1error: `#[hello]` must be used on a function
2 --> $DIR/mismatch_fn_static.rs:10:1
3 |
4LL | #[hello]
5 | ^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/mismatch_mut.rs created+22
......@@ -0,0 +1,22 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8//~^ ERROR `#[eii]` cannot be used on mutable statics
9static mut HELLO: u64;
10
11#[hello]
12//~^ ERROR mutability does not match with the definition of`#[hello]`
13static HELLO_IMPL: u64 = 5;
14
15// what you would write:
16fn main() {
17 // directly
18 println!("{HELLO_IMPL}");
19
20 // through the alias
21 println!("{}", unsafe { HELLO });
22}
tests/ui/eii/static/mismatch_mut.stderr created+14
......@@ -0,0 +1,14 @@
1error: `#[eii]` cannot be used on mutable statics
2 --> $DIR/mismatch_mut.rs:7:1
3 |
4LL | #[eii(hello)]
5 | ^^^^^^^^^^^^^
6
7error: mutability does not match with the definition of`#[hello]`
8 --> $DIR/mismatch_mut.rs:11:1
9 |
10LL | #[hello]
11 | ^^^^^^^^
12
13error: aborting due to 2 previous errors
14
tests/ui/eii/static/mismatch_mut2.rs created+21
......@@ -0,0 +1,21 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8static HELLO: u64;
9
10#[hello]
11//~^ ERROR mutability does not match with the definition of`#[hello]`
12static mut HELLO_IMPL: u64 = 5;
13
14// what you would write:
15fn main() {
16 // directly
17 println!("{}", unsafe { HELLO_IMPL });
18
19 // through the alias
20 println!("{HELLO}");
21}
tests/ui/eii/static/mismatch_mut2.stderr created+8
......@@ -0,0 +1,8 @@
1error: mutability does not match with the definition of`#[hello]`
2 --> $DIR/mismatch_mut2.rs:10:1
3 |
4LL | #[hello]
5 | ^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/mismatch_safety.rs created+21
......@@ -0,0 +1,21 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8unsafe static HELLO: u64;
9
10#[hello]
11//~^ ERROR safety does not match with the definition of`#[hello]`
12static HELLO_IMPL: u64 = 5;
13
14// what you would write:
15fn main() {
16 // directly
17 println!("{HELLO_IMPL}");
18
19 // through the alias
20 println!("{}", unsafe { HELLO });
21}
tests/ui/eii/static/mismatch_safety.stderr created+8
......@@ -0,0 +1,8 @@
1error: safety does not match with the definition of`#[hello]`
2 --> $DIR/mismatch_safety.rs:10:1
3 |
4LL | #[hello]
5 | ^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/mismatch_safety2.rs created+21
......@@ -0,0 +1,21 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8static HELLO: u64;
9
10#[hello]
11unsafe static HELLO_IMPL: u64 = 5;
12//~^ ERROR static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
13
14// what you would write:
15fn main() {
16 // directly
17 println!("{HELLO_IMPL}");
18
19 // through the alias
20 println!("{}", unsafe { HELLO });
21}
tests/ui/eii/static/mismatch_safety2.stderr created+8
......@@ -0,0 +1,8 @@
1error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
2 --> $DIR/mismatch_safety2.rs:11:1
3 |
4LL | unsafe static HELLO_IMPL: u64 = 5;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/mismatch_static_fn.rs created+16
......@@ -0,0 +1,16 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8static HELLO: u64;
9
10#[hello]
11//~^ ERROR `#[hello]` must be used on a static
12fn hello_impl() -> u64 {
13 5
14}
15
16fn main() { }
tests/ui/eii/static/mismatch_static_fn.stderr created+8
......@@ -0,0 +1,8 @@
1error: `#[hello]` must be used on a static
2 --> $DIR/mismatch_static_fn.rs:10:1
3 |
4LL | #[hello]
5 | ^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/multiple_decls.rs created+12
......@@ -0,0 +1,12 @@
1#![feature(extern_item_impls)]
2
3const A: () = ();
4#[eii(A)]
5static A: u64;
6//~^ ERROR the name `A` is defined multiple times
7//~| ERROR expected function or static, found constant `A`
8
9#[A]
10static A_IMPL: u64 = 5;
11
12fn main() {}
tests/ui/eii/static/multiple_decls.stderr created+21
......@@ -0,0 +1,21 @@
1error[E0428]: the name `A` is defined multiple times
2 --> $DIR/multiple_decls.rs:5:1
3 |
4LL | const A: () = ();
5 | ----------------- previous definition of the value `A` here
6LL | #[eii(A)]
7LL | static A: u64;
8 | ^^^^^^^^^^^^^^ `A` redefined here
9 |
10 = note: `A` must be defined only once in the value namespace of this module
11
12error[E0423]: expected function or static, found constant `A`
13 --> $DIR/multiple_decls.rs:5:8
14 |
15LL | static A: u64;
16 | ^ not a function or static
17
18error: aborting due to 2 previous errors
19
20Some errors have detailed explanations: E0423, E0428.
21For more information about an error, try `rustc --explain E0423`.
tests/ui/eii/static/multiple_impls.rs created+20
......@@ -0,0 +1,20 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether one function could implement two EIIs.
5#![feature(extern_item_impls)]
6
7#[eii(a)]
8static A: u64;
9
10#[eii(b)]
11static B: u64;
12
13#[a]
14#[b]
15//~^ ERROR static cannot implement multiple EIIs
16static IMPL: u64 = 5;
17
18fn main() {
19 println!("{A} {B} {IMPL}")
20}
tests/ui/eii/static/multiple_impls.run.stdout created+1
......@@ -0,0 +1 @@
15 5 5
tests/ui/eii/static/multiple_impls.stderr created+10
......@@ -0,0 +1,10 @@
1error: static cannot implement multiple EIIs
2 --> $DIR/multiple_impls.rs:14:1
3 |
4LL | #[b]
5 | ^^^^
6 |
7 = note: this is not allowed because multiple externally implementable statics that alias may be unintuitive
8
9error: aborting due to 1 previous error
10
tests/ui/eii/static/mut.rs created+21
......@@ -0,0 +1,21 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests whether EIIs work on statics
5#![feature(extern_item_impls)]
6
7#[eii(hello)]
8//~^ ERROR `#[eii]` cannot be used on mutable statics
9static mut HELLO: u64;
10
11#[hello]
12static mut HELLO_IMPL: u64 = 5;
13
14// what you would write:
15fn main() {
16 // directly
17 println!("{}", unsafe { HELLO_IMPL });
18
19 // through the alias
20 println!("{}", unsafe { HELLO });
21}
tests/ui/eii/static/mut.run.stdout created+2
......@@ -0,0 +1,2 @@
15
25
tests/ui/eii/static/mut.stderr created+8
......@@ -0,0 +1,8 @@
1error: `#[eii]` cannot be used on mutable statics
2 --> $DIR/mut.rs:7:1
3 |
4LL | #[eii(hello)]
5 | ^^^^^^^^^^^^^
6
7error: aborting due to 1 previous error
8
tests/ui/eii/static/same_address.rs created+21
......@@ -0,0 +1,21 @@
1//@ run-pass
2//@ check-run-results
3//@ ignore-backends: gcc
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
5//@ ignore-windows
6// Tests whether EIIs and their declarations share the same address
7#![feature(extern_item_impls)]
8
9#[eii(hello)]
10static HELLO: u64;
11
12#[hello]
13static HELLO_IMPL: u64 = 5;
14
15// what you would write:
16fn main() {
17 assert_eq!(
18 &HELLO as *const u64 as usize,
19 &HELLO_IMPL as *const u64 as usize,
20 )
21}
tests/ui/eii/static/simple.rs created+22
......@@ -0,0 +1,22 @@
1//@ run-pass
2//@ check-run-results
3//@ ignore-backends: gcc
4// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
5//@ ignore-windows
6// Tests whether EIIs work on statics
7#![feature(extern_item_impls)]
8
9#[eii(hello)]
10static HELLO: u64;
11
12#[hello]
13static HELLO_IMPL: u64 = 5;
14
15// what you would write:
16fn main() {
17 // directly
18 println!("{HELLO_IMPL}");
19
20 // through the alias
21 println!("{HELLO}");
22}
tests/ui/eii/static/simple.run.stdout created+2
......@@ -0,0 +1,2 @@
15
25
tests/ui/eii/static/subtype.rs created+18
......@@ -0,0 +1,18 @@
1//@ check-pass
2//@ ignore-backends: gcc
3// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
4//@ ignore-windows
5// Tests that mismatching types of the declaration and definition are rejected
6#![feature(extern_item_impls)]
7
8use std::ptr;
9
10#[eii(hello)]
11static HELLO: for<'a> fn(&'a u8) -> &'a u8;
12
13#[hello]
14static HELLO_IMPL: for<'a> fn(&'a u8) -> &'static u8 = |_| todo!();
15
16fn main() {
17
18}
tests/ui/eii/static/subtype_wrong.rs created+17
......@@ -0,0 +1,17 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests that mismatching types of the declaration and definition are rejected
5#![feature(extern_item_impls)]
6
7use std::ptr;
8
9#[eii(hello)]
10static HELLO: for<'a> fn(&'a u8) -> &'static u8;
11
12#[hello]
13static HELLO_IMPL: for<'a> fn(&'a u8) -> &'a u8 = |_| todo!();
14//~^ ERROR mismatched types
15
16fn main() {
17}
tests/ui/eii/static/subtype_wrong.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0308]: mismatched types
2 --> $DIR/subtype_wrong.rs:13:1
3 |
4LL | static HELLO_IMPL: for<'a> fn(&'a u8) -> &'a u8 = |_| todo!();
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
6 |
7 = note: expected fn pointer `for<'a> fn(&'a _) -> &'static _`
8 found fn pointer `for<'a> fn(&'a _) -> &'a _`
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0308`.
tests/ui/eii/static/wrong_ty.rs created+18
......@@ -0,0 +1,18 @@
1//@ ignore-backends: gcc
2// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418
3//@ ignore-windows
4// Tests that mismatching types of the declaration and definition are rejected
5#![feature(extern_item_impls)]
6
7use std::ptr;
8
9#[eii(hello)]
10static HELLO: u64;
11
12#[hello]
13static HELLO_IMPL: bool = true;
14//~^ ERROR static `HELLO_IMPL` has a type that is incompatible with the declaration of `#[hello]` [E0806]
15
16fn main() {
17
18}
tests/ui/eii/static/wrong_ty.stderr created+15
......@@ -0,0 +1,15 @@
1error[E0806]: static `HELLO_IMPL` has a type that is incompatible with the declaration of `#[hello]`
2 --> $DIR/wrong_ty.rs:13:1
3 |
4LL | static HELLO_IMPL: bool = true;
5 | ^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: expected this because of this attribute
8 --> $DIR/wrong_ty.rs:12:1
9 |
10LL | #[hello]
11 | ^^^^^^^^
12
13error: aborting due to 1 previous error
14
15For more information about this error, try `rustc --explain E0806`.
tests/ui/feature-gates/feature-gate-check-nested-macro-invocation.rs created+16
......@@ -0,0 +1,16 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/32782>
2macro_rules! bar (
3 () => ()
4);
5
6macro_rules! foo (
7 () => (
8 #[allow_internal_unstable()]
9 //~^ ERROR allow_internal_unstable side-steps
10 //~| ERROR `#[allow_internal_unstable]` attribute cannot be used on macro calls
11 bar!();
12 );
13);
14
15foo!();
16fn main() {}
tests/ui/feature-gates/feature-gate-check-nested-macro-invocation.stderr created+28
......@@ -0,0 +1,28 @@
1error[E0658]: allow_internal_unstable side-steps feature gating and stability checks
2 --> $DIR/feature-gate-check-nested-macro-invocation.rs:8:9
3 |
4LL | #[allow_internal_unstable()]
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6...
7LL | foo!();
8 | ------ in this macro invocation
9 |
10 = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable
11 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
12 = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
13
14error: `#[allow_internal_unstable]` attribute cannot be used on macro calls
15 --> $DIR/feature-gate-check-nested-macro-invocation.rs:8:9
16 |
17LL | #[allow_internal_unstable()]
18 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19...
20LL | foo!();
21 | ------ in this macro invocation
22 |
23 = help: `#[allow_internal_unstable]` can be applied to functions and macro defs
24 = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
25
26error: aborting due to 2 previous errors
27
28For more information about this error, try `rustc --explain E0658`.
tests/ui/feature-gates/feature-gate-diagnostic-on-move.rs+2-3
......@@ -2,9 +2,8 @@
22//! gate, but the fact that not adding the feature gate will cause the
33//! diagnostic to not emit the custom diagnostic message
44//!
5#[diagnostic::on_move(
6 message = "Foo"
7)]
5#[diagnostic::on_move(message = "Foo")]
6//~^ WARN unknown diagnostic attribute
87#[derive(Debug)]
98struct Foo;
109
tests/ui/feature-gates/feature-gate-diagnostic-on-move.stderr+13-4
......@@ -1,5 +1,14 @@
1warning: unknown diagnostic attribute
2 --> $DIR/feature-gate-diagnostic-on-move.rs:5:15
3 |
4LL | #[diagnostic::on_move(message = "Foo")]
5 | ^^^^^^^
6 |
7 = help: add `#![feature(diagnostic_on_move)]` to the crate attributes to enable
8 = note: `#[warn(unknown_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
9
110error[E0382]: use of moved value: `foo`
2 --> $DIR/feature-gate-diagnostic-on-move.rs:16:15
11 --> $DIR/feature-gate-diagnostic-on-move.rs:15:15
312 |
413LL | let foo = Foo;
514 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
......@@ -9,14 +18,14 @@ LL | let bar = foo;
918 | ^^^ value used here after move
1019 |
1120note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary
12 --> $DIR/feature-gate-diagnostic-on-move.rs:11:17
21 --> $DIR/feature-gate-diagnostic-on-move.rs:10:17
1322 |
1423LL | fn takes_foo(_: Foo) {}
1524 | --------- ^^^ this parameter takes ownership of the value
1625 | |
1726 | in this function
1827note: if `Foo` implemented `Clone`, you could clone the value
19 --> $DIR/feature-gate-diagnostic-on-move.rs:9:1
28 --> $DIR/feature-gate-diagnostic-on-move.rs:8:1
2029 |
2130LL | struct Foo;
2231 | ^^^^^^^^^^ consider implementing `Clone` for this type
......@@ -24,6 +33,6 @@ LL | struct Foo;
2433LL | takes_foo(foo);
2534 | --- you could clone this value
2635
27error: aborting due to 1 previous error
36error: aborting due to 1 previous error; 1 warning emitted
2837
2938For more information about this error, try `rustc --explain E0382`.
tests/ui/feature-gates/feature-gate-diagnostic-on-unknown.stderr+1
......@@ -10,6 +10,7 @@ error: unknown diagnostic attribute
1010LL | #[diagnostic::on_unknown(message = "Tada")]
1111 | ^^^^^^^^^^
1212 |
13 = help: add `#![feature(diagnostic_on_unknown)]` to the crate attributes to enable
1314note: the lint level is defined here
1415 --> $DIR/feature-gate-diagnostic-on-unknown.rs:1:9
1516 |
tests/ui/imports/issue-56125.rs+1-1
......@@ -15,7 +15,7 @@ mod m2 {
1515mod m3 {
1616 mod empty {}
1717 use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
18 use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
18 use issue_56125::*;
1919}
2020
2121fn main() {}
tests/ui/imports/issue-56125.stderr+1-18
......@@ -54,24 +54,7 @@ LL | use issue_56125::non_last_segment::non_last_segment::*;
5454 = help: consider adding an explicit import of `issue_56125` to disambiguate
5555 = help: or use `self::issue_56125` to refer to this module unambiguously
5656
57error[E0659]: `issue_56125` is ambiguous
58 --> $DIR/issue-56125.rs:18:9
59 |
60LL | use issue_56125::*;
61 | ^^^^^^^^^^^ ambiguous name
62 |
63 = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
64 = note: `issue_56125` could refer to a crate passed with `--extern`
65 = help: use `::issue_56125` to refer to this crate unambiguously
66note: `issue_56125` could also refer to the module imported here
67 --> $DIR/issue-56125.rs:18:9
68 |
69LL | use issue_56125::*;
70 | ^^^^^^^^^^^^^^
71 = help: consider adding an explicit import of `issue_56125` to disambiguate
72 = help: or use `self::issue_56125` to refer to this module unambiguously
73
74error: aborting due to 4 previous errors
57error: aborting due to 3 previous errors
7558
7659Some errors have detailed explanations: E0432, E0659.
7760For more information about an error, try `rustc --explain E0432`.
tests/ui/imports/shadow-glob-module-resolution-2.rs-2
......@@ -14,7 +14,5 @@ use a::*;
1414use e as b;
1515//~^ ERROR: unresolved import `e`
1616use b::c::D as e;
17//~^ ERROR: cannot determine resolution for the import
18//~| ERROR: cannot determine resolution for the import
1917
2018fn main() { }
tests/ui/imports/shadow-glob-module-resolution-2.stderr+1-15
......@@ -1,17 +1,3 @@
1error: cannot determine resolution for the import
2 --> $DIR/shadow-glob-module-resolution-2.rs:16:5
3 |
4LL | use b::c::D as e;
5 | ^^^^^^^^^^^^
6
7error: cannot determine resolution for the import
8 --> $DIR/shadow-glob-module-resolution-2.rs:16:5
9 |
10LL | use b::c::D as e;
11 | ^^^^^^^^^^^^
12 |
13 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14
151error[E0432]: unresolved import `e`
162 --> $DIR/shadow-glob-module-resolution-2.rs:14:5
173 |
......@@ -24,6 +10,6 @@ LL - use e as b;
2410LL + use a as b;
2511 |
2612
27error: aborting due to 3 previous errors
13error: aborting due to 1 previous error
2814
2915For more information about this error, try `rustc --explain E0432`.
tests/ui/imports/shadow-glob-module-resolution-4.rs-2
......@@ -12,8 +12,6 @@ use e as b;
1212
1313use b::C as e;
1414//~^ ERROR: unresolved import `b::C`
15//~| ERROR: cannot determine resolution for the import
16//~| ERROR: cannot determine resolution for the import
1715
1816fn e() {}
1917
tests/ui/imports/shadow-glob-module-resolution-4.stderr+1-15
......@@ -1,23 +1,9 @@
1error: cannot determine resolution for the import
2 --> $DIR/shadow-glob-module-resolution-4.rs:13:5
3 |
4LL | use b::C as e;
5 | ^^^^^^^^^
6
7error: cannot determine resolution for the import
8 --> $DIR/shadow-glob-module-resolution-4.rs:13:5
9 |
10LL | use b::C as e;
11 | ^^^^^^^^^
12 |
13 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14
151error[E0432]: unresolved import `b::C`
162 --> $DIR/shadow-glob-module-resolution-4.rs:13:5
173 |
184LL | use b::C as e;
195 | ^^^^^^^^^
206
21error: aborting due to 3 previous errors
7error: aborting due to 1 previous error
228
239For more information about this error, try `rustc --explain E0432`.
tests/ui/issues/issue-21033.rs deleted-47
......@@ -1,47 +0,0 @@
1//@ run-pass
2#![allow(unused_mut)]
3#![allow(unused_variables)]
4
5#![feature(box_patterns)]
6
7enum E {
8 StructVar { boxed: Box<i32> }
9}
10
11fn main() {
12
13 // Test matching each shorthand notation for field patterns.
14 let mut a = E::StructVar { boxed: Box::new(3) };
15 match a {
16 E::StructVar { box boxed } => { }
17 }
18 match a {
19 E::StructVar { box ref boxed } => { }
20 }
21 match a {
22 E::StructVar { box mut boxed } => { }
23 }
24 match a {
25 E::StructVar { box ref mut boxed } => { }
26 }
27 match a {
28 E::StructVar { ref boxed } => { }
29 }
30 match a {
31 E::StructVar { ref mut boxed } => { }
32 }
33 match a {
34 E::StructVar { mut boxed } => { }
35 }
36
37 // Test matching non shorthand notation. Recreate a since last test
38 // moved `boxed`
39 let mut a = E::StructVar { boxed: Box::new(3) };
40 match a {
41 E::StructVar { boxed: box ref mut num } => { }
42 }
43 match a {
44 E::StructVar { boxed: ref mut num } => { }
45 }
46
47}
tests/ui/issues/issue-29516.rs deleted-20
......@@ -1,20 +0,0 @@
1//@ check-pass
2#![feature(auto_traits)]
3#![feature(negative_impls)]
4
5auto trait NotSame {}
6
7impl<A> !NotSame for (A, A) {}
8
9trait OneOfEach {}
10
11impl<A> OneOfEach for (A,) {}
12
13impl<A, B> OneOfEach for (A, B)
14where
15 (B,): OneOfEach,
16 (A, B): NotSame,
17{
18}
19
20fn main() {}
tests/ui/issues/issue-3154.rs deleted-11
......@@ -1,11 +0,0 @@
1struct Thing<'a, Q:'a> {
2 x: &'a Q
3}
4
5fn thing<'a,Q>(x: &Q) -> Thing<'a,Q> {
6 Thing { x: x } //~ ERROR explicit lifetime required in the type of `x` [E0621]
7}
8
9fn main() {
10 thing(&());
11}
tests/ui/issues/issue-3154.stderr deleted-14
......@@ -1,14 +0,0 @@
1error[E0621]: explicit lifetime required in the type of `x`
2 --> $DIR/issue-3154.rs:6:5
3 |
4LL | Thing { x: x }
5 | ^^^^^^^^^^^^^^ lifetime `'a` required
6 |
7help: add explicit lifetime `'a` to the type of `x`
8 |
9LL | fn thing<'a,Q>(x: &'a Q) -> Thing<'a,Q> {
10 | ++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0621`.
tests/ui/issues/issue-32782.rs deleted-15
......@@ -1,15 +0,0 @@
1macro_rules! bar (
2 () => ()
3);
4
5macro_rules! foo (
6 () => (
7 #[allow_internal_unstable()]
8 //~^ ERROR allow_internal_unstable side-steps
9 //~| ERROR `#[allow_internal_unstable]` attribute cannot be used on macro calls
10 bar!();
11 );
12);
13
14foo!();
15fn main() {}
tests/ui/issues/issue-32782.stderr deleted-28
......@@ -1,28 +0,0 @@
1error[E0658]: allow_internal_unstable side-steps feature gating and stability checks
2 --> $DIR/issue-32782.rs:7:9
3 |
4LL | #[allow_internal_unstable()]
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6...
7LL | foo!();
8 | ------ in this macro invocation
9 |
10 = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable
11 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
12 = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
13
14error: `#[allow_internal_unstable]` attribute cannot be used on macro calls
15 --> $DIR/issue-32782.rs:7:9
16 |
17LL | #[allow_internal_unstable()]
18 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19...
20LL | foo!();
21 | ------ in this macro invocation
22 |
23 = help: `#[allow_internal_unstable]` can be applied to functions and macro defs
24 = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
25
26error: aborting due to 2 previous errors
27
28For more information about this error, try `rustc --explain E0658`.
tests/ui/issues/issue-3874.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ build-pass
2#![allow(dead_code)]
3
4enum PureCounter { PureCounterVariant(usize) }
5
6fn each<F>(thing: PureCounter, blk: F) where F: FnOnce(&usize) {
7 let PureCounter::PureCounterVariant(ref x) = thing;
8 blk(x);
9}
10
11pub fn main() {}
tests/ui/issues/issue-5100.rs deleted-58
......@@ -1,58 +0,0 @@
1//@ dont-require-annotations: NOTE
2
3#![feature(box_patterns)]
4
5enum A { B, C }
6
7fn main() {
8 match (true, false) {
9 A::B => (),
10//~^ ERROR mismatched types
11//~| NOTE expected `(bool, bool)`, found `A`
12//~| NOTE expected tuple `(bool, bool)`
13//~| NOTE found enum `A`
14 _ => ()
15 }
16
17 match (true, false) {
18 (true, false, false) => ()
19//~^ ERROR mismatched types
20//~| NOTE expected a tuple with 2 elements, found one with 3 elements
21//~| NOTE expected tuple `(bool, bool)`
22//~| NOTE found tuple `(_, _, _)`
23 }
24
25 match (true, false) {
26 (true, false, false) => ()
27//~^ ERROR mismatched types
28//~| NOTE expected a tuple with 2 elements, found one with 3 elements
29//~| NOTE expected tuple `(bool, bool)`
30//~| NOTE found tuple `(_, _, _)`
31 }
32
33 match (true, false) {
34 box (true, false) => ()
35//~^ ERROR mismatched types
36//~| NOTE expected tuple `(bool, bool)`
37//~| NOTE found struct `Box<_>`
38 }
39
40 match (true, false) {
41 &(true, false) => ()
42//~^ ERROR mismatched types
43//~| NOTE expected `(bool, bool)`, found `&_`
44//~| NOTE expected tuple `(bool, bool)`
45//~| NOTE found reference `&_`
46 }
47
48
49 let v = [('a', 'b') //~ ERROR expected function, found `(char, char)`
50 ('c', 'd'),
51 ('e', 'f')];
52
53 for &(x,y) in &v {} // should be OK
54
55 // Make sure none of the errors above were fatal
56 let x: char = true; //~ ERROR mismatched types
57 //~| NOTE expected `char`, found `bool`
58}
tests/ui/issues/issue-5100.stderr deleted-73
......@@ -1,73 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-5100.rs:9:9
3 |
4LL | match (true, false) {
5 | ------------- this expression has type `(bool, bool)`
6LL | A::B => (),
7 | ^^^^ expected `(bool, bool)`, found `A`
8 |
9 = note: expected tuple `(bool, bool)`
10 found enum `A`
11
12error[E0308]: mismatched types
13 --> $DIR/issue-5100.rs:18:9
14 |
15LL | match (true, false) {
16 | ------------- this expression has type `(bool, bool)`
17LL | (true, false, false) => ()
18 | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
19 |
20 = note: expected tuple `(bool, bool)`
21 found tuple `(_, _, _)`
22
23error[E0308]: mismatched types
24 --> $DIR/issue-5100.rs:26:9
25 |
26LL | match (true, false) {
27 | ------------- this expression has type `(bool, bool)`
28LL | (true, false, false) => ()
29 | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
30 |
31 = note: expected tuple `(bool, bool)`
32 found tuple `(_, _, _)`
33
34error[E0308]: mismatched types
35 --> $DIR/issue-5100.rs:34:9
36 |
37LL | match (true, false) {
38 | ------------- this expression has type `(bool, bool)`
39LL | box (true, false) => ()
40 | ^^^^^^^^^^^^^^^^^ expected `(bool, bool)`, found `Box<_>`
41 |
42 = note: expected tuple `(bool, bool)`
43 found struct `Box<_>`
44
45error[E0308]: mismatched types
46 --> $DIR/issue-5100.rs:41:9
47 |
48LL | match (true, false) {
49 | ------------- this expression has type `(bool, bool)`
50LL | &(true, false) => ()
51 | ^^^^^^^^^^^^^^ expected `(bool, bool)`, found `&_`
52 |
53 = note: expected tuple `(bool, bool)`
54 found reference `&_`
55
56error[E0618]: expected function, found `(char, char)`
57 --> $DIR/issue-5100.rs:49:14
58 |
59LL | let v = [('a', 'b')
60 | ^^^^^^^^^^- help: consider separating array elements with a comma: `,`
61
62error[E0308]: mismatched types
63 --> $DIR/issue-5100.rs:56:19
64 |
65LL | let x: char = true;
66 | ---- ^^^^ expected `char`, found `bool`
67 | |
68 | expected due to this
69
70error: aborting due to 7 previous errors
71
72Some errors have detailed explanations: E0308, E0618.
73For more information about an error, try `rustc --explain E0308`.
tests/ui/lifetimes/missing-lifetime-in-return.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/3154
2
3struct Thing<'a, Q:'a> {
4 x: &'a Q
5}
6
7fn thing<'a,Q>(x: &Q) -> Thing<'a,Q> {
8 Thing { x: x } //~ ERROR explicit lifetime required in the type of `x` [E0621]
9}
10
11fn main() {
12 thing(&());
13}
tests/ui/lifetimes/missing-lifetime-in-return.stderr created+14
......@@ -0,0 +1,14 @@
1error[E0621]: explicit lifetime required in the type of `x`
2 --> $DIR/missing-lifetime-in-return.rs:8:5
3 |
4LL | Thing { x: x }
5 | ^^^^^^^^^^^^^^ lifetime `'a` required
6 |
7help: add explicit lifetime `'a` to the type of `x`
8 |
9LL | fn thing<'a,Q>(x: &'a Q) -> Thing<'a,Q> {
10 | ++
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0621`.
tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.rs+2-1
......@@ -1,5 +1,6 @@
11// Test for #151358, assertion failed: !worker_thread.is_null()
2//~^ ERROR cycle detected when looking up span for `Default`
2//~^ ERROR internal compiler error: query cycle when printing cycle detected
3//~^^ ERROR cycle detected when getting the resolver for lowering
34//
45//@ compile-flags: -Z threads=2
56//@ compare-output-by-lines
tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr+16-4
......@@ -1,9 +1,21 @@
1error[E0391]: cycle detected when looking up span for `Default`
1error: internal compiler error: query cycle when printing cycle detected
22 |
3 = note: ...which immediately requires looking up span for `Default` again
4 = note: cycle used when perform lints prior to AST lowering
3 = note: ...when getting HIR ID of `Default`
4 = note: ...which requires getting the crate HIR...
5 = note: ...which requires perform lints prior to AST lowering...
6 = note: ...which requires looking up span for `Default`...
7 = note: ...which again requires getting HIR ID of `Default`, completing the cycle
8 = note: cycle used when getting the resolver for lowering
59 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
610
7error: aborting due to 1 previous error
11error[E0391]: cycle detected when getting the resolver for lowering
12 |
13 = note: ...which requires getting HIR ID of `Default`...
14 = note: ...which requires getting the crate HIR...
15 = note: ...which requires perform lints prior to AST lowering...
16 = note: ...which again requires getting the resolver for lowering, completing the cycle
17 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
18
19error: aborting due to 2 previous errors
820
921For more information about this error, try `rustc --explain E0391`.
tests/ui/pattern/match-errors-derived-error-suppression.rs created+59
......@@ -0,0 +1,59 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/5100>
2//@ dont-require-annotations: NOTE
3
4#![feature(box_patterns)]
5
6enum A { B, C }
7
8fn main() {
9 match (true, false) {
10 A::B => (),
11//~^ ERROR mismatched types
12//~| NOTE expected `(bool, bool)`, found `A`
13//~| NOTE expected tuple `(bool, bool)`
14//~| NOTE found enum `A`
15 _ => ()
16 }
17
18 match (true, false) {
19 (true, false, false) => ()
20//~^ ERROR mismatched types
21//~| NOTE expected a tuple with 2 elements, found one with 3 elements
22//~| NOTE expected tuple `(bool, bool)`
23//~| NOTE found tuple `(_, _, _)`
24 }
25
26 match (true, false) {
27 (true, false, false) => ()
28//~^ ERROR mismatched types
29//~| NOTE expected a tuple with 2 elements, found one with 3 elements
30//~| NOTE expected tuple `(bool, bool)`
31//~| NOTE found tuple `(_, _, _)`
32 }
33
34 match (true, false) {
35 box (true, false) => ()
36//~^ ERROR mismatched types
37//~| NOTE expected tuple `(bool, bool)`
38//~| NOTE found struct `Box<_>`
39 }
40
41 match (true, false) {
42 &(true, false) => ()
43//~^ ERROR mismatched types
44//~| NOTE expected `(bool, bool)`, found `&_`
45//~| NOTE expected tuple `(bool, bool)`
46//~| NOTE found reference `&_`
47 }
48
49
50 let v = [('a', 'b') //~ ERROR expected function, found `(char, char)`
51 ('c', 'd'),
52 ('e', 'f')];
53
54 for &(x,y) in &v {} // should be OK
55
56 // Make sure none of the errors above were fatal
57 let x: char = true; //~ ERROR mismatched types
58 //~| NOTE expected `char`, found `bool`
59}
tests/ui/pattern/match-errors-derived-error-suppression.stderr created+73
......@@ -0,0 +1,73 @@
1error[E0308]: mismatched types
2 --> $DIR/match-errors-derived-error-suppression.rs:10:9
3 |
4LL | match (true, false) {
5 | ------------- this expression has type `(bool, bool)`
6LL | A::B => (),
7 | ^^^^ expected `(bool, bool)`, found `A`
8 |
9 = note: expected tuple `(bool, bool)`
10 found enum `A`
11
12error[E0308]: mismatched types
13 --> $DIR/match-errors-derived-error-suppression.rs:19:9
14 |
15LL | match (true, false) {
16 | ------------- this expression has type `(bool, bool)`
17LL | (true, false, false) => ()
18 | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
19 |
20 = note: expected tuple `(bool, bool)`
21 found tuple `(_, _, _)`
22
23error[E0308]: mismatched types
24 --> $DIR/match-errors-derived-error-suppression.rs:27:9
25 |
26LL | match (true, false) {
27 | ------------- this expression has type `(bool, bool)`
28LL | (true, false, false) => ()
29 | ^^^^^^^^^^^^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
30 |
31 = note: expected tuple `(bool, bool)`
32 found tuple `(_, _, _)`
33
34error[E0308]: mismatched types
35 --> $DIR/match-errors-derived-error-suppression.rs:35:9
36 |
37LL | match (true, false) {
38 | ------------- this expression has type `(bool, bool)`
39LL | box (true, false) => ()
40 | ^^^^^^^^^^^^^^^^^ expected `(bool, bool)`, found `Box<_>`
41 |
42 = note: expected tuple `(bool, bool)`
43 found struct `Box<_>`
44
45error[E0308]: mismatched types
46 --> $DIR/match-errors-derived-error-suppression.rs:42:9
47 |
48LL | match (true, false) {
49 | ------------- this expression has type `(bool, bool)`
50LL | &(true, false) => ()
51 | ^^^^^^^^^^^^^^ expected `(bool, bool)`, found `&_`
52 |
53 = note: expected tuple `(bool, bool)`
54 found reference `&_`
55
56error[E0618]: expected function, found `(char, char)`
57 --> $DIR/match-errors-derived-error-suppression.rs:50:14
58 |
59LL | let v = [('a', 'b')
60 | ^^^^^^^^^^- help: consider separating array elements with a comma: `,`
61
62error[E0308]: mismatched types
63 --> $DIR/match-errors-derived-error-suppression.rs:57:19
64 |
65LL | let x: char = true;
66 | ---- ^^^^ expected `char`, found `bool`
67 | |
68 | expected due to this
69
70error: aborting due to 7 previous errors
71
72Some errors have detailed explanations: E0308, E0618.
73For more information about an error, try `rustc --explain E0308`.
tests/ui/pattern/match-struct-var-having-boxed-field.rs created+48
......@@ -0,0 +1,48 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/21033>
2//@ run-pass
3#![allow(unused_mut)]
4#![allow(unused_variables)]
5
6#![feature(box_patterns)]
7
8enum E {
9 StructVar { boxed: Box<i32> }
10}
11
12fn main() {
13
14 // Test matching each shorthand notation for field patterns.
15 let mut a = E::StructVar { boxed: Box::new(3) };
16 match a {
17 E::StructVar { box boxed } => { }
18 }
19 match a {
20 E::StructVar { box ref boxed } => { }
21 }
22 match a {
23 E::StructVar { box mut boxed } => { }
24 }
25 match a {
26 E::StructVar { box ref mut boxed } => { }
27 }
28 match a {
29 E::StructVar { ref boxed } => { }
30 }
31 match a {
32 E::StructVar { ref mut boxed } => { }
33 }
34 match a {
35 E::StructVar { mut boxed } => { }
36 }
37
38 // Test matching non shorthand notation. Recreate a since last test
39 // moved `boxed`
40 let mut a = E::StructVar { boxed: Box::new(3) };
41 match a {
42 E::StructVar { boxed: box ref mut num } => { }
43 }
44 match a {
45 E::StructVar { boxed: ref mut num } => { }
46 }
47
48}
tests/ui/query-system/query-cycle-printing-issue-151358.rs+2-1
......@@ -1,4 +1,5 @@
1//~ ERROR: cycle detected when looking up span for `Default`
1//~ ERROR: cycle when printing cycle detected
2//~^ ERROR: cycle detected
23trait Default {}
34use std::num::NonZero;
45fn main() {
tests/ui/query-system/query-cycle-printing-issue-151358.stderr+16-4
......@@ -1,9 +1,21 @@
1error[E0391]: cycle detected when looking up span for `Default`
1error: internal compiler error: query cycle when printing cycle detected
22 |
3 = note: ...which immediately requires looking up span for `Default` again
4 = note: cycle used when perform lints prior to AST lowering
3 = note: ...when getting HIR ID of `Default`
4 = note: ...which requires getting the crate HIR...
5 = note: ...which requires perform lints prior to AST lowering...
6 = note: ...which requires looking up span for `Default`...
7 = note: ...which again requires getting HIR ID of `Default`, completing the cycle
8 = note: cycle used when getting the resolver for lowering
59 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
610
7error: aborting due to 1 previous error
11error[E0391]: cycle detected when getting the resolver for lowering
12 |
13 = note: ...which requires getting HIR ID of `Default`...
14 = note: ...which requires getting the crate HIR...
15 = note: ...which requires perform lints prior to AST lowering...
16 = note: ...which again requires getting the resolver for lowering, completing the cycle
17 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
18
19error: aborting due to 2 previous errors
820
921For more information about this error, try `rustc --explain E0391`.
tests/ui/resolve/query-cycle-issue-124901.rs+2-1
......@@ -1,4 +1,5 @@
1//~ ERROR: cycle detected when looking up span for `Default`
1//~ ERROR: cycle when printing cycle detected
2//~^ ERROR: cycle detected
23trait Default {
34 type Id;
45
tests/ui/resolve/query-cycle-issue-124901.stderr+16-4
......@@ -1,9 +1,21 @@
1error[E0391]: cycle detected when looking up span for `Default`
1error: internal compiler error: query cycle when printing cycle detected
22 |
3 = note: ...which immediately requires looking up span for `Default` again
4 = note: cycle used when perform lints prior to AST lowering
3 = note: ...when getting HIR ID of `Default`
4 = note: ...which requires getting the crate HIR...
5 = note: ...which requires perform lints prior to AST lowering...
6 = note: ...which requires looking up span for `Default`...
7 = note: ...which again requires getting HIR ID of `Default`, completing the cycle
8 = note: cycle used when getting the resolver for lowering
59 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
610
7error: aborting due to 1 previous error
11error[E0391]: cycle detected when getting the resolver for lowering
12 |
13 = note: ...which requires getting HIR ID of `Default`...
14 = note: ...which requires getting the crate HIR...
15 = note: ...which requires perform lints prior to AST lowering...
16 = note: ...which again requires getting the resolver for lowering, completing the cycle
17 = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
18
19error: aborting due to 2 previous errors
820
921For more information about this error, try `rustc --explain E0391`.
tests/ui/scalable-vectors/transmute.rs created+39
......@@ -0,0 +1,39 @@
1//@ build-pass
2//@ compile-flags: -Copt-level=3
3//@ only-aarch64
4#![crate_type = "lib"]
5#![allow(incomplete_features, internal_features, dead_code, improper_ctypes)]
6#![allow(nonstandard_style, private_interfaces)]
7#![feature(abi_unadjusted, link_llvm_intrinsics, rustc_attrs)]
8
9// Tests that use of transmute between `svuint8x2_t` and `svint8x2_t` builds with optimisations
10// without any failures from LLVM.
11
12use std::mem::transmute;
13
14#[rustc_scalable_vector(16)]
15struct svbool_t(bool);
16
17#[rustc_scalable_vector(16)]
18struct svuint8_t(u8);
19
20#[rustc_scalable_vector]
21struct svuint8x2_t(svuint8_t, svuint8_t);
22
23#[rustc_scalable_vector(16)]
24struct svint8_t(i8);
25
26#[rustc_scalable_vector]
27struct svint8x2_t(svint8_t, svint8_t);
28
29#[target_feature(enable = "sve")]
30pub unsafe fn svld2_u8(pg: svbool_t, base: *const i8) -> svuint8x2_t {
31 unsafe extern "unadjusted" {
32 #[cfg_attr(
33 target_arch = "aarch64",
34 link_name = "llvm.aarch64.sve.ld2.sret.nxv16i8"
35 )]
36 fn _svld2_s8(pg: svbool_t, base: *const i8) -> svint8x2_t;
37 }
38 transmute(_svld2_s8(pg, base))
39}