Auto merge of #147453 - matthiaskrgr:rollup-z3db8zi, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#146865 (kcfi: only reify trait methods when dyn-compatible)
 - rust-lang/rust#147205 (Add a new `wasm32-wasip3` target to Rust)
 - rust-lang/rust#147322 (cg_llvm: Consistently import `llvm::Type` and `llvm::Value`)
 - rust-lang/rust#147398 (Fix; correct placement of type inference error for method calls)
 - rust-lang/rust#147410 (Update `S-waiting-on-team` refs to new `S-waiting-on-{team}` labels)
 - rust-lang/rust#147422 (collect-license-metadata: Print a diff of the expected output)
 - rust-lang/rust#147431 (compiletest: Read the whole test file before parsing directives)
 - rust-lang/rust#147433 (Fix doc comment)

Failed merges:

 - rust-lang/rust#147390 (Use globals instead of metadata for std::autodiff)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-10-07 20:47:13 +00:00
67 changed files with 373 additions and 161 deletions

View File

@@ -686,6 +686,7 @@ dependencies = [
"anyhow", "anyhow",
"serde", "serde",
"serde_json", "serde_json",
"similar",
"spdx-rs", "spdx-rs",
] ]

View File

@@ -22,11 +22,9 @@ use smallvec::SmallVec;
use crate::attributes::{self, llfn_attrs_from_instance}; use crate::attributes::{self, llfn_attrs_from_instance};
use crate::builder::Builder; use crate::builder::Builder;
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::llvm::{self, Attribute, AttributePlace}; use crate::llvm::{self, Attribute, AttributePlace, Type, Value};
use crate::llvm_util; use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
trait ArgAttributesExt { trait ArgAttributesExt {
fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value); fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);

View File

@@ -13,14 +13,12 @@ use rustc_target::asm::*;
use smallvec::SmallVec; use smallvec::SmallVec;
use tracing::debug; use tracing::debug;
use crate::attributes;
use crate::builder::Builder; use crate::builder::Builder;
use crate::common::Funclet; use crate::common::Funclet;
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::llvm::ToLlvmBool; use crate::llvm::{self, ToLlvmBool, Type, Value};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{attributes, llvm};
impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn codegen_inline_asm( fn codegen_inline_asm(

View File

@@ -13,8 +13,9 @@ use smallvec::SmallVec;
use crate::context::SimpleCx; use crate::context::SimpleCx;
use crate::errors::SanitizerMemtagRequiresMte; use crate::errors::SanitizerMemtagRequiresMte;
use crate::llvm::AttributePlace::Function; use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; use crate::llvm::{
use crate::value::Value; self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects, Value,
};
use crate::{Session, attributes, llvm_util}; use crate::{Session, attributes, llvm_util};
pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {

View File

@@ -28,10 +28,10 @@ use rustc_span::Symbol;
use rustc_target::spec::SanitizerSet; use rustc_target::spec::SanitizerSet;
use super::ModuleLlvm; use super::ModuleLlvm;
use crate::attributes;
use crate::builder::Builder; use crate::builder::Builder;
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::value::Value; use crate::llvm::{self, Value};
use crate::{attributes, llvm};
pub(crate) struct ValueIter<'ll> { pub(crate) struct ValueIter<'ll> {
cur: Option<&'ll Value>, cur: Option<&'ll Value>,

View File

@@ -37,11 +37,9 @@ use crate::common::Funclet;
use crate::context::{CodegenCx, FullCx, GenericCx, SCx}; use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
use crate::llvm::{ use crate::llvm::{
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, FromGeneric, GEPNoWrapFlags, Metadata, TRUE, self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, FromGeneric, GEPNoWrapFlags, Metadata, TRUE,
ToLlvmBool, ToLlvmBool, Type, Value,
}; };
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
#[must_use] #[must_use]
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SCx<'ll>>> { pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SCx<'ll>>> {

View File

@@ -12,9 +12,7 @@ use tracing::debug;
use crate::builder::{Builder, PlaceRef, UNNAMED}; use crate::builder::{Builder, PlaceRef, UNNAMED};
use crate::context::SimpleCx; use crate::context::SimpleCx;
use crate::declare::declare_simple_fn; use crate::declare::declare_simple_fn;
use crate::llvm; use crate::llvm::{self, Metadata, TRUE, Type, Value};
use crate::llvm::{Metadata, TRUE, Type};
use crate::value::Value;
pub(crate) fn adjust_activity_to_abi<'tcx>( pub(crate) fn adjust_activity_to_abi<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View File

@@ -10,8 +10,7 @@ use rustc_middle::ty::{self, Instance, TypeVisitableExt};
use tracing::debug; use tracing::debug;
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::llvm; use crate::llvm::{self, Value};
use crate::value::Value;
/// Codegens a reference to a fn/method item, monomorphizing and /// Codegens a reference to a fn/method item, monomorphizing and
/// inlining as it goes. /// inlining as it goes.

View File

@@ -20,9 +20,7 @@ use tracing::debug;
use crate::consts::const_alloc_to_llvm; use crate::consts::const_alloc_to_llvm;
pub(crate) use crate::context::CodegenCx; pub(crate) use crate::context::CodegenCx;
use crate::context::{GenericCx, SCx}; use crate::context::{GenericCx, SCx};
use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool}; use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value};
use crate::type_::Type;
use crate::value::Value;
/* /*
* A note on nomenclature of linking: "extern", "foreign", and "upcall". * A note on nomenclature of linking: "extern", "foreign", and "upcall".

View File

@@ -21,10 +21,9 @@ use tracing::{debug, instrument, trace};
use crate::common::CodegenCx; use crate::common::CodegenCx;
use crate::errors::SymbolAlreadyDefined; use crate::errors::SymbolAlreadyDefined;
use crate::type_::Type; use crate::llvm::{self, Type, Value};
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value; use crate::{base, debuginfo};
use crate::{base, debuginfo, llvm};
pub(crate) fn const_alloc_to_llvm<'ll>( pub(crate) fn const_alloc_to_llvm<'ll>(
cx: &CodegenCx<'ll, '_>, cx: &CodegenCx<'ll, '_>,

View File

@@ -35,10 +35,8 @@ use crate::abi::to_llvm_calling_convention;
use crate::back::write::to_llvm_code_model; use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn; use crate::callee::get_fn;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
use crate::llvm::{Metadata, MetadataKindId, Module}; use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value};
use crate::type_::Type; use crate::{attributes, common, coverageinfo, debuginfo, llvm_util};
use crate::value::Value;
use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
/// `TyCtxt` (and related cache datastructures) can't be move between threads. /// `TyCtxt` (and related cache datastructures) can't be move between threads.
/// However, there are various cx related functions which we want to be available to the builder and /// However, there are various cx related functions which we want to be available to the builder and

View File

@@ -9,8 +9,7 @@ use rustc_session::config::{CrateType, DebugInfo};
use crate::builder::Builder; use crate::builder::Builder;
use crate::common::CodegenCx; use crate::common::CodegenCx;
use crate::llvm; use crate::llvm::{self, Value};
use crate::value::Value;
/// Inserts a side-effect free instruction sequence that makes sure that the /// Inserts a side-effect free instruction sequence that makes sure that the
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.

View File

@@ -41,8 +41,7 @@ use crate::llvm::debuginfo::{
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
DIScope, DIType, DebugEmissionKind, DebugNameTableKind, DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
}; };
use crate::llvm::{self, FromGeneric}; use crate::llvm::{self, FromGeneric, Value};
use crate::value::Value;
impl PartialEq for llvm::Metadata { impl PartialEq for llvm::Metadata {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {

View File

@@ -35,12 +35,11 @@ use self::namespace::mangled_name_of_instance;
use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use self::utils::{DIB, create_DIArray, is_node_local_to_unit};
use crate::builder::Builder; use crate::builder::Builder;
use crate::common::{AsCCharPtr, CodegenCx}; use crate::common::{AsCCharPtr, CodegenCx};
use crate::llvm;
use crate::llvm::debuginfo::{ use crate::llvm::debuginfo::{
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope,
DITemplateTypeParameter, DIType, DIVariable, DITemplateTypeParameter, DIType, DIVariable,
}; };
use crate::value::Value; use crate::llvm::{self, Value};
mod create_scope_map; mod create_scope_map;
mod dwarf_const; mod dwarf_const;

View File

@@ -23,13 +23,11 @@ use smallvec::SmallVec;
use tracing::debug; use tracing::debug;
use crate::abi::FnAbiLlvmExt; use crate::abi::FnAbiLlvmExt;
use crate::attributes;
use crate::common::AsCCharPtr; use crate::common::AsCCharPtr;
use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx}; use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx};
use crate::llvm::AttributePlace::Function; use crate::llvm::AttributePlace::Function;
use crate::llvm::{FromGeneric, Visibility}; use crate::llvm::{self, FromGeneric, Type, Value, Visibility};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, llvm};
/// Declare a function with a SimpleCx. /// Declare a function with a SimpleCx.
/// ///

View File

@@ -25,11 +25,9 @@ use crate::builder::Builder;
use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call};
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::errors::AutoDiffWithoutEnable; use crate::errors::AutoDiffWithoutEnable;
use crate::llvm::{self, Metadata}; use crate::llvm::{self, Metadata, Type, Value};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg; use crate::va_arg::emit_va_arg;
use crate::value::Value;
fn call_simple_intrinsic<'ll, 'tcx>( fn call_simple_intrinsic<'ll, 'tcx>(
bx: &mut Builder<'_, 'll, 'tcx>, bx: &mut Builder<'_, 'll, 'tcx>,

View File

@@ -6,7 +6,7 @@ use rustc_span::InnerSpan;
pub(crate) use self::Diagnostic::*; pub(crate) use self::Diagnostic::*;
use self::OptimizationDiagnosticKind::*; use self::OptimizationDiagnosticKind::*;
use super::{DiagnosticInfo, SMDiagnostic}; use super::{DiagnosticInfo, SMDiagnostic};
use crate::value::Value; use crate::llvm::Value;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub(crate) enum OptimizationDiagnosticKind { pub(crate) enum OptimizationDiagnosticKind {

View File

@@ -13,12 +13,10 @@ use rustc_middle::ty::{self, Ty};
use rustc_target::callconv::{CastTarget, FnAbi}; use rustc_target::callconv::{CastTarget, FnAbi};
use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::abi::{FnAbiLlvmExt, LlvmType};
use crate::common;
use crate::context::{CodegenCx, GenericCx, SCx}; use crate::context::{CodegenCx, GenericCx, SCx};
pub(crate) use crate::llvm::Type; use crate::llvm::{self, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value};
use crate::llvm::{FALSE, Metadata, TRUE, ToLlvmBool};
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{common, llvm};
impl PartialEq for Type { impl PartialEq for Type {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {

View File

@@ -11,7 +11,7 @@ use rustc_span::{DUMMY_SP, Span};
use tracing::debug; use tracing::debug;
use crate::common::*; use crate::common::*;
use crate::type_::Type; use crate::llvm::Type;
fn uncached_llvm_type<'a, 'tcx>( fn uncached_llvm_type<'a, 'tcx>(
cx: &CodegenCx<'a, 'tcx>, cx: &CodegenCx<'a, 'tcx>,

View File

@@ -9,9 +9,8 @@ use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use crate::builder::Builder; use crate::builder::Builder;
use crate::type_::Type; use crate::llvm::{Type, Value};
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
fn round_up_to_alignment<'ll>( fn round_up_to_alignment<'ll>(
bx: &mut Builder<'_, 'll, '_>, bx: &mut Builder<'_, 'll, '_>,

View File

@@ -1,8 +1,7 @@
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::{fmt, ptr}; use std::{fmt, ptr};
use crate::llvm; use crate::llvm::{self, Value};
pub(crate) use crate::llvm::Value;
impl PartialEq for Value { impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {

View File

@@ -7,9 +7,8 @@ use rustc_attr_parsing::is_doc_alias_attrs_contain_symbol;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::sso::SsoHashSet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::{self as hir, ExprKind, HirId, Node};
use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_hir_analysis::autoderef::{self, Autoderef};
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt}; 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 ty = self.resolve_vars_if_possible(ty.value);
let guar = match *ty.kind() { let guar = match *ty.kind() {
ty::Infer(ty::TyVar(_)) => { 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 let raw_ptr_call = bad_ty.reached_raw_pointer
&& !self.tcx.features().arbitrary_self_types(); && !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( let mut err = self.err_ctxt().emit_inference_failure_err(
self.body_id, self.body_id,
span, err_span,
ty.into(), ty.into(),
TypeAnnotationNeeded::E0282, TypeAnnotationNeeded::E0282,
!raw_ptr_call, !raw_ptr_call,

View File

@@ -839,7 +839,7 @@ pub enum PatKind<'tcx> {
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
/// much simpler. /// much simpler.
/// * raw pointers derived from integers, other raw pointers will have already resulted in an /// * raw pointers derived from integers, other raw pointers will have already resulted in an
// error. /// error.
/// * `String`, if `string_deref_patterns` is enabled. /// * `String`, if `string_deref_patterns` is enabled.
Constant { Constant {
value: ty::Value<'tcx>, value: ty::Value<'tcx>,

View File

@@ -618,11 +618,11 @@ impl<'tcx> Instance<'tcx> {
// be directly reified because it's closure-like. The reify can handle the // be directly reified because it's closure-like. The reify can handle the
// unresolved instance. // unresolved instance.
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
// Reify `Trait::method` implementations // Reify `Trait::method` implementations if the trait is dyn-compatible.
// FIXME(maurer) only reify it if it is a vtable-safe function
} else if let Some(assoc) = tcx.opt_associated_item(def_id) } else if let Some(assoc) = tcx.opt_associated_item(def_id)
&& let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
assoc.container 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 // 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. // KCFI because it can only attach one type per function.

View File

@@ -1624,6 +1624,7 @@ supported_targets! {
("wasm32v1-none", wasm32v1_none), ("wasm32v1-none", wasm32v1_none),
("wasm32-wasip1", wasm32_wasip1), ("wasm32-wasip1", wasm32_wasip1),
("wasm32-wasip2", wasm32_wasip2), ("wasm32-wasip2", wasm32_wasip2),
("wasm32-wasip3", wasm32_wasip3),
("wasm32-wasip1-threads", wasm32_wasip1_threads), ("wasm32-wasip1-threads", wasm32_wasip1_threads),
("wasm32-wali-linux-musl", wasm32_wali_linux_musl), ("wasm32-wali-linux-musl", wasm32_wali_linux_musl),
("wasm64-unknown-unknown", wasm64_unknown_unknown), ("wasm64-unknown-unknown", wasm64_unknown_unknown),

View File

@@ -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
}

View File

@@ -85,6 +85,11 @@ wasip2 = { version = '0.14.4', features = [
'rustc-dep-of-std', 'rustc-dep-of-std',
], default-features = false, package = 'wasi' } ], 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] [target.'cfg(target_os = "uefi")'.dependencies]
r-efi = { version = "5.2.0", features = ['rustc-dep-of-std'] } r-efi = { version = "5.2.0", features = ['rustc-dep-of-std'] }
r-efi-alloc = { version = "2.0.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "2.0.0", features = ['rustc-dep-of-std'] }

View File

@@ -103,7 +103,7 @@ pub mod linux;
all(target_vendor = "fortanix", target_env = "sgx") 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; pub mod wasi;
#[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))] #[cfg(any(all(target_os = "wasi", target_env = "p2"), doc))]

View File

@@ -36,7 +36,7 @@ cfg_select! {
mod wasip1; mod wasip1;
pub use wasip1::*; pub use wasip1::*;
} }
all(target_os = "wasi", target_env = "p2") => { all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => {
mod wasip2; mod wasip2;
pub use wasip2::*; pub use wasip2::*;
} }

View File

@@ -3,7 +3,7 @@ cfg_select! {
all(target_family = "unix", not(target_os = "l4re")), all(target_family = "unix", not(target_os = "l4re")),
target_os = "windows", target_os = "windows",
target_os = "hermit", 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", target_os = "solid_asp3",
) => { ) => {
mod socket; mod socket;

View File

@@ -26,7 +26,7 @@ cfg_select! {
mod unix; mod unix;
pub use unix::*; pub use unix::*;
} }
all(target_os = "wasi", target_env = "p2") => { all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => {
mod wasip2; mod wasip2;
pub use wasip2::*; pub use wasip2::*;
} }

View File

@@ -49,7 +49,7 @@ cfg_select! {
mod vexos; mod vexos;
pub use self::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; mod wasip2;
pub use self::wasip2::*; pub use self::wasip2::*;
} }

View File

@@ -90,7 +90,7 @@ cfg_select! {
mod wasip1; mod wasip1;
pub use wasip1::fill_bytes; 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; mod wasip2;
pub use wasip2::{fill_bytes, hashmap_random_keys}; pub use wasip2::{fill_bytes, hashmap_random_keys};
} }
@@ -115,7 +115,7 @@ cfg_select! {
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
all(target_family = "wasm", target_os = "unknown"), 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 = "xous",
target_os = "vexos", target_os = "vexos",
)))] )))]

View File

@@ -37,7 +37,7 @@ cfg_select! {
mod wasip1; mod wasip1;
pub use wasip1::*; pub use wasip1::*;
} }
all(target_os = "wasi", target_env = "p2") => { all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => {
mod wasip2; mod wasip2;
pub use wasip2::*; pub use wasip2::*;
} }

View File

@@ -99,7 +99,7 @@ cfg_select! {
#[cfg(not(target_feature = "atomics"))] #[cfg(not(target_feature = "atomics"))]
pub use unsupported::{Thread, available_parallelism}; 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; mod wasip2;
pub use wasip2::{sleep, sleep_until}; pub use wasip2::{sleep, sleep_until};
#[expect(dead_code)] #[expect(dead_code)]
@@ -146,7 +146,7 @@ cfg_select! {
target_os = "hurd", target_os = "hurd",
target_os = "fuchsia", target_os = "fuchsia",
target_os = "vxworks", 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) { pub fn sleep_until(deadline: crate::time::Instant) {
use crate::time::Instant; use crate::time::Instant;

View File

@@ -15,5 +15,13 @@ labels_blocking_approval = [
"S-waiting-on-crater", "S-waiting-on-crater",
"S-waiting-on-fcp", "S-waiting-on-fcp",
"S-waiting-on-MCP", "S-waiting-on-MCP",
"S-waiting-on-team" "S-waiting-on-t-lang",
"S-waiting-on-t-compiler",
"S-waiting-on-t-libs-api",
"S-waiting-on-t-libs",
"S-waiting-on-t-types",
"S-waiting-on-t-opsem",
"S-waiting-on-t-rustdoc",
"S-waiting-on-t-rustdoc-frontend",
"S-waiting-on-t-clippy"
] ]

View File

@@ -430,6 +430,16 @@ fn copy_self_contained_objects(
target.triple 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"] { for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
copy_and_stamp( copy_and_stamp(
builder, builder,

View File

@@ -134,6 +134,7 @@
- [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1](platform-support/wasm32-wasip1.md)
- [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md)
- [wasm32-wasip2](platform-support/wasm32-wasip2.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-wali-linux-musl](platform-support/wasm32-wali-linux.md)
- [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md) - [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md)
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md) - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)

View File

@@ -198,6 +198,7 @@ target | std | notes
[`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 [`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-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-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 [`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`](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 [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64

View File

@@ -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.

View File

@@ -9,4 +9,5 @@ license = "MIT OR Apache-2.0"
anyhow = "1.0.65" anyhow = "1.0.65"
serde = { version = "1.0.147", features = ["derive"] } serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.85" serde_json = "1.0.85"
similar = "2.7.0"
spdx-rs = "0.5.1" spdx-rs = "0.5.1"

View File

@@ -5,9 +5,21 @@ mod reuse;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use similar::{ChangeTag, TextDiff};
use crate::licenses::LicensesInterner; 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. /// The entry point to the binary.
/// ///
/// You should probably let `bootstrap` execute this program instead of running it directly. /// 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 { if existing_json != output {
eprintln!("The existing {} file is out of date.", dest.display()); eprintln!("The existing {} file is out of date.", dest.display());
eprintln!("Run ./x run collect-license-metadata to update it."); 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()); anyhow::bail!("The existing {} file doesn't match what REUSE reports.", dest.display());
} }
println!("license information matches"); println!("license information matches");

View File

@@ -1,9 +1,6 @@
use std::collections::HashSet; 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::process::Command;
use std::{env, fs};
use camino::{Utf8Path, Utf8PathBuf}; use camino::{Utf8Path, Utf8PathBuf};
use semver::Version; use semver::Version;
@@ -54,18 +51,19 @@ pub struct EarlyProps {
impl EarlyProps { impl EarlyProps {
pub fn from_file(config: &Config, testfile: &Utf8Path) -> Self { pub fn from_file(config: &Config, testfile: &Utf8Path) -> Self {
let file = File::open(testfile.as_std_path()).expect("open test file to parse earlyprops"); let file_contents =
Self::from_reader(config, testfile, file) fs::read_to_string(testfile).expect("read test file to parse earlyprops");
Self::from_file_contents(config, testfile, &file_contents)
} }
pub fn from_reader<R: Read>(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 props = EarlyProps::default();
let mut poisoned = false; let mut poisoned = false;
iter_directives( iter_directives(
config.mode, config.mode,
&mut poisoned, &mut poisoned,
testfile, testfile,
rdr, file_contents,
// (dummy comment to force args into vertical layout) // (dummy comment to force args into vertical layout)
&mut |ref ln: DirectiveLine<'_>| { &mut |ref ln: DirectiveLine<'_>| {
parse_and_update_aux(config, ln, testfile, &mut props.aux); 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) { fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config: &Config) {
let mut has_edition = false; let mut has_edition = false;
if !testfile.is_dir() { 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; let mut poisoned = false;
@@ -370,7 +368,7 @@ impl TestProps {
config.mode, config.mode,
&mut poisoned, &mut poisoned,
testfile, testfile,
file, &file_contents,
&mut |ref ln: DirectiveLine<'_>| { &mut |ref ln: DirectiveLine<'_>| {
if !ln.applies_to_test_revision(test_revision) { if !ln.applies_to_test_revision(test_revision) {
return; return;
@@ -859,7 +857,7 @@ fn iter_directives(
mode: TestMode, mode: TestMode,
poisoned: &mut bool, poisoned: &mut bool,
testfile: &Utf8Path, testfile: &Utf8Path,
rdr: impl Read, file_contents: &str,
it: &mut dyn FnMut(DirectiveLine<'_>), it: &mut dyn FnMut(DirectiveLine<'_>),
) { ) {
if testfile.is_dir() { if testfile.is_dir() {
@@ -886,16 +884,7 @@ fn iter_directives(
} }
} }
let mut rdr = BufReader::with_capacity(1024, rdr); for (line_number, ln) in (1..).zip(file_contents.lines()) {
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;
}
let ln = ln.trim(); let ln = ln.trim();
let Some(directive_line) = line_directive(line_number, ln) else { let Some(directive_line) = line_directive(line_number, ln) else {
@@ -1359,13 +1348,13 @@ where
Some((min, max)) Some((min, max))
} }
pub(crate) fn make_test_description<R: Read>( pub(crate) fn make_test_description(
config: &Config, config: &Config,
cache: &DirectivesCache, cache: &DirectivesCache,
name: String, name: String,
path: &Utf8Path, path: &Utf8Path,
filterable_path: &Utf8Path, filterable_path: &Utf8Path,
src: R, file_contents: &str,
test_revision: Option<&str>, test_revision: Option<&str>,
poisoned: &mut bool, poisoned: &mut bool,
) -> CollectedTestDesc { ) -> CollectedTestDesc {
@@ -1380,7 +1369,7 @@ pub(crate) fn make_test_description<R: Read>(
config.mode, config.mode,
&mut local_poisoned, &mut local_poisoned,
path, path,
src, file_contents,
&mut |ref ln @ DirectiveLine { line_number, .. }| { &mut |ref ln @ DirectiveLine { line_number, .. }| {
if !ln.applies_to_test_revision(test_revision) { if !ln.applies_to_test_revision(test_revision) {
return; return;

View File

@@ -1,5 +1,3 @@
use std::io::Read;
use camino::Utf8Path; use camino::Utf8Path;
use semver::Version; use semver::Version;
@@ -10,12 +8,12 @@ use crate::directives::{
}; };
use crate::executor::{CollectedTestDesc, ShouldPanic}; use crate::executor::{CollectedTestDesc, ShouldPanic};
fn make_test_description<R: Read>( fn make_test_description(
config: &Config, config: &Config,
name: String, name: String,
path: &Utf8Path, path: &Utf8Path,
filterable_path: &Utf8Path, filterable_path: &Utf8Path,
src: R, file_contents: &str,
revision: Option<&str>, revision: Option<&str>,
) -> CollectedTestDesc { ) -> CollectedTestDesc {
let cache = DirectivesCache::load(config); let cache = DirectivesCache::load(config);
@@ -26,7 +24,7 @@ fn make_test_description<R: Read>(
name, name,
path, path,
filterable_path, filterable_path,
src, file_contents,
revision, revision,
&mut poisoned, &mut poisoned,
); );
@@ -226,14 +224,13 @@ fn cfg() -> ConfigBuilder {
} }
fn parse_rs(config: &Config, contents: &str) -> EarlyProps { fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
let bytes = contents.as_bytes(); EarlyProps::from_file_contents(config, Utf8Path::new("a.rs"), contents)
EarlyProps::from_reader(config, Utf8Path::new("a.rs"), bytes)
} }
fn check_ignore(config: &Config, contents: &str) -> bool { fn check_ignore(config: &Config, contents: &str) -> bool {
let tn = String::new(); let tn = String::new();
let p = Utf8Path::new("a.rs"); 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 d.ignore
} }
@@ -243,9 +240,9 @@ fn should_fail() {
let tn = String::new(); let tn = String::new();
let p = Utf8Path::new("a.rs"); 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); 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); assert_eq!(d.should_panic, ShouldPanic::Yes);
} }
@@ -778,9 +775,8 @@ fn threads_support() {
} }
} }
fn run_path(poisoned: &mut bool, path: &Utf8Path, buf: &[u8]) { fn run_path(poisoned: &mut bool, path: &Utf8Path, file_contents: &str) {
let rdr = std::io::Cursor::new(&buf); iter_directives(TestMode::Ui, poisoned, path, file_contents, &mut |_| {});
iter_directives(TestMode::Ui, poisoned, path, rdr, &mut |_| {});
} }
#[test] #[test]
@@ -789,7 +785,7 @@ fn test_unknown_directive_check() {
run_path( run_path(
&mut poisoned, &mut poisoned,
Utf8Path::new("a.rs"), Utf8Path::new("a.rs"),
include_bytes!("./test-auxillary/unknown_directive.rs"), include_str!("./test-auxillary/unknown_directive.rs"),
); );
assert!(poisoned); assert!(poisoned);
} }
@@ -800,7 +796,7 @@ fn test_known_directive_check_no_error() {
run_path( run_path(
&mut poisoned, &mut poisoned,
Utf8Path::new("a.rs"), Utf8Path::new("a.rs"),
include_bytes!("./test-auxillary/known_directive.rs"), include_str!("./test-auxillary/known_directive.rs"),
); );
assert!(!poisoned); assert!(!poisoned);
} }
@@ -811,7 +807,7 @@ fn test_error_annotation_no_error() {
run_path( run_path(
&mut poisoned, &mut poisoned,
Utf8Path::new("a.rs"), Utf8Path::new("a.rs"),
include_bytes!("./test-auxillary/error_annotation.rs"), include_str!("./test-auxillary/error_annotation.rs"),
); );
assert!(!poisoned); assert!(!poisoned);
} }
@@ -822,7 +818,7 @@ fn test_non_rs_unknown_directive_not_checked() {
run_path( run_path(
&mut poisoned, &mut poisoned,
Utf8Path::new("a.Makefile"), Utf8Path::new("a.Makefile"),
include_bytes!("./test-auxillary/not_rs.Makefile"), include_str!("./test-auxillary/not_rs.Makefile"),
); );
assert!(!poisoned); assert!(!poisoned);
} }
@@ -830,21 +826,21 @@ fn test_non_rs_unknown_directive_not_checked() {
#[test] #[test]
fn test_trailing_directive() { fn test_trailing_directive() {
let mut poisoned = false; 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); assert!(poisoned);
} }
#[test] #[test]
fn test_trailing_directive_with_comment() { fn test_trailing_directive_with_comment() {
let mut poisoned = false; 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); assert!(poisoned);
} }
#[test] #[test]
fn test_not_trailing_directive() { fn test_not_trailing_directive() {
let mut poisoned = false; 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); assert!(!poisoned);
} }

View File

@@ -892,7 +892,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
// `CollectedTest` that can be handed over to the test executor. // `CollectedTest` that can be handed over to the test executor.
collector.tests.extend(revisions.into_iter().map(|revision| { collector.tests.extend(revisions.into_iter().map(|revision| {
// Create a test name and description to hand over to the executor. // 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) = let (test_name, filterable_path) =
make_test_name_and_filterable_path(&cx.config, testpaths, revision); make_test_name_and_filterable_path(&cx.config, testpaths, revision);
// Create a description struct for the test/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_name,
&test_path, &test_path,
&filterable_path, &filterable_path,
src_file, &file_contents,
revision, revision,
&mut collector.poisoned, &mut collector.poisoned,
); );

View File

@@ -586,6 +586,9 @@
//@ revisions: wasm32_wasip2 //@ revisions: wasm32_wasip2
//@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2 //@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2
//@ [wasm32_wasip2] needs-llvm-components: webassembly //@ [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 //@ revisions: wasm32_wali_linux_musl
//@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl //@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl
//@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly //@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly

View File

@@ -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 <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::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 <fn_ptr_reify_shim::S as fn_ptr_reify_shim::NotDynCompatible>::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();
}

View File

@@ -15,8 +15,9 @@ use minicore::*;
struct Thing; struct Thing;
trait MyTrait { trait MyTrait {
// NOTE: this test assumes that this trait is dyn-compatible.
#[unsafe(naked)] #[unsafe(naked)]
extern "C" fn my_naked_function() { extern "C" fn my_naked_function(&self) {
// the real function is defined // the real function is defined
// CHECK: .globl // CHECK: .globl
// CHECK-SAME: my_naked_function // CHECK-SAME: my_naked_function
@@ -34,13 +35,13 @@ impl MyTrait for Thing {}
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub fn main() { pub fn main() {
// Trick the compiler into generating an indirect call. // 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 // main calls the shim function
// CHECK: call void // CHECK: call void
// CHECK-SAME: my_naked_function // CHECK-SAME: my_naked_function
// CHECK-SAME: reify.shim.fnptr // CHECK-SAME: reify.shim.fnptr
(F)(); (F)(&Thing);
} }
// CHECK: declare !kcfi_type // CHECK: declare !kcfi_type

View File

@@ -5,7 +5,7 @@ LL | let var_fn = Value::wrap();
| ^^^^^^ | ^^^^^^
... ...
LL | let _ = var_fn.clone(); 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 help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified
| |

View File

@@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_env = "_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 <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`

View File

@@ -5,7 +5,7 @@ LL | needs_foo(|x| {
| ^ | ^
... ...
LL | x.to_string(); 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| {
| ^^^^^^^^ | ^^^^^^^^
LL | LL |
LL | cont.reify_as(); 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 help: consider giving this closure parameter an explicit type
| |
@@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| {
| ^^^^^^^^ | ^^^^^^^^
LL | LL |
LL | cont.reify_as(); 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| {
| ^^^^^^^^ | ^^^^^^^^
LL | LL |
LL | cont.reify_as(); 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 help: consider giving this closure parameter an explicit type
| |
@@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| {
| ^^^^^^^^ | ^^^^^^^^
LL | LL |
LL | cont.reify_as(); 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/incompat-call-after-qualified-path-0.rs:21:6 --> $DIR/incompat-call-after-qualified-path-0.rs:21:6
| |
LL | f(|a, b| a.cmp(b)); 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/incompat-call-after-qualified-path-1.rs:25:6 --> $DIR/incompat-call-after-qualified-path-1.rs:25:6
| |
LL | f(|a, b| a.cmp(b)); 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -1,8 +1,8 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/issue-20261.rs:4:11 --> $DIR/issue-20261.rs:4:9
| |
LL | i.clone(); LL | i.clone();
| ^^^^^ cannot infer type | ^ cannot infer type
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
LL | let x = panic!(); LL | let x = panic!();
| ^ | ^
LL | x.clone(); LL | x.clone();
| ----- type must be known at this point | - type must be known at this point
| |
help: consider giving `x` an explicit type help: consider giving `x` an explicit type
| |

View File

@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/branches3.rs:9:10 --> $DIR/branches3.rs:9:10
| |
LL | |s| s.len() 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 help: consider giving this closure parameter an explicit type
| |
@@ -13,7 +13,7 @@ error[E0282]: type annotations needed
--> $DIR/branches3.rs:18:10 --> $DIR/branches3.rs:18:10
| |
LL | |s| s.len() 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 help: consider giving this closure parameter an explicit type
| |
@@ -24,7 +24,7 @@ error[E0282]: type annotations needed
--> $DIR/branches3.rs:26:10 --> $DIR/branches3.rs:26:10
| |
LL | |s| s.len() 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 help: consider giving this closure parameter an explicit type
| |
@@ -35,7 +35,7 @@ error[E0282]: type annotations needed
--> $DIR/branches3.rs:33:10 --> $DIR/branches3.rs:33:10
| |
LL | |s| s.len() 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -1,11 +1,10 @@
error[E0282]: type annotations needed 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(); LL | let _a: i32 = (ptr as *const _).read();
| ^^^^ | ^^^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type
| | | |
| cannot infer type | cannot infer type
| cannot call a method on a raw pointer with an unknown pointee type
error[E0282]: type annotations needed for `*const _` error[E0282]: type annotations needed for `*const _`
--> $DIR/call_method_unknown_pointee.rs:12:13 --> $DIR/call_method_unknown_pointee.rs:12:13
@@ -22,13 +21,12 @@ LL | let b: *const _ = ptr as *const _;
| ++++++++++ | ++++++++++
error[E0282]: type annotations needed 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(); LL | let _a: i32 = (ptr as *mut _).read();
| ^^^^ | ^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type
| | | |
| cannot infer type | cannot infer type
| cannot call a method on a raw pointer with an unknown pointee type
error[E0282]: type annotations needed for `*mut _` error[E0282]: type annotations needed for `*mut _`
--> $DIR/call_method_unknown_pointee.rs:23:13 --> $DIR/call_method_unknown_pointee.rs:23:13

View File

@@ -1,14 +1,14 @@
error[E0282]: type annotations needed 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(); LL | let _a: i32 = (ptr as &_).read();
| ^^^^ cannot infer type | ^^^^^^^^^^^ cannot infer type
error[E0282]: type annotations needed 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(); 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<T>` in the current scope error[E0599]: no method named `read` found for struct `SmartPtr<T>` in the current scope
--> $DIR/call_method_unknown_referent.rs:46:35 --> $DIR/call_method_unknown_referent.rs:46:35

View File

@@ -21,10 +21,10 @@ note: the traits `Iterator` and `ToTokens` must be implemented
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/not-repeatable.rs:11:13 --> $DIR/not-repeatable.rs:11:25
| |
LL | let _ = quote! { $($ip)* }; LL | let _ = quote! { $($ip)* };
| ^^^^^^^^^^^^^^^^^^ cannot infer type | ^^ cannot infer type
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@@ -5,7 +5,7 @@ LL | let x = [Foo(PhantomData); 2];
| ^ | ^
LL | LL |
LL | extract(x).max(2); 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 help: consider giving `x` an explicit type, where the placeholders `_` are specified
| |

View File

@@ -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::<i32>() + ap.arg::<i32>()
}
}
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);
}

View File

@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
LL | let x: Option<_> = None; LL | let x: Option<_> = None;
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
LL | x.unwrap().method_that_could_exist_on_some_type(); 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 help: consider specifying the generic argument
| |
@@ -16,8 +16,6 @@ error[E0282]: type annotations needed
| |
LL | .sum::<_>() LL | .sum::<_>()
| ^^^ cannot infer type of the type parameter `S` declared on the method `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 error: aborting due to 2 previous errors

View File

@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/closures_in_branches.rs:8:10 --> $DIR/closures_in_branches.rs:8:10
| |
LL | |x| x.len() 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 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 --> $DIR/closures_in_branches.rs:22:10
| |
LL | |x| x.len() 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 help: consider giving this closure parameter an explicit type
| |

View File

@@ -5,7 +5,7 @@ LL | let iv = S ^ index.into();
| ^^ | ^^
LL | LL |
LL | &iv.to_bytes_be(); 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 help: consider giving `iv` an explicit type
| |

View File

@@ -18,7 +18,7 @@ LL | for node in graph.iter() {
| ^^^^ method not found in `&G` | ^^^^ method not found in `&G`
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/issue-13853.rs:28:14 --> $DIR/issue-13853.rs:28:9
| |
LL | node.zomg(); LL | node.zomg();
| ^^^^ cannot infer type | ^^^^ cannot infer type