diff --git a/Cargo.lock b/Cargo.lock index 92a9013ca2575..e67898756fad5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -686,6 +686,7 @@ dependencies = [ "anyhow", "serde", "serde_json", + "similar", "spdx-rs", ] diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 4a749642265df..c4ad8e4d075f7 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -13,7 +13,7 @@ use crate::builder::{Builder, PlaceRef, UNNAMED}; use crate::context::SimpleCx; use crate::declare::declare_simple_fn; use crate::llvm; -use crate::llvm::{Metadata, TRUE, Type}; +use crate::llvm::{TRUE, Type}; use crate::value::Value; pub(crate) fn adjust_activity_to_abi<'tcx>( @@ -159,32 +159,36 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( let mut outer_pos: usize = 0; let mut activity_pos = 0; - let enzyme_const = cx.create_metadata(b"enzyme_const"); - let enzyme_out = cx.create_metadata(b"enzyme_out"); - let enzyme_dup = cx.create_metadata(b"enzyme_dup"); - let enzyme_dupv = cx.create_metadata(b"enzyme_dupv"); - let enzyme_dupnoneed = cx.create_metadata(b"enzyme_dupnoneed"); - let enzyme_dupnoneedv = cx.create_metadata(b"enzyme_dupnoneedv"); + // We used to use llvm's metadata to instruct enzyme how to differentiate a function. + // In debug mode we would use incremental compilation which caused the metadata to be + // dropped. This is prevented by now using named globals, which are also understood + // by Enzyme. + let global_const = cx.declare_global("enzyme_const", cx.type_ptr()); + let global_out = cx.declare_global("enzyme_out", cx.type_ptr()); + let global_dup = cx.declare_global("enzyme_dup", cx.type_ptr()); + let global_dupv = cx.declare_global("enzyme_dupv", cx.type_ptr()); + let global_dupnoneed = cx.declare_global("enzyme_dupnoneed", cx.type_ptr()); + let global_dupnoneedv = cx.declare_global("enzyme_dupnoneedv", cx.type_ptr()); while activity_pos < inputs.len() { let diff_activity = inputs[activity_pos as usize]; // Duplicated arguments received a shadow argument, into which enzyme will write the // gradient. - let (activity, duplicated): (&Metadata, bool) = match diff_activity { + let (activity, duplicated): (&llvm::Value, bool) = match diff_activity { DiffActivity::None => panic!("not a valid input activity"), - DiffActivity::Const => (enzyme_const, false), - DiffActivity::Active => (enzyme_out, false), - DiffActivity::ActiveOnly => (enzyme_out, false), - DiffActivity::Dual => (enzyme_dup, true), - DiffActivity::Dualv => (enzyme_dupv, true), - DiffActivity::DualOnly => (enzyme_dupnoneed, true), - DiffActivity::DualvOnly => (enzyme_dupnoneedv, true), - DiffActivity::Duplicated => (enzyme_dup, true), - DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true), - DiffActivity::FakeActivitySize(_) => (enzyme_const, false), + DiffActivity::Const => (global_const, false), + DiffActivity::Active => (global_out, false), + DiffActivity::ActiveOnly => (global_out, false), + DiffActivity::Dual => (global_dup, true), + DiffActivity::Dualv => (global_dupv, true), + DiffActivity::DualOnly => (global_dupnoneed, true), + DiffActivity::DualvOnly => (global_dupnoneedv, true), + DiffActivity::Duplicated => (global_dup, true), + DiffActivity::DuplicatedOnly => (global_dupnoneed, true), + DiffActivity::FakeActivitySize(_) => (global_const, false), }; let outer_arg = outer_args[outer_pos]; - args.push(cx.get_metadata_value(activity)); + args.push(activity); if matches!(diff_activity, DiffActivity::Dualv) { let next_outer_arg = outer_args[outer_pos + 1]; let elem_bytes_size: u64 = match inputs[activity_pos + 1] { @@ -244,7 +248,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( assert_eq!(cx.type_kind(next_outer_ty3), TypeKind::Integer); args.push(next_outer_arg2); } - args.push(cx.get_metadata_value(enzyme_const)); + args.push(global_const); args.push(next_outer_arg); outer_pos += 2 + 2 * iterations; activity_pos += 2; @@ -353,13 +357,13 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( let mut args = Vec::with_capacity(num_args as usize + 1); args.push(fn_to_diff); - let enzyme_primal_ret = cx.create_metadata(b"enzyme_primal_return"); + let global_primal_ret = cx.declare_global("enzyme_primal_return", cx.type_ptr()); if matches!(attrs.ret_activity, DiffActivity::Dual | DiffActivity::Active) { - args.push(cx.get_metadata_value(enzyme_primal_ret)); + args.push(global_primal_ret); } if attrs.width > 1 { - let enzyme_width = cx.create_metadata(b"enzyme_width"); - args.push(cx.get_metadata_value(enzyme_width)); + let global_width = cx.declare_global("enzyme_width", cx.type_ptr()); + args.push(global_width); args.push(cx.get_const_int(cx.type_i64(), attrs.width as u64)); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 12f80a197b1b8..45b87cee957c9 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -7,9 +7,8 @@ use rustc_attr_parsing::is_doc_alias_attrs_contain_symbol; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use rustc_errors::Applicability; -use rustc_hir as hir; -use rustc_hir::HirId; use rustc_hir::def::DefKind; +use rustc_hir::{self as hir, ExprKind, HirId, Node}; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt}; @@ -486,13 +485,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty.value); let guar = match *ty.kind() { ty::Infer(ty::TyVar(_)) => { + // We want to get the variable name that the method + // is being called on. If it is a method call. + let err_span = match (mode, self.tcx.hir_node(scope_expr_id)) { + ( + Mode::MethodCall, + Node::Expr(hir::Expr { + kind: ExprKind::MethodCall(_, recv, ..), + .. + }), + ) => recv.span, + _ => span, + }; + let raw_ptr_call = bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types(); - // FIXME: Ideally we'd use the span of the self-expr here, - // not of the method path. + let mut err = self.err_ctxt().emit_inference_failure_err( self.body_id, - span, + err_span, ty.into(), TypeAnnotationNeeded::E0282, !raw_ptr_call, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index f1d19800a7891..eed27345b747b 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -839,7 +839,7 @@ pub enum PatKind<'tcx> { /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are /// much simpler. /// * raw pointers derived from integers, other raw pointers will have already resulted in an - // error. + /// error. /// * `String`, if `string_deref_patterns` is enabled. Constant { value: ty::Value<'tcx>, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 34ead91b4f6de..c27d47fcc0d8d 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -618,11 +618,11 @@ impl<'tcx> Instance<'tcx> { // be directly reified because it's closure-like. The reify can handle the // unresolved instance. resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } - // Reify `Trait::method` implementations - // FIXME(maurer) only reify it if it is a vtable-safe function + // Reify `Trait::method` implementations if the trait is dyn-compatible. } else if let Some(assoc) = tcx.opt_associated_item(def_id) && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = assoc.container + && tcx.is_dyn_compatible(assoc.container_id(tcx)) { // If this function could also go in a vtable, we need to `ReifyShim` it with // KCFI because it can only attach one type per function. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 36214dd1c3ed2..1318f28ff89f3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -309,6 +309,7 @@ symbols! { PathBuf, Pending, PinCoerceUnsized, + PinDerefMutHelper, Pointer, Poll, ProcMacro, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2f7109de804ae..1638c87c9ca9a 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1624,6 +1624,7 @@ supported_targets! { ("wasm32v1-none", wasm32v1_none), ("wasm32-wasip1", wasm32_wasip1), ("wasm32-wasip2", wasm32_wasip2), + ("wasm32-wasip3", wasm32_wasip3), ("wasm32-wasip1-threads", wasm32_wasip1_threads), ("wasm32-wali-linux-musl", wasm32_wali_linux_musl), ("wasm64-unknown-unknown", wasm64_unknown_unknown), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs new file mode 100644 index 0000000000000..e3d5e6542c263 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs @@ -0,0 +1,20 @@ +//! The `wasm32-wasip3` target is the next in the chain of `wasm32-wasip1`, then +//! `wasm32-wasip2`, then WASIp3. The main feature of WASIp3 is native async +//! support in the component model itself. +//! +//! Like `wasm32-wasip2` this target produces a component by default. Support +//! for `wasm32-wasip3` is very early as of the time of this writing so +//! components produced will still import WASIp2 APIs, but that's ok since it's +//! all component-model-level imports anyway. Over time the imports of the +//! standard library will change to WASIp3. + +use crate::spec::Target; + +pub(crate) fn target() -> Target { + // As of now WASIp3 is a lightly edited wasip2 target, so start with that + // and this may grow over time as more features are supported. + let mut target = super::wasm32_wasip2::target(); + target.llvm_target = "wasm32-wasip3".into(); + target.options.env = "p3".into(); + target +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 37e622102e70f..5665229a4cbe6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3476,6 +3476,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // can do about it. As far as they are concerned, `?` is compiler magic. return; } + if tcx.is_diagnostic_item(sym::PinDerefMutHelper, parent_def_id) { + let parent_predicate = + self.resolve_vars_if_possible(data.derived.parent_trait_pred); + + // Skip PinDerefMutHelper in suggestions, but still show downstream suggestions. + ensure_sufficient_stack(|| { + self.note_obligation_cause_code( + body_id, + err, + parent_predicate, + param_env, + &data.derived.parent_code, + obligated_types, + seen_requirements, + ) + }); + return; + } let self_ty_str = tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path()); let trait_name = tcx.short_string( diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 535830f2e749f..81c2dabf0d1d8 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1689,9 +1689,89 @@ impl const Deref for Pin { } } +mod helper { + /// Helper that prevents downstream crates from implementing `DerefMut` for `Pin`. + /// + /// The `Pin` type implements the unsafe trait `PinCoerceUnsized`, which essentially requires + /// that the type does not have a malicious `Deref` or `DerefMut` impl. However, without this + /// helper module, downstream crates are able to write `impl DerefMut for Pin` as + /// long as it does not overlap with the impl provided by stdlib. This is because `Pin` is + /// `#[fundamental]`, so stdlib promises to never implement traits for `Pin` that it does not + /// implement today. + /// + /// However, this is problematic. Downstream crates could implement `DerefMut` for + /// `Pin<&LocalType>`, and they could do so maliciously. To prevent this, the implementation for + /// `Pin` delegates to this helper module. Since `helper::Pin` is not `#[fundamental]`, the + /// orphan rules assume that stdlib might implement `helper::DerefMut` for `helper::Pin<&_>` in + /// the future. Because of this, downstream crates can no longer provide an implementation of + /// `DerefMut` for `Pin<&_>`, as it might overlap with a trait impl that, according to the + /// orphan rules, the stdlib could introduce without a breaking change in a future release. + /// + /// See for the issue this fixes. + #[repr(transparent)] + #[unstable(feature = "pin_derefmut_internals", issue = "none")] + #[allow(missing_debug_implementations)] + pub struct PinHelper { + pointer: Ptr, + } + + #[unstable(feature = "pin_derefmut_internals", issue = "none")] + #[rustc_const_unstable(feature = "const_convert", issue = "143773")] + #[rustc_diagnostic_item = "PinDerefMutHelper"] + pub const trait PinDerefMutHelper { + type Target: ?Sized; + fn deref_mut(&mut self) -> &mut Self::Target; + } + + #[unstable(feature = "pin_derefmut_internals", issue = "none")] + #[rustc_const_unstable(feature = "const_convert", issue = "143773")] + impl const PinDerefMutHelper for PinHelper + where + Ptr::Target: crate::marker::Unpin, + { + type Target = Ptr::Target; + + #[inline(always)] + fn deref_mut(&mut self) -> &mut Ptr::Target { + &mut self.pointer + } + } +} + #[stable(feature = "pin", since = "1.33.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl> const DerefMut for Pin { +#[cfg(not(doc))] +impl const DerefMut for Pin +where + Ptr: [const] Deref, + helper::PinHelper: [const] helper::PinDerefMutHelper, +{ + #[inline] + fn deref_mut(&mut self) -> &mut Ptr::Target { + // SAFETY: Pin and PinHelper have the same layout, so this is equivalent to + // `&mut self.pointer` which is safe because `Target: Unpin`. + helper::PinDerefMutHelper::deref_mut(unsafe { + &mut *(self as *mut Pin as *mut helper::PinHelper) + }) + } +} + +/// The `Target` type is restricted to `Unpin` types as it's not safe to obtain a mutable reference +/// to a pinned value. +/// +/// For soundness reasons, implementations of `DerefMut` for `Pin` are rejected even when `T` is +/// a local type not covered by this impl block. (Since `Pin` is [fundamental], such implementations +/// would normally be possible.) +/// +/// [fundamental]: ../../reference/items/implementations.html#r-items.impl.trait.fundamental +#[stable(feature = "pin", since = "1.33.0")] +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +#[cfg(doc)] +impl const DerefMut for Pin +where + Ptr: [const] DerefMut, + ::Target: Unpin, +{ fn deref_mut(&mut self) -> &mut Ptr::Target { Pin::get_mut(Pin::as_mut(self)) } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 888914a2f772e..779b07ce240a6 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -85,6 +85,11 @@ wasip2 = { version = '0.14.4', features = [ 'rustc-dep-of-std', ], default-features = false, package = 'wasi' } +[target.'cfg(all(target_os = "wasi", target_env = "p3"))'.dependencies] +wasip2 = { version = '0.14.4', features = [ + 'rustc-dep-of-std', +], default-features = false, package = 'wasi' } + [target.'cfg(target_os = "uefi")'.dependencies] r-efi = { version = "5.2.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "2.0.0", features = ['rustc-dep-of-std'] } diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 96d9bfae8ca32..fd7a11433af1b 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -103,7 +103,7 @@ pub mod linux; all(target_vendor = "fortanix", target_env = "sgx") ) )))] -#[cfg(any(target_os = "wasi", doc))] +#[cfg(any(target_os = "wasi", any(target_env = "p1", target_env = "p2"), doc))] pub mod wasi; #[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))] diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index e11e8e5430f06..75c59da721e19 100644 --- a/library/std/src/sys/args/mod.rs +++ b/library/std/src/sys/args/mod.rs @@ -36,7 +36,7 @@ cfg_select! { mod wasip1; pub use wasip1::*; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use wasip2::*; } diff --git a/library/std/src/sys/net/connection/mod.rs b/library/std/src/sys/net/connection/mod.rs index 7f9636a8ccfd6..41e7159f909ae 100644 --- a/library/std/src/sys/net/connection/mod.rs +++ b/library/std/src/sys/net/connection/mod.rs @@ -3,7 +3,7 @@ cfg_select! { all(target_family = "unix", not(target_os = "l4re")), target_os = "windows", target_os = "hermit", - all(target_os = "wasi", target_env = "p2"), + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")), target_os = "solid_asp3", ) => { mod socket; diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index d0a4a2fab497d..1d941dec1b792 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -26,7 +26,7 @@ cfg_select! { mod unix; pub use unix::*; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use wasip2::*; } diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index dd5e83ee570b6..9e964540a87c1 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -49,7 +49,7 @@ cfg_select! { mod vexos; pub use self::vexos::*; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use self::wasip2::*; } diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 3c5a4c82a9f1e..ec81d89a0f3af 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -90,7 +90,7 @@ cfg_select! { mod wasip1; pub use wasip1::fill_bytes; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use wasip2::{fill_bytes, hashmap_random_keys}; } @@ -115,7 +115,7 @@ cfg_select! { target_os = "linux", target_os = "android", all(target_family = "wasm", target_os = "unknown"), - all(target_os = "wasi", target_env = "p2"), + all(target_os = "wasi", not(target_env = "p1")), target_os = "xous", target_os = "vexos", )))] diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index 404ac87792696..660317e3ea844 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -37,7 +37,7 @@ cfg_select! { mod wasip1; pub use wasip1::*; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use wasip2::*; } diff --git a/library/std/src/sys/thread/mod.rs b/library/std/src/sys/thread/mod.rs index 3bd83dd760ac9..a20b2a3ddd8ce 100644 --- a/library/std/src/sys/thread/mod.rs +++ b/library/std/src/sys/thread/mod.rs @@ -99,7 +99,7 @@ cfg_select! { #[cfg(not(target_feature = "atomics"))] pub use unsupported::{Thread, available_parallelism}; } - all(target_os = "wasi", target_env = "p2") => { + all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { mod wasip2; pub use wasip2::{sleep, sleep_until}; #[expect(dead_code)] @@ -146,7 +146,7 @@ cfg_select! { target_os = "hurd", target_os = "fuchsia", target_os = "vxworks", - all(target_os = "wasi", target_env = "p2"), + all(target_os = "wasi", not(target_env = "p1")), )))] pub fn sleep_until(deadline: crate::time::Instant) { use crate::time::Instant; diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index d29d1041486bd..c0ddd031821a6 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -430,6 +430,16 @@ fn copy_self_contained_objects( target.triple ) }); + + // wasm32-wasip3 doesn't exist in wasi-libc yet, so instead use libs + // from the wasm32-wasip2 target. Once wasi-libc supports wasip3 this + // should be deleted and the native objects should be used. + let srcdir = if target == "wasm32-wasip3" { + assert!(!srcdir.exists(), "wasip3 support is in wasi-libc, this should be updated now"); + builder.wasi_libdir(TargetSelection::from_user("wasm32-wasip2")).unwrap() + } else { + srcdir + }; for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] { copy_and_stamp( builder, diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index a9ce738a01387..6622ef2cf82f0 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -134,6 +134,7 @@ - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) - [wasm32-wasip2](platform-support/wasm32-wasip2.md) + - [wasm32-wasip3](platform-support/wasm32-wasip3.md) - [wasm32-wali-linux-musl](platform-support/wasm32-wali-linux.md) - [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md) - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 263ea1ddb4250..7efeb216a886f 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -198,6 +198,7 @@ target | std | notes [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads [`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 +[`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | WebAssembly with WASIp3 [`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64 diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip3.md b/src/doc/rustc/src/platform-support/wasm32-wasip3.md new file mode 100644 index 0000000000000..e8063a1bdcfed --- /dev/null +++ b/src/doc/rustc/src/platform-support/wasm32-wasip3.md @@ -0,0 +1,83 @@ +# `wasm32-wasip3` + +**Tier: 3** + +The `wasm32-wasip3` target is the next stage of evolution of the +[`wasm32-wasip2`](./wasm32-wasip2.md) target. The `wasm32-wasip3` target enables +the Rust standard library to use WASIp3 APIs to implement various pieces of +functionality. WASIp3 brings native async support over WASIp2, which integrates +well with Rust's `async` ecosystem. + +> **Note**: As of 2025-10-01 WASIp3 has not yet been approved by the WASI +> subgroup of the WebAssembly Community Group. Development is expected to +> conclude in late 2025 or early 2026. Until then the Rust standard library +> won't actually use WASIp3 APIs on the `wasm32-wasip3` target as they are not +> yet stable and would reduce the stability of this target. Once WASIp3 is +> approved, however, the standard library will update to use WASIp3 natively. + +> **Note**: This target does not yet build as of 2025-10-01 due to and update +> needed in the `libc` crate. Using it will require a `[patch]` for now. + +> **Note**: Until the standard library is fully migrated to use the `wasip3` +> crate then components produced for `wasm32-wasip3` may import WASIp2 APIs. +> This is considered a transitionary phase until fully support of libstd is +> implemented. + +## Target maintainers + +[@alexcrichton](https://github.com/alexcrichton) + +## Requirements + +This target is cross-compiled. The target supports `std` fully. + +## Platform requirements + +The WebAssembly runtime should support both WASIp2 and WASIp3. Runtimes also +are required to support components since this target outputs a component as +opposed to a core wasm module. Two example runtimes for WASIp3 are [Wasmtime] +and [Jco]. + +[Wasmtime]: https://wasmtime.dev/ +[Jco]: https://github.com/bytecodealliance/jco + +## Building the target + +To build this target first acquire a copy of +[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22 +is the minimum needed. + +Next configure the `WASI_SDK_PATH` environment variable to point to where this +is installed. For example: + +```text +export WASI_SDK_PATH=/path/to/wasi-sdk-22.0 +``` + +Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld` +driver for LLD is required when linking WebAssembly code together. Rust's build +system will automatically pick up any necessary binaries and programs from +`WASI_SDK_PATH`. + +## Testing + +This target is not tested in CI at this time. Locally it can be tested with a +`wasmtime` binary in `PATH` like so: + +```text +./x.py test --target wasm32-wasip3 tests/ui +``` + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +```text +#[cfg(all(target_os = "wasi", target_env = "p3"))] +``` + +## Enabled WebAssembly features + +The default set of WebAssembly features enabled for compilation is currently the +same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the +documentation there for more information. diff --git a/src/tools/collect-license-metadata/Cargo.toml b/src/tools/collect-license-metadata/Cargo.toml index edf9e5c5393ea..f84da24428155 100644 --- a/src/tools/collect-license-metadata/Cargo.toml +++ b/src/tools/collect-license-metadata/Cargo.toml @@ -9,4 +9,5 @@ license = "MIT OR Apache-2.0" anyhow = "1.0.65" serde = { version = "1.0.147", features = ["derive"] } serde_json = "1.0.85" +similar = "2.7.0" spdx-rs = "0.5.1" diff --git a/src/tools/collect-license-metadata/src/main.rs b/src/tools/collect-license-metadata/src/main.rs index 08a30d0b8994f..4e218ea59fda6 100644 --- a/src/tools/collect-license-metadata/src/main.rs +++ b/src/tools/collect-license-metadata/src/main.rs @@ -5,9 +5,21 @@ mod reuse; use std::path::PathBuf; use anyhow::{Context, Error}; +use similar::{ChangeTag, TextDiff}; use crate::licenses::LicensesInterner; +fn diff_text(expected: &str, actual: &str) { + for change in TextDiff::from_lines(expected, actual).iter_all_changes() { + let sign = match change.tag() { + ChangeTag::Delete => "-", + ChangeTag::Insert => "+", + ChangeTag::Equal => " ", + }; + print!("{}{}", sign, change); + } +} + /// The entry point to the binary. /// /// You should probably let `bootstrap` execute this program instead of running it directly. @@ -41,6 +53,8 @@ fn main() -> Result<(), Error> { if existing_json != output { eprintln!("The existing {} file is out of date.", dest.display()); eprintln!("Run ./x run collect-license-metadata to update it."); + eprintln!("Diff:"); + diff_text(&existing, &serde_json::to_string_pretty(&output).unwrap()); anyhow::bail!("The existing {} file doesn't match what REUSE reports.", dest.display()); } println!("license information matches"); diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index dab6850e0d62a..34ecbc2d59f10 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -1,9 +1,6 @@ use std::collections::HashSet; -use std::env; -use std::fs::File; -use std::io::BufReader; -use std::io::prelude::*; use std::process::Command; +use std::{env, fs}; use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; @@ -54,18 +51,19 @@ pub struct EarlyProps { impl EarlyProps { pub fn from_file(config: &Config, testfile: &Utf8Path) -> Self { - let file = File::open(testfile.as_std_path()).expect("open test file to parse earlyprops"); - Self::from_reader(config, testfile, file) + let file_contents = + fs::read_to_string(testfile).expect("read test file to parse earlyprops"); + Self::from_file_contents(config, testfile, &file_contents) } - pub fn from_reader(config: &Config, testfile: &Utf8Path, rdr: R) -> Self { + pub fn from_file_contents(config: &Config, testfile: &Utf8Path, file_contents: &str) -> Self { let mut props = EarlyProps::default(); let mut poisoned = false; iter_directives( config.mode, &mut poisoned, testfile, - rdr, + file_contents, // (dummy comment to force args into vertical layout) &mut |ref ln: DirectiveLine<'_>| { parse_and_update_aux(config, ln, testfile, &mut props.aux); @@ -362,7 +360,7 @@ impl TestProps { fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config: &Config) { let mut has_edition = false; if !testfile.is_dir() { - let file = File::open(testfile.as_std_path()).unwrap(); + let file_contents = fs::read_to_string(testfile).unwrap(); let mut poisoned = false; @@ -370,7 +368,7 @@ impl TestProps { config.mode, &mut poisoned, testfile, - file, + &file_contents, &mut |ref ln: DirectiveLine<'_>| { if !ln.applies_to_test_revision(test_revision) { return; @@ -859,7 +857,7 @@ fn iter_directives( mode: TestMode, poisoned: &mut bool, testfile: &Utf8Path, - rdr: impl Read, + file_contents: &str, it: &mut dyn FnMut(DirectiveLine<'_>), ) { if testfile.is_dir() { @@ -886,16 +884,7 @@ fn iter_directives( } } - let mut rdr = BufReader::with_capacity(1024, rdr); - let mut ln = String::new(); - let mut line_number = 0; - - loop { - line_number += 1; - ln.clear(); - if rdr.read_line(&mut ln).unwrap() == 0 { - break; - } + for (line_number, ln) in (1..).zip(file_contents.lines()) { let ln = ln.trim(); let Some(directive_line) = line_directive(line_number, ln) else { @@ -1359,13 +1348,13 @@ where Some((min, max)) } -pub(crate) fn make_test_description( +pub(crate) fn make_test_description( config: &Config, cache: &DirectivesCache, name: String, path: &Utf8Path, filterable_path: &Utf8Path, - src: R, + file_contents: &str, test_revision: Option<&str>, poisoned: &mut bool, ) -> CollectedTestDesc { @@ -1380,7 +1369,7 @@ pub(crate) fn make_test_description( config.mode, &mut local_poisoned, path, - src, + file_contents, &mut |ref ln @ DirectiveLine { line_number, .. }| { if !ln.applies_to_test_revision(test_revision) { return; diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 95dd46532ba88..77080c7469371 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use camino::Utf8Path; use semver::Version; @@ -10,12 +8,12 @@ use crate::directives::{ }; use crate::executor::{CollectedTestDesc, ShouldPanic}; -fn make_test_description( +fn make_test_description( config: &Config, name: String, path: &Utf8Path, filterable_path: &Utf8Path, - src: R, + file_contents: &str, revision: Option<&str>, ) -> CollectedTestDesc { let cache = DirectivesCache::load(config); @@ -26,7 +24,7 @@ fn make_test_description( name, path, filterable_path, - src, + file_contents, revision, &mut poisoned, ); @@ -226,14 +224,13 @@ fn cfg() -> ConfigBuilder { } fn parse_rs(config: &Config, contents: &str) -> EarlyProps { - let bytes = contents.as_bytes(); - EarlyProps::from_reader(config, Utf8Path::new("a.rs"), bytes) + EarlyProps::from_file_contents(config, Utf8Path::new("a.rs"), contents) } fn check_ignore(config: &Config, contents: &str) -> bool { let tn = String::new(); let p = Utf8Path::new("a.rs"); - let d = make_test_description(&config, tn, p, p, std::io::Cursor::new(contents), None); + let d = make_test_description(&config, tn, p, p, contents, None); d.ignore } @@ -243,9 +240,9 @@ fn should_fail() { let tn = String::new(); let p = Utf8Path::new("a.rs"); - let d = make_test_description(&config, tn.clone(), p, p, std::io::Cursor::new(""), None); + let d = make_test_description(&config, tn.clone(), p, p, "", None); assert_eq!(d.should_panic, ShouldPanic::No); - let d = make_test_description(&config, tn, p, p, std::io::Cursor::new("//@ should-fail"), None); + let d = make_test_description(&config, tn, p, p, "//@ should-fail", None); assert_eq!(d.should_panic, ShouldPanic::Yes); } @@ -778,9 +775,8 @@ fn threads_support() { } } -fn run_path(poisoned: &mut bool, path: &Utf8Path, buf: &[u8]) { - let rdr = std::io::Cursor::new(&buf); - iter_directives(TestMode::Ui, poisoned, path, rdr, &mut |_| {}); +fn run_path(poisoned: &mut bool, path: &Utf8Path, file_contents: &str) { + iter_directives(TestMode::Ui, poisoned, path, file_contents, &mut |_| {}); } #[test] @@ -789,7 +785,7 @@ fn test_unknown_directive_check() { run_path( &mut poisoned, Utf8Path::new("a.rs"), - include_bytes!("./test-auxillary/unknown_directive.rs"), + include_str!("./test-auxillary/unknown_directive.rs"), ); assert!(poisoned); } @@ -800,7 +796,7 @@ fn test_known_directive_check_no_error() { run_path( &mut poisoned, Utf8Path::new("a.rs"), - include_bytes!("./test-auxillary/known_directive.rs"), + include_str!("./test-auxillary/known_directive.rs"), ); assert!(!poisoned); } @@ -811,7 +807,7 @@ fn test_error_annotation_no_error() { run_path( &mut poisoned, Utf8Path::new("a.rs"), - include_bytes!("./test-auxillary/error_annotation.rs"), + include_str!("./test-auxillary/error_annotation.rs"), ); assert!(!poisoned); } @@ -822,7 +818,7 @@ fn test_non_rs_unknown_directive_not_checked() { run_path( &mut poisoned, Utf8Path::new("a.Makefile"), - include_bytes!("./test-auxillary/not_rs.Makefile"), + include_str!("./test-auxillary/not_rs.Makefile"), ); assert!(!poisoned); } @@ -830,21 +826,21 @@ fn test_non_rs_unknown_directive_not_checked() { #[test] fn test_trailing_directive() { let mut poisoned = false; - run_path(&mut poisoned, Utf8Path::new("a.rs"), b"//@ only-x86 only-arm"); + run_path(&mut poisoned, Utf8Path::new("a.rs"), "//@ only-x86 only-arm"); assert!(poisoned); } #[test] fn test_trailing_directive_with_comment() { let mut poisoned = false; - run_path(&mut poisoned, Utf8Path::new("a.rs"), b"//@ only-x86 only-arm with comment"); + run_path(&mut poisoned, Utf8Path::new("a.rs"), "//@ only-x86 only-arm with comment"); assert!(poisoned); } #[test] fn test_not_trailing_directive() { let mut poisoned = false; - run_path(&mut poisoned, Utf8Path::new("a.rs"), b"//@ revisions: incremental"); + run_path(&mut poisoned, Utf8Path::new("a.rs"), "//@ revisions: incremental"); assert!(!poisoned); } diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 2d759279f34bc..ac1a8226112a9 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -892,7 +892,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // `CollectedTest` that can be handed over to the test executor. collector.tests.extend(revisions.into_iter().map(|revision| { // Create a test name and description to hand over to the executor. - let src_file = fs::File::open(&test_path).expect("open test file to parse ignores"); + let file_contents = + fs::read_to_string(&test_path).expect("read test file to parse ignores"); let (test_name, filterable_path) = make_test_name_and_filterable_path(&cx.config, testpaths, revision); // Create a description struct for the test/revision. @@ -904,7 +905,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te test_name, &test_path, &filterable_path, - src_file, + &file_contents, revision, &mut collector.poisoned, ); diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index ebea9fe40f518..e26c213837066 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -586,6 +586,9 @@ //@ revisions: wasm32_wasip2 //@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2 //@ [wasm32_wasip2] needs-llvm-components: webassembly +//@ revisions: wasm32_wasip3 +//@ [wasm32_wasip3] compile-flags: --target wasm32-wasip3 +//@ [wasm32_wasip3] needs-llvm-components: webassembly //@ revisions: wasm32_wali_linux_musl //@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl //@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly diff --git a/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs b/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs new file mode 100644 index 0000000000000..604b4c8c2f8a5 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs @@ -0,0 +1,74 @@ +//@ add-core-stubs +//@ revisions: aarch64 x86_64 +//@ [aarch64] compile-flags: --target aarch64-unknown-none +//@ [aarch64] needs-llvm-components: aarch64 +//@ [x86_64] compile-flags: --target x86_64-unknown-none +//@ [x86_64] needs-llvm-components: x86 +//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +// A `ReifyShim` should only be created when the trait is dyn-compatible. + +extern crate minicore; +use minicore::*; + +trait DynCompatible { + fn dyn_name(&self) -> &'static str; + + fn dyn_name_default(&self) -> &'static str { + let _ = self; + "dyn_default" + } +} + +// Not dyn-compatible because the `Self: Sized` bound is missing. +trait NotDynCompatible { + fn not_dyn_name() -> &'static str; + + fn not_dyn_name_default() -> &'static str { + "not_dyn_default" + } +} + +struct S; + +impl DynCompatible for S { + fn dyn_name(&self) -> &'static str { + "dyn_compatible" + } +} + +impl NotDynCompatible for S { + fn not_dyn_name() -> &'static str { + "not_dyn_compatible" + } +} + +#[no_mangle] +pub fn main() { + let s = S; + + // `DynCompatible` is indeed dyn-compatible. + let _: &dyn DynCompatible = &s; + + // CHECK: call ::dyn_name{{.*}}reify.shim.fnptr + let dyn_name = S::dyn_name as fn(&S) -> &str; + let _unused = dyn_name(&s); + + // CHECK: call fn_ptr_reify_shim::DynCompatible::dyn_name_default{{.*}}reify.shim.fnptr + let dyn_name_default = S::dyn_name_default as fn(&S) -> &str; + let _unused = dyn_name_default(&s); + + // Check using $ (end-of-line) that these calls do not contain `reify.shim.fnptr`. + + // CHECK: call ::not_dyn_name{{$}} + let not_dyn_name = S::not_dyn_name as fn() -> &'static str; + let _unused = not_dyn_name(); + + // CHECK: call fn_ptr_reify_shim::NotDynCompatible::not_dyn_name_default{{$}} + let not_dyn_name_default = S::not_dyn_name_default as fn() -> &'static str; + let _unused = not_dyn_name_default(); +} diff --git a/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs b/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs index 2c8cdc919b85d..31f59ee01decb 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs @@ -15,8 +15,9 @@ use minicore::*; struct Thing; trait MyTrait { + // NOTE: this test assumes that this trait is dyn-compatible. #[unsafe(naked)] - extern "C" fn my_naked_function() { + extern "C" fn my_naked_function(&self) { // the real function is defined // CHECK: .globl // CHECK-SAME: my_naked_function @@ -34,13 +35,13 @@ impl MyTrait for Thing {} #[unsafe(no_mangle)] pub fn main() { // Trick the compiler into generating an indirect call. - const F: extern "C" fn() = Thing::my_naked_function; + const F: extern "C" fn(&Thing) = Thing::my_naked_function; // main calls the shim function // CHECK: call void // CHECK-SAME: my_naked_function // CHECK-SAME: reify.shim.fnptr - (F)(); + (F)(&Thing); } // CHECK: declare !kcfi_type diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index 0acb33febe52b..0203ff52d63f8 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -63,27 +63,25 @@ + let mut _44: &mut std::future::Ready<()>; + let mut _45: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _46: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ let mut _46: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _47: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _48: &mut &mut std::future::Ready<()>; ++ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } -+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { -+ } -+ } -+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) { + } + } -+ scope 19 (inlined Option::<()>::take) { -+ let mut _47: std::option::Option<()>; -+ scope 20 (inlined std::mem::replace::>) { -+ scope 21 { ++ scope 17 (inlined Option::<()>::take) { ++ let mut _49: std::option::Option<()>; ++ scope 18 (inlined std::mem::replace::>) { ++ scope 19 { + } + } + } -+ scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _48: isize; -+ let mut _49: !; -+ scope 23 { ++ scope 20 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _50: isize; ++ let mut _51: !; ++ scope 21 { + } + } + } @@ -217,18 +215,23 @@ + _22 = &mut (*_23); + StorageDead(_24); + StorageLive(_44); -+ StorageLive(_49); ++ StorageLive(_46); ++ StorageLive(_51); + StorageLive(_41); + StorageLive(_42); -+ _44 = copy (_19.0: &mut std::future::Ready<()>); + StorageLive(_47); -+ _47 = Option::<()>::None; -+ _42 = copy ((*_44).0: std::option::Option<()>); -+ ((*_44).0: std::option::Option<()>) = copy _47; ++ _47 = &raw mut _19; ++ _46 = copy _47 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); + StorageDead(_47); -+ StorageLive(_48); -+ _48 = discriminant(_42); -+ switchInt(move _48) -> [0: bb11, 1: bb12, otherwise: bb5]; ++ _44 = copy ((*_46).0: &mut std::future::Ready<()>); ++ StorageLive(_49); ++ _49 = Option::<()>::None; ++ _42 = copy ((*_44).0: std::option::Option<()>); ++ ((*_44).0: std::option::Option<()>) = copy _49; ++ StorageDead(_49); ++ StorageLive(_50); ++ _50 = discriminant(_42); ++ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5]; } + + bb5: { @@ -291,16 +294,17 @@ + } + + bb11: { -+ _49 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; ++ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; + } + + bb12: { + _41 = move ((_42 as Some).0: ()); -+ StorageDead(_48); ++ StorageDead(_50); + StorageDead(_42); + _18 = Poll::<()>::Ready(move _41); + StorageDead(_41); -+ StorageDead(_49); ++ StorageDead(_51); ++ StorageDead(_46); + StorageDead(_44); + StorageDead(_22); + StorageDead(_19); diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 98ee46c29b1be..6c8cad3e992e7 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -65,27 +65,25 @@ + let mut _46: &mut std::future::Ready<()>; + let mut _47: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _48: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ let mut _48: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _49: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _50: &mut &mut std::future::Ready<()>; ++ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } -+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { -+ } -+ } -+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) { + } + } -+ scope 19 (inlined Option::<()>::take) { -+ let mut _49: std::option::Option<()>; -+ scope 20 (inlined std::mem::replace::>) { -+ scope 21 { ++ scope 17 (inlined Option::<()>::take) { ++ let mut _51: std::option::Option<()>; ++ scope 18 (inlined std::mem::replace::>) { ++ scope 19 { + } + } + } -+ scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _50: isize; -+ let mut _51: !; -+ scope 23 { ++ scope 20 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _52: isize; ++ let mut _53: !; ++ scope 21 { + } + } + } @@ -234,18 +232,23 @@ + _22 = &mut (*_23); + StorageDead(_24); + StorageLive(_46); -+ StorageLive(_51); ++ StorageLive(_48); ++ StorageLive(_53); + StorageLive(_43); + StorageLive(_44); -+ _46 = copy (_19.0: &mut std::future::Ready<()>); + StorageLive(_49); -+ _49 = Option::<()>::None; -+ _44 = copy ((*_46).0: std::option::Option<()>); -+ ((*_46).0: std::option::Option<()>) = copy _49; ++ _49 = &raw mut _19; ++ _48 = copy _49 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); + StorageDead(_49); -+ StorageLive(_50); -+ _50 = discriminant(_44); -+ switchInt(move _50) -> [0: bb16, 1: bb17, otherwise: bb7]; ++ _46 = copy ((*_48).0: &mut std::future::Ready<()>); ++ StorageLive(_51); ++ _51 = Option::<()>::None; ++ _44 = copy ((*_46).0: std::option::Option<()>); ++ ((*_46).0: std::option::Option<()>) = copy _51; ++ StorageDead(_51); ++ StorageLive(_52); ++ _52 = discriminant(_44); ++ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7]; } - bb6 (cleanup): { @@ -332,16 +335,17 @@ + } + + bb16: { -+ _51 = option::expect_failed(const "`Ready` polled after completion") -> bb11; ++ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11; + } + + bb17: { + _43 = move ((_44 as Some).0: ()); -+ StorageDead(_50); ++ StorageDead(_52); + StorageDead(_44); + _18 = Poll::<()>::Ready(move _43); + StorageDead(_43); -+ StorageDead(_51); ++ StorageDead(_53); ++ StorageDead(_48); + StorageDead(_46); + StorageDead(_22); + StorageDead(_19); diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs index a53b6d5e58981..6bb384cc87e8d 100644 --- a/tests/ui/autodiff/autodiff_illegal.rs +++ b/tests/ui/autodiff/autodiff_illegal.rs @@ -110,15 +110,6 @@ fn f14(x: f32) -> Foo { type MyFloat = f32; -// We would like to support type alias to f32/f64 in argument type in the future, -// but that requires us to implement our checks at a later stage -// like THIR which has type information available. -#[autodiff_reverse(df15, Active, Active)] -fn f15(x: MyFloat) -> f32 { - //~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] - unimplemented!() -} - // We would like to support type alias to f32/f64 in return type in the future #[autodiff_reverse(df16, Active, Active)] fn f16(x: f32) -> MyFloat { @@ -136,13 +127,6 @@ fn f17(x: f64) -> F64Trans { unimplemented!() } -// We would like to support `#[repr(transparent)]` f32/f64 wrapper in argument type in the future -#[autodiff_reverse(df18, Active, Active)] -fn f18(x: F64Trans) -> f64 { - //~^^ ERROR failed to resolve: use of undeclared type `F64Trans` [E0433] - unimplemented!() -} - // Invalid return activity #[autodiff_forward(df19, Dual, Active)] fn f19(x: f32) -> f32 { @@ -163,11 +147,4 @@ fn f21(x: f32) -> f32 { unimplemented!() } -struct DoesNotImplDefault; -#[autodiff_forward(df22, Dual)] -pub fn f22() -> DoesNotImplDefault { - //~^^ ERROR the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied - unimplemented!() -} - fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr index ad6f10af46780..848ae1155e9c4 100644 --- a/tests/ui/autodiff/autodiff_illegal.stderr +++ b/tests/ui/autodiff/autodiff_illegal.stderr @@ -107,53 +107,24 @@ LL | #[autodiff_reverse(df13, Reverse)] | ^^^^^^^ error: invalid return activity Active in Forward Mode - --> $DIR/autodiff_illegal.rs:147:1 + --> $DIR/autodiff_illegal.rs:131:1 | LL | #[autodiff_forward(df19, Dual, Active)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid return activity Dual in Reverse Mode - --> $DIR/autodiff_illegal.rs:153:1 + --> $DIR/autodiff_illegal.rs:137:1 | LL | #[autodiff_reverse(df20, Active, Dual)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid return activity Duplicated in Reverse Mode - --> $DIR/autodiff_illegal.rs:160:1 + --> $DIR/autodiff_illegal.rs:144:1 | LL | #[autodiff_reverse(df21, Active, Duplicated)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0433]: failed to resolve: use of undeclared type `MyFloat` - --> $DIR/autodiff_illegal.rs:116:1 - | -LL | #[autodiff_reverse(df15, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat` - -error[E0433]: failed to resolve: use of undeclared type `F64Trans` - --> $DIR/autodiff_illegal.rs:140:1 - | -LL | #[autodiff_reverse(df18, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans` - -error[E0599]: the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied - --> $DIR/autodiff_illegal.rs:167:1 - | -LL | struct DoesNotImplDefault; - | ------------------------- doesn't satisfy `DoesNotImplDefault: Default` -LL | #[autodiff_forward(df22, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called on `(DoesNotImplDefault, DoesNotImplDefault)` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `DoesNotImplDefault: Default` - which is required by `(DoesNotImplDefault, DoesNotImplDefault): Default` -help: consider annotating `DoesNotImplDefault` with `#[derive(Default)]` - | -LL + #[derive(Default)] -LL | struct DoesNotImplDefault; - | - -error: aborting due to 21 previous errors +error: aborting due to 18 previous errors -Some errors have detailed explanations: E0428, E0433, E0599, E0658. +Some errors have detailed explanations: E0428, E0658. For more information about an error, try `rustc --explain E0428`. diff --git a/tests/ui/autodiff/incremental.rs b/tests/ui/autodiff/incremental.rs new file mode 100644 index 0000000000000..a79059deaa778 --- /dev/null +++ b/tests/ui/autodiff/incremental.rs @@ -0,0 +1,41 @@ +//@ revisions: DEBUG RELEASE +//@[RELEASE] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat +//@[DEBUG] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=0 -Clto=fat -C debuginfo=2 +//@ needs-enzyme +//@ incremental +//@ no-prefer-dynamic +//@ build-pass +#![crate_type = "bin"] +#![feature(autodiff)] + +// We used to use llvm's metadata to instruct enzyme how to differentiate a function. +// In debug mode we would use incremental compilation which caused the metadata to be +// dropped. We now use globals instead and add this test to verify that incremental +// keeps working. Also testing debug mode while at it. + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(bar, Duplicated, Duplicated)] +pub fn foo(r: &[f64; 10], res: &mut f64) { + let mut output = [0.0; 10]; + output[0] = r[0]; + output[1] = r[1] * r[2]; + output[2] = r[4] * r[5]; + output[3] = r[2] * r[6]; + output[4] = r[1] * r[7]; + output[5] = r[2] * r[8]; + output[6] = r[1] * r[9]; + output[7] = r[5] * r[6]; + output[8] = r[5] * r[7]; + output[9] = r[4] * r[8]; + *res = output.iter().sum(); +} +fn main() { + let inputs = Box::new([3.1; 10]); + let mut d_inputs = Box::new([0.0; 10]); + let mut res = Box::new(0.0); + let mut d_res = Box::new(1.0); + + bar(&inputs, &mut d_inputs, &mut res, &mut d_res); + dbg!(&d_inputs); +} diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr index 19c3c64181985..bad799b2550b9 100644 --- a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr +++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr @@ -5,7 +5,7 @@ LL | let var_fn = Value::wrap(); | ^^^^^^ ... LL | let _ = var_fn.clone(); - | ----- type must be known at this point + | ------ type must be known at this point | help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified | diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index e62f741b3020c..3f14c7b08eac6 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` + = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `p3`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr index 4bb9047b3035d..3d667f12371ab 100644 --- a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr +++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr @@ -5,7 +5,7 @@ LL | needs_foo(|x| { | ^ ... LL | x.to_string(); - | --------- type must be known at this point + | - type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/deref/pin-impl-deref.rs b/tests/ui/deref/pin-impl-deref.rs index b1dc8dea3f248..ccd8d0dfc72ae 100644 --- a/tests/ui/deref/pin-impl-deref.rs +++ b/tests/ui/deref/pin-impl-deref.rs @@ -22,7 +22,7 @@ impl MyPinType { fn impl_deref_mut(_: impl DerefMut) {} fn unpin_impl_ref(r_unpin: Pin<&MyUnpinType>) { impl_deref_mut(r_unpin) - //~^ ERROR: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied + //~^ ERROR: the trait bound `&MyUnpinType: DerefMut` is not satisfied } fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) { impl_deref_mut(r_unpin) @@ -30,7 +30,7 @@ fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) { fn pin_impl_ref(r_pin: Pin<&MyPinType>) { impl_deref_mut(r_pin) //~^ ERROR: `PhantomPinned` cannot be unpinned - //~| ERROR: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied + //~| ERROR: the trait bound `&MyPinType: DerefMut` is not satisfied } fn pin_impl_mut(r_pin: Pin<&mut MyPinType>) { impl_deref_mut(r_pin) diff --git a/tests/ui/deref/pin-impl-deref.stderr b/tests/ui/deref/pin-impl-deref.stderr index 106654641a117..4143d66f42723 100644 --- a/tests/ui/deref/pin-impl-deref.stderr +++ b/tests/ui/deref/pin-impl-deref.stderr @@ -1,40 +1,34 @@ -error[E0277]: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied +error[E0277]: the trait bound `&MyUnpinType: DerefMut` is not satisfied --> $DIR/pin-impl-deref.rs:24:20 | LL | impl_deref_mut(r_unpin) - | -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyUnpinType>` + | -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `&MyUnpinType` | | | required by a bound introduced by this call | + = note: `DerefMut` is implemented for `&mut MyUnpinType`, but not for `&MyUnpinType` = note: required for `Pin<&MyUnpinType>` to implement `DerefMut` note: required by a bound in `impl_deref_mut` --> $DIR/pin-impl-deref.rs:22:27 | LL | fn impl_deref_mut(_: impl DerefMut) {} | ^^^^^^^^ required by this bound in `impl_deref_mut` -help: consider mutably borrowing here - | -LL | impl_deref_mut(&mut r_unpin) - | ++++ -error[E0277]: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied +error[E0277]: the trait bound `&MyPinType: DerefMut` is not satisfied --> $DIR/pin-impl-deref.rs:31:20 | LL | impl_deref_mut(r_pin) - | -------------- ^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyPinType>` + | -------------- ^^^^^ the trait `DerefMut` is not implemented for `&MyPinType` | | | required by a bound introduced by this call | + = note: `DerefMut` is implemented for `&mut MyPinType`, but not for `&MyPinType` = note: required for `Pin<&MyPinType>` to implement `DerefMut` note: required by a bound in `impl_deref_mut` --> $DIR/pin-impl-deref.rs:22:27 | LL | fn impl_deref_mut(_: impl DerefMut) {} | ^^^^^^^^ required by this bound in `impl_deref_mut` -help: consider mutably borrowing here - | -LL | impl_deref_mut(&mut r_pin) - | ++++ error[E0277]: `PhantomPinned` cannot be unpinned --> $DIR/pin-impl-deref.rs:31:20 diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr index cb383b2db3893..dca0a7b0a1a9f 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr @@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| { | ^^^^^^^^ LL | LL | cont.reify_as(); - | -------- type must be known at this point + | ---- type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| { | ^^^^^^^^ LL | LL | cont.reify_as(); - | -------- type must be known at this point + | ---- type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr index cb383b2db3893..dca0a7b0a1a9f 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr @@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| { | ^^^^^^^^ LL | LL | cont.reify_as(); - | -------- type must be known at this point + | ---- type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| { | ^^^^^^^^ LL | LL | cont.reify_as(); - | -------- type must be known at this point + | ---- type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr index ba1c81c4518a7..10056bdf3d4f4 100644 --- a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/incompat-call-after-qualified-path-0.rs:21:6 | LL | f(|a, b| a.cmp(b)); - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr index 93bba3625b540..632a9b99f84ef 100644 --- a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/incompat-call-after-qualified-path-1.rs:25:6 | LL | f(|a, b| a.cmp(b)); - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/issues/issue-20261.stderr b/tests/ui/issues/issue-20261.stderr index 6738708ca225d..c5348abb3c501 100644 --- a/tests/ui/issues/issue-20261.stderr +++ b/tests/ui/issues/issue-20261.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/issue-20261.rs:4:11 + --> $DIR/issue-20261.rs:4:9 | LL | i.clone(); - | ^^^^^ cannot infer type + | ^ cannot infer type error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-2151.stderr b/tests/ui/issues/issue-2151.stderr index 59fef42eb5e8b..b130f162414d0 100644 --- a/tests/ui/issues/issue-2151.stderr +++ b/tests/ui/issues/issue-2151.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let x = panic!(); | ^ LL | x.clone(); - | ----- type must be known at this point + | - type must be known at this point | help: consider giving `x` an explicit type | diff --git a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr index 539673bc343ce..117d189867bd7 100644 --- a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr +++ b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:9:10 | LL | |s| s.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -13,7 +13,7 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:18:10 | LL | |s| s.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -24,7 +24,7 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:26:10 | LL | |s| s.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -35,7 +35,7 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:33:10 | LL | |s| s.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/methods/call_method_unknown_pointee.stderr b/tests/ui/methods/call_method_unknown_pointee.stderr index 9d0f38cf6b5c1..e20c6f8e8a17c 100644 --- a/tests/ui/methods/call_method_unknown_pointee.stderr +++ b/tests/ui/methods/call_method_unknown_pointee.stderr @@ -1,11 +1,10 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:10:41 + --> $DIR/call_method_unknown_pointee.rs:10:23 | LL | let _a: i32 = (ptr as *const _).read(); - | ^^^^ - | | - | cannot infer type - | cannot call a method on a raw pointer with an unknown pointee type + | ^^^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type + | | + | cannot infer type error[E0282]: type annotations needed for `*const _` --> $DIR/call_method_unknown_pointee.rs:12:13 @@ -22,13 +21,12 @@ LL | let b: *const _ = ptr as *const _; | ++++++++++ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:21:39 + --> $DIR/call_method_unknown_pointee.rs:21:23 | LL | let _a: i32 = (ptr as *mut _).read(); - | ^^^^ - | | - | cannot infer type - | cannot call a method on a raw pointer with an unknown pointee type + | ^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type + | | + | cannot infer type error[E0282]: type annotations needed for `*mut _` --> $DIR/call_method_unknown_pointee.rs:23:13 diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr index 5d6974a00c695..35c7d9caf3efa 100644 --- a/tests/ui/methods/call_method_unknown_referent.stderr +++ b/tests/ui/methods/call_method_unknown_referent.stderr @@ -1,14 +1,14 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_referent.rs:20:31 + --> $DIR/call_method_unknown_referent.rs:20:19 | LL | let _a: i32 = (ptr as &_).read(); - | ^^^^ cannot infer type + | ^^^^^^^^^^^ cannot infer type error[E0282]: type annotations needed - --> $DIR/call_method_unknown_referent.rs:26:37 + --> $DIR/call_method_unknown_referent.rs:26:14 | LL | let _b = (rc as std::rc::Rc<_>).read(); - | ^^^^ cannot infer type + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope --> $DIR/call_method_unknown_referent.rs:46:35 diff --git a/tests/ui/proc-macro/quote/not-repeatable.stderr b/tests/ui/proc-macro/quote/not-repeatable.stderr index ff31799abb007..5943111efd585 100644 --- a/tests/ui/proc-macro/quote/not-repeatable.stderr +++ b/tests/ui/proc-macro/quote/not-repeatable.stderr @@ -21,10 +21,10 @@ note: the traits `Iterator` and `ToTokens` must be implemented --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0282]: type annotations needed - --> $DIR/not-repeatable.rs:11:13 + --> $DIR/not-repeatable.rs:11:25 | LL | let _ = quote! { $($ip)* }; - | ^^^^^^^^^^^^^^^^^^ cannot infer type + | ^^ cannot infer type error: aborting due to 2 previous errors diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr index b8a8f927542f0..c98b9bb38fdb0 100644 --- a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr @@ -5,7 +5,7 @@ LL | let x = [Foo(PhantomData); 2]; | ^ LL | LL | extract(x).max(2); - | --- type must be known at this point + | ---------- type must be known at this point | help: consider giving `x` an explicit type, where the placeholders `_` are specified | diff --git a/tests/ui/sanitizer/kcfi-c-variadic.rs b/tests/ui/sanitizer/kcfi-c-variadic.rs new file mode 100644 index 0000000000000..45d00a4524ebf --- /dev/null +++ b/tests/ui/sanitizer/kcfi-c-variadic.rs @@ -0,0 +1,20 @@ +//@ needs-sanitizer-kcfi +//@ no-prefer-dynamic +//@ compile-flags: -Zsanitizer=kcfi -Cpanic=abort -Cunsafe-allow-abi-mismatch=sanitizer +//@ ignore-backends: gcc +//@ run-pass + +#![feature(c_variadic)] + +trait Trait { + unsafe extern "C" fn foo(x: i32, y: i32, mut ap: ...) -> i32 { + x + y + ap.arg::() + ap.arg::() + } +} + +impl Trait for i32 {} + +fn main() { + let f = i32::foo as unsafe extern "C" fn(i32, i32, ...) -> i32; + assert_eq!(unsafe { f(1, 2, 3, 4) }, 1 + 2 + 3 + 4); +} diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.stderr index 71ac4f53b3f4f..10308ec07da5a 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | let x: Option<_> = None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` LL | x.unwrap().method_that_could_exist_on_some_type(); - | ------------------------------------ type must be known at this point + | ---------- type must be known at this point | help: consider specifying the generic argument | @@ -16,8 +16,6 @@ error[E0282]: type annotations needed | LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` -LL | .to_string() - | --------- type must be known at this point | error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr index 559bc57d90638..849ffd214f07d 100644 --- a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:8:10 | LL | |x| x.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | @@ -13,7 +13,7 @@ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:22:10 | LL | |x| x.len() - | ^ --- type must be known at this point + | ^ - type must be known at this point | help: consider giving this closure parameter an explicit type | diff --git a/tests/ui/type-inference/regression-issue-81317.stderr b/tests/ui/type-inference/regression-issue-81317.stderr index a070b50e31175..fcd3fca06e18b 100644 --- a/tests/ui/type-inference/regression-issue-81317.stderr +++ b/tests/ui/type-inference/regression-issue-81317.stderr @@ -5,7 +5,7 @@ LL | let iv = S ^ index.into(); | ^^ LL | LL | &iv.to_bytes_be(); - | ----------- type must be known at this point + | -- type must be known at this point | help: consider giving `iv` an explicit type | diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr index 9b8698d6ed2c0..4a39b404770d0 100644 --- a/tests/ui/typeck/issue-13853.stderr +++ b/tests/ui/typeck/issue-13853.stderr @@ -18,10 +18,10 @@ LL | for node in graph.iter() { | ^^^^ method not found in `&G` error[E0282]: type annotations needed - --> $DIR/issue-13853.rs:28:14 + --> $DIR/issue-13853.rs:28:9 | LL | node.zomg(); - | ^^^^ cannot infer type + | ^^^^ cannot infer type error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 diff --git a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs index f3ece563f5403..e8c3bbba1e458 100644 --- a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs +++ b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs @@ -1,5 +1,4 @@ -//@ check-pass -//@ known-bug: #85099 +//@ check-fail // Should fail. Can coerce `Pin` into `Pin` where // `T: Deref` and `U: Deref`, using the @@ -43,6 +42,7 @@ impl<'a, Fut: Future> SomeTrait<'a, Fut> for Fut { } impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> { +//~^ ERROR: conflicting implementations of trait `DerefMut` fn deref_mut<'c>( self: &'c mut Pin<&'b dyn SomeTrait<'a, Fut>>, ) -> &'c mut (dyn SomeTrait<'a, Fut> + 'b) { diff --git a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr new file mode 100644 index 0000000000000..2bcd92b76a09d --- /dev/null +++ b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `DerefMut` for type `Pin<&dyn SomeTrait<'_, _>>` + --> $DIR/pin-unsound-issue-85099-derefmut.rs:44:1 + | +LL | impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl DerefMut for Pin + where as pin::helper::PinDerefMutHelper>::Target == as Deref>::Target, Ptr: Deref, pin::helper::PinHelper: pin::helper::PinDerefMutHelper, pin::helper::PinHelper: ?Sized; + = note: upstream crates may add a new impl of trait `std::pin::helper::PinDerefMutHelper` for type `std::pin::helper::PinHelper<&dyn SomeTrait<'_, _>>` in future versions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`.