diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 4bb497097c1de..5efec6bcf770f 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -430,6 +430,26 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { ), ); } + + // Call arguments are moved by reference, so they must be plain locals + // or the contents of a box; other moved places violate MIR invariants. + if self.tcx.sess.opts.unstable_opts.validate_mir + && self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) + { + let is_plain_local = place.projection.is_empty(); + let is_box_deref = + matches!(place.projection.as_ref(), [ProjectionElem::Deref]) + && self.body.local_decls[place.local].ty.is_box(); + if !is_plain_local && !is_box_deref { + self.fail( + location, + format!( + "encountered `Move` of a non-local, non-box place in `Call` terminator: {:?}", + terminator.kind, + ), + ); + } + } } } diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index e1d2b53366066..8a437c4995724 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -48,11 +48,15 @@ decl_derive!( /// struct Foo { /// #[generic_type_visitable(bounds())] /// just_self: Box, - /// #[generic_type_visitable(bounds(Bar: GenericTypeVisitable))] + /// #[generic_type_visitable(bounds(Bar: GenericTypeVisitable<__V>))] /// contains_self: (Box, Bar), /// } /// struct Bar; /// ``` + /// + /// Note: the `__V` lifetime is an implementation detail of the derive macro. + /// We could probably handle this in a nicer way, but we don't expect this form + /// to really be necessary any time soon, so for now we don't. customizable_type_visitable_derive ); @@ -461,7 +465,7 @@ mod kw { /// Parses a bound like: /// /// ```ignore (would need to import GenericTypeVisitable to get this to compile) -/// #[generic_type_visitable(bounds(Foo: GenericTypeVisitable, Bar: GenericTypeVisitable))] +/// #[generic_type_visitable(bounds(Foo: GenericTypeVisitable<__V>, Bar: GenericTypeVisitable<__V>))] /// ``` fn parse_generic_type_visitable_bound( attr: &Attribute, diff --git a/library/core/src/time.rs b/library/core/src/time.rs index f9e2dc6b7f849..c123c66ee3bc0 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -345,7 +345,7 @@ impl Duration { /// Creates a new `Duration` from the specified number of weeks. /// - /// For this method, one week is defined as 7 days, or 604,800 seconds. + /// For this function, one week is defined as 7 days, or 604,800 seconds. /// /// # Panics /// @@ -375,7 +375,7 @@ impl Duration { /// Creates a new `Duration` from the specified number of days. /// - /// For this method, one day is defined as 24 hours, or 86,400 seconds. + /// For this function, one day is defined as 24 hours, or 86,400 seconds. /// /// # Panics /// @@ -405,7 +405,7 @@ impl Duration { /// Creates a new `Duration` from the specified number of hours. /// - /// For this method, one hour is defined as 60 minutes, or 3,600 seconds. + /// For this function, one hour is defined as 60 minutes, or 3,600 seconds. /// /// # Panics /// @@ -435,7 +435,7 @@ impl Duration { /// Creates a new `Duration` from the specified number of minutes. /// - /// For this method, one minute is defined as 60 seconds. + /// For this function, one minute is defined as 60 seconds. /// /// # Panics /// diff --git a/src/doc/book b/src/doc/book index 917544888a55e..1500248d8f230 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 917544888a55e4da7109bdba8c88c893c0da70f4 +Subproject commit 1500248d8f230566e4ec9f27fcbb8fe9e2898ab1 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index f5abcf137698e..ab8544aeed7b7 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit f5abcf137698e5ad6ebed359d69654ff705346af +Subproject commit ab8544aeed7b792984366aa122ac19bd47ad9a2f diff --git a/src/doc/reference b/src/doc/reference index 3b38834b39f73..e24eecf97b0c9 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 3b38834b39f732c64686f7c64aa29dcf3cd83ba5 +Subproject commit e24eecf97b0c9a6dbac67191098204dc8a190aaa diff --git a/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md index 110fd1331bc44..2b06f5b414c1b 100644 --- a/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md +++ b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md @@ -115,7 +115,7 @@ For rust-analyzer, the corresponding implementations are located across several These two traits correspond to the role of [`InferCtxt`][rustc inferctxt] in rustc. [`InferCtxtLike`][ir inferctxtlike] must be defined in `rustc_infer` due to coherence -constraints(orphan rules). +constraints (orphan rules). As a result, it cannot provide functionality that lives in `rustc_trait_selection`. Instead, behavior that depends on trait-solving logic is abstracted into a separate trait, [`SolverDelegate`][ir solverdelegate]. @@ -214,9 +214,9 @@ non-obvious considerations: 1. The generic parameters `I` and `J` are reserved for `I: Interner` and `J` being the interner it is being lifted to. -2. `PhantomData` is handled automatically, creating a new `PhantomData` but - _has_ to be included in the file through; `use std::marker::PhantomData;` - you cannot use `std::marker::PhantomData` directly on the field of a struct. +2. `PhantomData` is handled automatically, creating a new `PhantomData`. But it + _has_ to be used in the fully unqualified form -- you cannot use + `std::marker::PhantomData` directly in the field. 3. The bounds are deliberately written as associated type bounds on the `Interner` trait rather than as `where` clauses on `LiftInto`. Given only `I: LiftInto`, Rust can then treat bounds such as the following as implied: @@ -255,12 +255,6 @@ There is intentionally no ignore attribute. The traversal must visit every field. This is a soundness requirement for rust-analyzer's use of the traversal when tracing and garbage-collecting interned types. -When the macro crate's `nightly` feature is enabled, the derive macro remains -registered but emits no tokens. The `GenericTypeVisitable` trait and its -traversal module are also excluded from the nightly configuration of -`rustc_type_ir`; they exist only in its non-nightly configuration. - - ## Long-term plans for supporting rust-analyzer In general, we aim to support rust-analyzer just as well as rustc in these shared crates—provided @@ -310,4 +304,4 @@ There are still duplicated implementations between rustc and rust-analyzer—suc [r-a coerce]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/infer/coerce.rs [rustc_lift]: https://github.com/rust-lang/rust/blob/0913b18e489ac1011b580e31fa5559654be12bfc/compiler/rustc_type_ir/src/lift.rs#L18 [rustc_typevisitable]: https://github.com/rust-lang/rust/blob/0913b18e489ac1011b580e31fa5559654be12bfc/compiler/rustc_type_ir/src/visit.rs#L62 -[rustc_typefoldable]: https://github.com/rust-lang/rust/blob/0913b18e489ac1011b580e31fa5559654be12bfc/compiler/rustc_type_ir/src/fold.rs#L71 \ No newline at end of file +[rustc_typefoldable]: https://github.com/rust-lang/rust/blob/0913b18e489ac1011b580e31fa5559654be12bfc/compiler/rustc_type_ir/src/fold.rs#L71 diff --git a/src/doc/rustc-dev-guide/src/solve/the-solver.md b/src/doc/rustc-dev-guide/src/solve/the-solver.md index 0151c0482d109..3d66ec272698d 100644 --- a/src/doc/rustc-dev-guide/src/solve/the-solver.md +++ b/src/doc/rustc-dev-guide/src/solve/the-solver.md @@ -7,7 +7,7 @@ as it is very similar to this implementation and also talks about limitations of ## A rough walkthrough -The entry-point of the solver is `InferCtxtEvalExt::evaluate_root_goal`. +The entry-point of the solver is `SolverDelegateEvalExt::evaluate_root_goal`. This function sets up the root `EvalCtxt` and then calls `EvalCtxt::evaluate_goal`, to actually enter the trait solver. diff --git a/src/doc/rustc/src/platform-support/windows-gnu.md b/src/doc/rustc/src/platform-support/windows-gnu.md index d7aec5af21dec..595c2a42c81a4 100644 --- a/src/doc/rustc/src/platform-support/windows-gnu.md +++ b/src/doc/rustc/src/platform-support/windows-gnu.md @@ -34,6 +34,7 @@ The targets are built and tested using a reasonably modern C toolchain, and it s * GCC 14.2 * mingw-w64 12.0.0 * MSVCRT library as the default +* Libgcc with DWARF-2 exception handling for i686 and SEH for x86_64 Using older tools (especially Binutils) may not work properly, due to the number of issues plaguing older versions of Binutils. The supported toolchain versions are subject to change. diff --git a/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.rs b/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.rs new file mode 100644 index 0000000000000..af44ff7e92252 --- /dev/null +++ b/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.rs @@ -0,0 +1,19 @@ +//@ edition: 2024 +//@ check-fail + +#![crate_type = "rlib"] +#![feature(rustc_private)] + +extern crate rustc_type_ir; +extern crate rustc_type_ir_macros; + +use rustc_type_ir_macros::GenericTypeVisitable; + +#[derive(GenericTypeVisitable)] +struct MissingBound { + // This should fail, as `T: GenericTypeVisitable<__V>` wasn't specified + #[generic_type_visitable(bounds())] + //~^ ERROR: the trait bound `T: GenericTypeVisitable<__V>` is not satisfied + partially_rec: (Vec, T), + other: u32, +} diff --git a/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.stderr b/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.stderr new file mode 100644 index 0000000000000..44433984e4a7f --- /dev/null +++ b/tests/ui-fulldeps/derive-generic-type-visitable-missing-bound.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `T: GenericTypeVisitable<__V>` is not satisfied + --> $DIR/derive-generic-type-visitable-missing-bound.rs:15:5 + | +LL | #[derive(GenericTypeVisitable)] + | -------------------- + | | + | required by a bound introduced by this call + | in this derive macro expansion +... +LL | #[generic_type_visitable(bounds())] + | ^ the nightly-only, unstable trait `GenericTypeVisitable<__V>` is not implemented for `T` + | + = note: required for `(Vec>, T)` to implement `GenericTypeVisitable<__V>` + = note: this error originates in the derive macro `GenericTypeVisitable` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/derive-generic-type-visitable.rs b/tests/ui-fulldeps/derive-generic-type-visitable.rs new file mode 100644 index 0000000000000..91c7a502a87d8 --- /dev/null +++ b/tests/ui-fulldeps/derive-generic-type-visitable.rs @@ -0,0 +1,119 @@ +//@ edition: 2024 +//@ run-pass + +#![feature(rustc_private)] + +extern crate rustc_type_ir; +extern crate rustc_type_ir_macros; + +use rustc_type_ir::GenericTypeVisitable; +use rustc_type_ir_macros::GenericTypeVisitable; + +// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta +// files. +#[expect(unused_extern_crates)] +extern crate rustc_driver; + +#[derive(GenericTypeVisitable)] +struct DerivesGenericTypeVisitable; + +#[derive(GenericTypeVisitable)] +struct Foo { + one: Incrementer, + two: Vec, +} + +#[derive(GenericTypeVisitable)] +enum Enum { + A, + B(Incrementer), + C { one: Incrementer, two: Vec }, +} + +#[derive(GenericTypeVisitable)] +struct Generic(Vec); + +#[derive(GenericTypeVisitable)] +struct Recursive { + #[generic_type_visitable(bounds())] + rec: Vec, + other: Incrementer, +} + +#[derive(GenericTypeVisitable)] +struct PartiallyRecursiveField { + #[generic_type_visitable(bounds(T: GenericTypeVisitable<__V>))] + partially_rec: (Vec, T), + other: Incrementer, +} + +// start testing setup + +use std::sync::atomic::{AtomicU8, Ordering}; + +static COUNT: AtomicU8 = AtomicU8::new(0); + +/// A type that, when visited, increments a global counter. +/// +/// Used to (weakly) test the correctness of the derive by making sure that +/// it traverses all the fields, and thus reaches all the incrementers. +#[derive(Clone)] +struct Incrementer; + +unsafe impl GenericTypeVisitable for Incrementer { + fn generic_visit_with(&self, _visitor: &mut V) { + COUNT.fetch_add(1, Ordering::Relaxed); + } +} + +// end testing setup + +fn main() { + use Incrementer as Inc; // for brevity + + #[track_caller] + fn check>(item: T, count: u8) { + let mut v = (); + item.generic_visit_with(&mut v); + assert_eq!(COUNT.swap(0, Ordering::Relaxed), count); + } + + check(DerivesGenericTypeVisitable, 0); + check(Foo { one: Inc, two: vec![] }, 1); + check(Foo { one: Inc, two: vec![Inc; 2] }, 1 + 2); + check(Enum::A, 0); + check(Enum::B(Inc), 1); + check(Enum::C { one: Inc, two: vec![] }, 1); + check(Enum::C { one: Inc, two: vec![Inc; 3] }, 1 + 3); + check(Generic::(vec![]), 0); + // visits each of the nested `Inc`s + check(Generic(vec![Inc; 5]), 5); + + // Every (nested) `rec!` adds another `Recursive`, and thus 1 more visited `Inc`. + macro_rules! rec { + [$($i:expr),* $(,)?] => { + Recursive { rec: vec![$($i),*], other: Inc } + } + } + check(rec![], 1); + check(rec![rec![]], 2); + check(rec![rec![], rec![]], 3); + check(rec![rec![rec![]]], 3); + + // Every (nested) `prec!` adds another `PartiallyRecursiveField`, and thus 1 more visited `Inc`. + macro_rules! prec { + ([$($i:expr),* $(,)?], $o:expr) => { + PartiallyRecursiveField { partially_rec: (vec![$($i),*], $o), other: Inc } + } + } + // Every nested `a()`, `b()`, and `c()` adds 0, 1, and 2 more visited `Inc`s, respectively. + let a = || Enum::A; + let b = || Enum::B(Inc); + let c = || Enum::C { one: Inc, two: vec![Inc] }; + check(prec!([], a()), 1 + 0); + check(prec!([], b()), 1 + 1); + check(prec!([], c()), 1 + 2); + check(prec!([prec!([], a())], a()), 1 + (1 + 0) + 0); + check(prec!([prec!([], b())], a()), 1 + (1 + 1) + 0); + check(prec!([prec!([], b())], b()), 1 + (1 + 1) + 1); +} diff --git a/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs index 9c9085ca1daca..64cea66c1d565 100644 --- a/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs +++ b/tests/ui/explicit-tail-calls/tailcc-no-signature-restriction.rs @@ -1,9 +1,9 @@ //@ run-pass //@ ignore-backends: gcc -//@ min-llvm-version: 22 -//@ revisions: x86_64 aarch64 +//@ min-llvm-version: 23 +//@ revisions: x86 x86_64 aarch64 // -// FIXME: enable x86 on LLVM 23. +//@ [x86] only-x86 //@ [x86_64] only-x86_64 //@ [aarch64] only-aarch64 #![feature(explicit_tail_calls, rust_tail_cc)] @@ -18,6 +18,7 @@ pub extern "tail" fn add() -> u64 { become add(1, 2); } +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(windows)))] #[inline(never)] pub extern "tail" fn pass_struct(a: u64, d: u64) -> u64 { #[derive(Clone, Copy)] @@ -42,8 +43,7 @@ pub extern "tail" fn pass_struct(a: u64, d: u64) -> u64 { fn main() { assert_eq!(add(), 3); - // FIXME: LLVM 22 has a bug which makes this miscompile. - if false { - assert_eq!(pass_struct(5, 6), 5 + 6); - } + // Windows and Aarch64 in LLVM 23 does not support byval arguments. + #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(windows)))] + assert_eq!(pass_struct(5, 6), 5 + 6); } diff --git a/tests/ui/mir/validate/call-move-arg.rs b/tests/ui/mir/validate/call-move-arg.rs new file mode 100644 index 0000000000000..a6e01f264a986 --- /dev/null +++ b/tests/ui/mir/validate/call-move-arg.rs @@ -0,0 +1,28 @@ +// Check that validation rejects moving a non-local, non-box place as a +// `Call` argument. +// +//@ failure-status: 101 +//@ dont-check-compiler-stderr +//@ compile-flags: -Zvalidate-mir + +#![feature(custom_mir, core_intrinsics)] +extern crate core; +use core::intrinsics::mir::*; + +fn bar(_x: i32) {} + +#[custom_mir(dialect = "built")] +pub fn main() { + mir! { + let a: (i32, i32); + { + a = (1, 2); + Call(RET = bar(Move(a.0)), ReturnTo(retblock), UnwindContinue()) + //~^ ERROR broken MIR in + //~| ERROR encountered `Move` of a non-local, non-box place in `Call` terminator + } + retblock = { + Return() + } + } +}