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",
"serde",
"serde_json",
"similar",
"spdx-rs",
]

View File

@@ -22,11 +22,9 @@ use smallvec::SmallVec;
use crate::attributes::{self, llfn_attrs_from_instance};
use crate::builder::Builder;
use crate::context::CodegenCx;
use crate::llvm::{self, Attribute, AttributePlace};
use crate::llvm::{self, Attribute, AttributePlace, Type, Value};
use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
trait ArgAttributesExt {
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 tracing::debug;
use crate::attributes;
use crate::builder::Builder;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::ToLlvmBool;
use crate::type_::Type;
use crate::llvm::{self, ToLlvmBool, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{attributes, llvm};
impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn codegen_inline_asm(

View File

@@ -13,8 +13,9 @@ use smallvec::SmallVec;
use crate::context::SimpleCx;
use crate::errors::SanitizerMemtagRequiresMte;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
use crate::value::Value;
use crate::llvm::{
self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects, Value,
};
use crate::{Session, attributes, llvm_util};
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 super::ModuleLlvm;
use crate::attributes;
use crate::builder::Builder;
use crate::context::CodegenCx;
use crate::value::Value;
use crate::{attributes, llvm};
use crate::llvm::{self, Value};
pub(crate) struct ValueIter<'ll> {
cur: Option<&'ll Value>,

View File

@@ -37,11 +37,9 @@ use crate::common::Funclet;
use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
use crate::llvm::{
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, FromGeneric, GEPNoWrapFlags, Metadata, TRUE,
ToLlvmBool,
ToLlvmBool, Type, Value,
};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
#[must_use]
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::context::SimpleCx;
use crate::declare::declare_simple_fn;
use crate::llvm;
use crate::llvm::{Metadata, TRUE, Type};
use crate::value::Value;
use crate::llvm::{self, Metadata, TRUE, Type, Value};
pub(crate) fn adjust_activity_to_abi<'tcx>(
tcx: TyCtxt<'tcx>,

View File

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

View File

@@ -20,9 +20,7 @@ use tracing::debug;
use crate::consts::const_alloc_to_llvm;
pub(crate) use crate::context::CodegenCx;
use crate::context::{GenericCx, SCx};
use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool};
use crate::type_::Type;
use crate::value::Value;
use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value};
/*
* 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::errors::SymbolAlreadyDefined;
use crate::type_::Type;
use crate::llvm::{self, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{base, debuginfo, llvm};
use crate::{base, debuginfo};
pub(crate) fn const_alloc_to_llvm<'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::callee::get_fn;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
use crate::llvm::{Metadata, MetadataKindId, Module};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value};
use crate::{attributes, common, coverageinfo, debuginfo, llvm_util};
/// `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

View File

@@ -9,8 +9,7 @@ use rustc_session::config::{CrateType, DebugInfo};
use crate::builder::Builder;
use crate::common::CodegenCx;
use crate::llvm;
use crate::value::Value;
use crate::llvm::{self, Value};
/// 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.

View File

@@ -41,8 +41,7 @@ use crate::llvm::debuginfo::{
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
};
use crate::llvm::{self, FromGeneric};
use crate::value::Value;
use crate::llvm::{self, FromGeneric, Value};
impl PartialEq for llvm::Metadata {
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 crate::builder::Builder;
use crate::common::{AsCCharPtr, CodegenCx};
use crate::llvm;
use crate::llvm::debuginfo::{
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope,
DITemplateTypeParameter, DIType, DIVariable,
};
use crate::value::Value;
use crate::llvm::{self, Value};
mod create_scope_map;
mod dwarf_const;

View File

@@ -23,13 +23,11 @@ use smallvec::SmallVec;
use tracing::debug;
use crate::abi::FnAbiLlvmExt;
use crate::attributes;
use crate::common::AsCCharPtr;
use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx};
use crate::llvm::AttributePlace::Function;
use crate::llvm::{FromGeneric, Visibility};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, llvm};
use crate::llvm::{self, FromGeneric, Type, Value, Visibility};
/// 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::context::CodegenCx;
use crate::errors::AutoDiffWithoutEnable;
use crate::llvm::{self, Metadata};
use crate::type_::Type;
use crate::llvm::{self, Metadata, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg;
use crate::value::Value;
fn call_simple_intrinsic<'ll, 'tcx>(
bx: &mut Builder<'_, 'll, 'tcx>,

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ use rustc_span::{DUMMY_SP, Span};
use tracing::debug;
use crate::common::*;
use crate::type_::Type;
use crate::llvm::Type;
fn uncached_llvm_type<'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 crate::builder::Builder;
use crate::type_::Type;
use crate::llvm::{Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
fn round_up_to_alignment<'ll>(
bx: &mut Builder<'_, 'll, '_>,

View File

@@ -1,8 +1,7 @@
use std::hash::{Hash, Hasher};
use std::{fmt, ptr};
use crate::llvm;
pub(crate) use crate::llvm::Value;
use crate::llvm::{self, Value};
impl PartialEq for Value {
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::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,

View File

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

View File

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

View File

@@ -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),

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',
], 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'] }

View File

@@ -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))]

View File

@@ -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::*;
}

View File

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

View File

@@ -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::*;
}

View File

@@ -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::*;
}

View File

@@ -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",
)))]

View File

@@ -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::*;
}

View File

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

View File

@@ -15,5 +15,13 @@ labels_blocking_approval = [
"S-waiting-on-crater",
"S-waiting-on-fcp",
"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
)
});
// 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,

View File

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

View File

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

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"
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.85"
similar = "2.7.0"
spdx-rs = "0.5.1"

View File

@@ -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");

View File

@@ -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<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 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<R: Read>(
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<R: Read>(
config.mode,
&mut local_poisoned,
path,
src,
file_contents,
&mut |ref ln @ DirectiveLine { line_number, .. }| {
if !ln.applies_to_test_revision(test_revision) {
return;

View File

@@ -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<R: Read>(
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<R: Read>(
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);
}

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.
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,
);

View File

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

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;
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

View File

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

View File

@@ -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 <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 call a method on a raw pointer with an unknown pointee type
| |
| cannot infer type
| cannot call a method on a raw pointer with an unknown pointee 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 call a method on a raw pointer with an unknown pointee type
| |
| cannot infer type
| cannot call a method on a raw pointer with an unknown pointee type
error[E0282]: type annotations needed for `*mut _`
--> $DIR/call_method_unknown_pointee.rs:23:13

View File

@@ -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<T>` in the current scope
--> $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
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

View File

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

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;
| ^^^^ 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

View File

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

View File

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

View File

@@ -18,7 +18,7 @@ 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