Auto merge of #131775 - Urgau:rollup-yc4a3sf, r=Urgau
Rollup of 10 pull requests Successful merges: - #131582 (Add wasm32-unknown-emscripten platform support document) - #131694 (Make fuchsia-test-runner.py compatible with new JSON output from llvm-readelf) - #131700 (Fix match_same_arms in stable_mir) - #131712 (Mark the unstable LazyCell::into_inner const) - #131746 (Relax a memory order in `once_box`) - #131754 (Don't report bivariance error when nesting a struct with field errors into another struct) - #131760 (llvm: Match aarch64 data layout to new LLVM layout) - #131764 (Fix unnecessary nesting in run-make test output directories) - #131766 (Add mailmap entry for my dev-desktop setup) - #131771 (Handle gracefully true/false in `cfg(target(..))` compact) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0037048da8
58 changed files with 400 additions and 108 deletions
1
.mailmap
1
.mailmap
|
|
@ -280,6 +280,7 @@ Jerry Hardee <hardeejj9@gmail.com>
|
|||
Jesús Rubio <jesusprubio@gmail.com>
|
||||
Jethro Beekman <github@jbeekman.nl>
|
||||
Jian Zeng <knight42@mail.ustc.edu.cn>
|
||||
Jieyou Xu <jieyouxu@outlook.com> <39484203+jieyouxu@users.noreply.github.com>
|
||||
Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
|
||||
Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>
|
||||
Jihyun Yu <j.yu@navercorp.com> Jihyun Yu <jihyun@nclab.kaist.ac.kr>
|
||||
|
|
|
|||
|
|
@ -723,7 +723,13 @@ pub fn eval_condition(
|
|||
}
|
||||
|
||||
mis.iter().fold(true, |res, mi| {
|
||||
let mut mi = mi.meta_item().unwrap().clone();
|
||||
let Some(mut mi) = mi.meta_item().cloned() else {
|
||||
dcx.emit_err(session_diagnostics::CfgPredicateIdentifier {
|
||||
span: mi.span(),
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
if let [seg, ..] = &mut mi.path.segments[..] {
|
||||
seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,16 @@ pub(crate) unsafe fn create_module<'ll>(
|
|||
}
|
||||
}
|
||||
|
||||
if llvm_version < (20, 0, 0) {
|
||||
if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
|
||||
// LLVM 20 defines three additional address spaces for alternate
|
||||
// pointer kinds used in Windows.
|
||||
// See https://github.com/llvm/llvm-project/pull/111879
|
||||
target_data_layout =
|
||||
target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", "");
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
{
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
|
||||
|
|
|
|||
|
|
@ -1875,24 +1875,15 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
item: &'tcx hir::Item<'tcx>,
|
||||
hir_generics: &hir::Generics<'tcx>,
|
||||
) {
|
||||
let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id);
|
||||
|
||||
match item.kind {
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
for field in tcx.adt_def(item.owner_id).all_fields() {
|
||||
if field.ty(tcx, identity_args).references_error() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Ok
|
||||
}
|
||||
ItemKind::TyAlias(..) => {
|
||||
assert!(
|
||||
tcx.type_alias_is_lazy(item.owner_id),
|
||||
"should not be computing variance of non-weak type alias"
|
||||
);
|
||||
if tcx.type_of(item.owner_id).skip_binder().references_error() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
|
||||
}
|
||||
|
|
@ -1955,6 +1946,15 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
// Look for `ErrorGuaranteed` deeply within this type.
|
||||
if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx
|
||||
.type_of(item.owner_id)
|
||||
.instantiate_identity()
|
||||
.visit_with(&mut HasErrorDeep { tcx, seen: Default::default() })
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
match hir_param.name {
|
||||
hir::ParamName::Error => {}
|
||||
_ => {
|
||||
|
|
@ -1965,6 +1965,46 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Look for `ErrorGuaranteed` deeply within structs' (unsubstituted) fields.
|
||||
struct HasErrorDeep<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
seen: FxHashSet<DefId>,
|
||||
}
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasErrorDeep<'tcx> {
|
||||
type Result = ControlFlow<ErrorGuaranteed>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
match *ty.kind() {
|
||||
ty::Adt(def, _) => {
|
||||
if self.seen.insert(def.did()) {
|
||||
for field in def.all_fields() {
|
||||
self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::Error(guar) => return ControlFlow::Break(guar),
|
||||
_ => {}
|
||||
}
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
|
||||
if let Err(guar) = r.error_reported() {
|
||||
ControlFlow::Break(guar)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
|
||||
if let Err(guar) = c.error_reported() {
|
||||
ControlFlow::Break(guar)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_bivariance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param: &'tcx hir::GenericParam<'tcx>,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
mcount: "\u{1}mcount".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a12".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a16".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a16".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
linker: Some("aarch64-kmc-elf-gcc".into()),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
max_atomic_width: Some(128),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
|
|||
},
|
||||
pointer_width: 64,
|
||||
arch: "aarch64".into(),
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a,+strict-align,+neon,+fp-armv8".into(),
|
||||
max_atomic_width: Some(128),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a,+outline-atomics".into(),
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions { mcount: "\u{1}_mcount".into(), ..base },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+reserve-x18".into(),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: opts,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: opts,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
|
|||
// i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
|
||||
// n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
|
||||
// S128 = 128 bits are the natural alignment of the stack in bits.
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
std: None, // ?
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
std: None, // ?
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(false),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+reserve-x18".into(),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ pub(crate) fn target() -> Target {
|
|||
std: None, // ?
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ pub(crate) fn target() -> Target {
|
|||
std: None, // ?
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
mcount: "\u{1}mcount".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ pub(crate) fn target() -> Target {
|
|||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch,
|
||||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ pub(crate) fn target() -> Target {
|
|||
std: None, // ?
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
data_layout:
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
.into(),
|
||||
arch: "arm64ec".into(),
|
||||
options: base,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,9 @@ fn pretty_terminator_head<W: Write>(writer: &mut W, terminator: &TerminatorKind)
|
|||
fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec<String> {
|
||||
use self::TerminatorKind::*;
|
||||
match terminator {
|
||||
Resume | Abort | Return | Unreachable => vec![],
|
||||
Call { target: None, unwind: UnwindAction::Cleanup(_), .. }
|
||||
| InlineAsm { destination: None, .. } => vec!["unwind".into()],
|
||||
Resume | Abort | Return | Unreachable | Call { target: None, unwind: _, .. } => vec![],
|
||||
Goto { .. } => vec!["".to_string()],
|
||||
SwitchInt { targets, .. } => targets
|
||||
.branches()
|
||||
|
|
@ -197,19 +199,15 @@ fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec<String> {
|
|||
.chain(iter::once("otherwise".into()))
|
||||
.collect(),
|
||||
Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()],
|
||||
Drop { unwind: _, .. } => vec!["return".into()],
|
||||
Call { target: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
|
||||
vec!["return".into(), "unwind".into()]
|
||||
}
|
||||
Call { target: Some(_), unwind: _, .. } => vec!["return".into()],
|
||||
Call { target: None, unwind: UnwindAction::Cleanup(_), .. } => vec!["unwind".into()],
|
||||
Call { target: None, unwind: _, .. } => vec![],
|
||||
Drop { unwind: _, .. } | Call { target: Some(_), unwind: _, .. } => vec!["return".into()],
|
||||
Assert { unwind: UnwindAction::Cleanup(_), .. } => {
|
||||
vec!["success".into(), "unwind".into()]
|
||||
}
|
||||
Assert { unwind: _, .. } => vec!["success".into()],
|
||||
InlineAsm { destination: Some(_), .. } => vec!["goto".into(), "unwind".into()],
|
||||
InlineAsm { destination: None, .. } => vec!["unwind".into()],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,27 +194,17 @@ pub trait MirVisitor {
|
|||
self.visit_place(place, PlaceContext::MUTATING, location);
|
||||
self.visit_rvalue(rvalue, location);
|
||||
}
|
||||
StatementKind::FakeRead(_, place) => {
|
||||
StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => {
|
||||
self.visit_place(place, PlaceContext::NON_MUTATING, location);
|
||||
}
|
||||
StatementKind::SetDiscriminant { place, .. } => {
|
||||
StatementKind::SetDiscriminant { place, .. }
|
||||
| StatementKind::Deinit(place)
|
||||
| StatementKind::Retag(_, place) => {
|
||||
self.visit_place(place, PlaceContext::MUTATING, location);
|
||||
}
|
||||
StatementKind::Deinit(place) => {
|
||||
self.visit_place(place, PlaceContext::MUTATING, location);
|
||||
}
|
||||
StatementKind::StorageLive(local) => {
|
||||
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
|
||||
self.visit_local(local, PlaceContext::NON_USE, location);
|
||||
}
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.visit_local(local, PlaceContext::NON_USE, location);
|
||||
}
|
||||
StatementKind::Retag(_, place) => {
|
||||
self.visit_place(place, PlaceContext::MUTATING, location);
|
||||
}
|
||||
StatementKind::PlaceMention(place) => {
|
||||
self.visit_place(place, PlaceContext::NON_MUTATING, location);
|
||||
}
|
||||
StatementKind::AscribeUserType { place, projections, variance: _ } => {
|
||||
self.visit_place(place, PlaceContext::NON_USE, location);
|
||||
self.visit_user_type_projection(projections);
|
||||
|
|
@ -234,8 +224,7 @@ pub trait MirVisitor {
|
|||
self.visit_operand(count, location);
|
||||
}
|
||||
},
|
||||
StatementKind::ConstEvalCounter => {}
|
||||
StatementKind::Nop => {}
|
||||
StatementKind::ConstEvalCounter | StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,14 +293,15 @@ pub trait MirVisitor {
|
|||
location: Location,
|
||||
) {
|
||||
match elem {
|
||||
ProjectionElem::Deref => {}
|
||||
ProjectionElem::Downcast(_idx) => {}
|
||||
ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ }
|
||||
| ProjectionElem::Deref
|
||||
| ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
|
||||
ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location),
|
||||
ProjectionElem::Index(local) => self.visit_local(local, ptx, location),
|
||||
ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {}
|
||||
ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
|
||||
ProjectionElem::Downcast(_idx) => {}
|
||||
ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location),
|
||||
ProjectionElem::Subtype(ty) => self.visit_ty(ty, location),
|
||||
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => {
|
||||
self.visit_ty(ty, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@ impl Visitable for Ty {
|
|||
match self.kind() {
|
||||
super::ty::TyKind::RigidTy(ty) => ty.visit(visitor)?,
|
||||
super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor)?,
|
||||
super::ty::TyKind::Param(_) => {}
|
||||
super::ty::TyKind::Bound(_, _) => {}
|
||||
super::ty::TyKind::Param(_) | super::ty::TyKind::Bound(_, _) => {}
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
|
@ -48,8 +47,7 @@ impl Visitable for TyConst {
|
|||
}
|
||||
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||
match &self.kind {
|
||||
crate::ty::TyConstKind::Param(_) => {}
|
||||
crate::ty::TyConstKind::Bound(_, _) => {}
|
||||
crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {}
|
||||
crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
|
||||
crate::ty::TyConstKind::Value(ty, alloc) => {
|
||||
alloc.visit(visitor)?;
|
||||
|
|
@ -166,17 +164,17 @@ impl Visitable for RigidTy {
|
|||
reg.visit(visitor);
|
||||
ty.visit(visitor)
|
||||
}
|
||||
RigidTy::FnDef(_, args) => args.visit(visitor),
|
||||
RigidTy::Adt(_, args)
|
||||
| RigidTy::Closure(_, args)
|
||||
| RigidTy::Coroutine(_, args, _)
|
||||
| RigidTy::CoroutineWitness(_, args)
|
||||
| RigidTy::FnDef(_, args) => args.visit(visitor),
|
||||
RigidTy::FnPtr(sig) => sig.visit(visitor),
|
||||
RigidTy::Closure(_, args) => args.visit(visitor),
|
||||
RigidTy::Coroutine(_, args, _) => args.visit(visitor),
|
||||
RigidTy::CoroutineWitness(_, args) => args.visit(visitor),
|
||||
RigidTy::Dynamic(pred, r, _) => {
|
||||
pred.visit(visitor)?;
|
||||
r.visit(visitor)
|
||||
}
|
||||
RigidTy::Tuple(fields) => fields.visit(visitor),
|
||||
RigidTy::Adt(_, args) => args.visit(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
|
|||
/// assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
|
||||
/// ```
|
||||
#[unstable(feature = "lazy_cell_into_inner", issue = "125623")]
|
||||
pub fn into_inner(this: Self) -> Result<T, F> {
|
||||
pub const fn into_inner(this: Self) -> Result<T, F> {
|
||||
match this.state.into_inner() {
|
||||
State::Init(data) => Ok(data),
|
||||
State::Uninit(f) => Err(f),
|
||||
|
|
@ -306,6 +306,6 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
|
|||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn panic_poisoned() -> ! {
|
||||
const fn panic_poisoned() -> ! {
|
||||
panic!("LazyCell instance has previously been poisoned")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
use crate::mem::replace;
|
||||
use crate::ptr::null_mut;
|
||||
use crate::sync::atomic::AtomicPtr;
|
||||
use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
|
||||
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||
|
||||
pub(crate) struct OnceBox<T> {
|
||||
ptr: AtomicPtr<T>,
|
||||
|
|
@ -60,7 +60,7 @@ impl<T> OnceBox<T> {
|
|||
#[cold]
|
||||
fn initialize(&self, f: impl FnOnce() -> Box<T>) -> &T {
|
||||
let new_ptr = Box::into_raw(f());
|
||||
match self.ptr.compare_exchange(null_mut(), new_ptr, AcqRel, Acquire) {
|
||||
match self.ptr.compare_exchange(null_mut(), new_ptr, Release, Acquire) {
|
||||
Ok(_) => unsafe { &*new_ptr },
|
||||
Err(ptr) => {
|
||||
// Lost the race to another thread.
|
||||
|
|
|
|||
|
|
@ -193,18 +193,38 @@ class TestEnvironment:
|
|||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
if process.returncode:
|
||||
self.env_logger.error(
|
||||
f"llvm-readelf failed for binary {binary} with output {process.stdout}"
|
||||
e = f"llvm-readelf failed for binary {binary} with output {process.stdout}"
|
||||
self.env_logger.error(e)
|
||||
raise Exception(e)
|
||||
|
||||
try:
|
||||
elf_output = json.loads(process.stdout)
|
||||
except Exception as e:
|
||||
e.add_note(f"Failed to read JSON from llvm-readelf for binary {binary}")
|
||||
e.add_note(f"stdout: {process.stdout}")
|
||||
raise
|
||||
|
||||
try:
|
||||
note_sections = elf_output[0]["NoteSections"]
|
||||
except Exception as e:
|
||||
e.add_note(
|
||||
f'Failed to read "NoteSections" from llvm-readelf for binary {binary}'
|
||||
)
|
||||
raise Exception(f"Unreadable build-id for binary {binary}")
|
||||
data = json.loads(process.stdout)
|
||||
if len(data) != 1:
|
||||
raise Exception(f"Unreadable output from llvm-readelf for binary {binary}")
|
||||
notes = data[0]["Notes"]
|
||||
for note in notes:
|
||||
note_section = note["NoteSection"]
|
||||
if note_section["Name"] == ".note.gnu.build-id":
|
||||
return note_section["Note"]["Build ID"]
|
||||
e.add_note(f"elf_output: {elf_output}")
|
||||
raise
|
||||
|
||||
for entry in note_sections:
|
||||
try:
|
||||
note_section = entry["NoteSection"]
|
||||
if note_section["Name"] == ".note.gnu.build-id":
|
||||
return note_section["Notes"][0]["Build ID"]
|
||||
except Exception as e:
|
||||
e.add_note(
|
||||
f'Failed to read ".note.gnu.build-id" from NoteSections \
|
||||
entry in llvm-readelf for binary {binary}'
|
||||
)
|
||||
e.add_note(f"NoteSections: {note_sections}")
|
||||
raise
|
||||
raise Exception(f"Build ID not found for binary {binary}")
|
||||
|
||||
def generate_buildid_dir(
|
||||
|
|
|
|||
|
|
@ -84,6 +84,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-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md)
|
||||
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
|
||||
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
||||
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ target | std | notes
|
|||
[`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline
|
||||
[`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline
|
||||
[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat
|
||||
`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
|
||||
[`wasm32-unknown-emscripten`](platform-support/wasm32-unknown-emscripten.md) | ✓ | WebAssembly via Emscripten
|
||||
[`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly
|
||||
`wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
|
||||
[`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
|
||||
|
|
|
|||
168
src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md
Normal file
168
src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# `wasm32-unknown-emscripten`
|
||||
|
||||
**Tier: 2**
|
||||
|
||||
The `wasm32-unknown-emscripten` target is a WebAssembly compilation target which
|
||||
uses the [Emscripten](https://emscripten.org/) compiler toolchain. Emscripten is
|
||||
a C/C++ toolchain designed to make it as easy as possible to port C/C++ code
|
||||
written for Linux to run on the web or in other JavaScript runtimes such as Node.
|
||||
It thus provides POSIX-compatible (musl) `libc` and `libstd` implementations and
|
||||
many Linux APIs, access to the OpenGL and SDL APIs, and the ability to run arbitrary
|
||||
JavaScript code, all based on web APIs using JS glue code. With the
|
||||
`wasm32-unknown-emscripten` target, Rust code can interoperate with Emscripten's
|
||||
ecosystem, C/C++ and JS code, and web APIs.
|
||||
|
||||
One existing user of this target is the
|
||||
[`pyodide` project](https://pyodide.org/) which provides a Python runtime in
|
||||
WebAssembly using Emscripten and compiles Python extension modules written in Rust
|
||||
to the `wasm32-unknown-emscripten` target.
|
||||
|
||||
If you want to generate a standalone WebAssembly binary that does not require
|
||||
access to the web APIs or the Rust standard library, the
|
||||
[`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) target may be better
|
||||
suited for you. However, [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md)
|
||||
does not (easily) support interop with C/C++ code. Please refer to the
|
||||
[wasm-bindgen](https://crates.io/crates/wasm-bindgen) crate in case you want to
|
||||
interoperate with JavaScript with this target.
|
||||
|
||||
Like Emscripten, the WASI targets [`wasm32-wasip1`](./wasm32-wasip1.md) and
|
||||
[`wasm32-wasip2`](./wasm32-wasip2.md) also provide access to the host environment,
|
||||
support interop with C/C++ (and other languages), and support most of the Rust
|
||||
standard library. While the WASI targets are portable across different hosts
|
||||
(web and non-web), WASI has no standard way of accessing web APIs, whereas
|
||||
Emscripten has the ability to run arbitrary JS from WASM and access many web APIs.
|
||||
If you are only targeting the web and need to access web APIs, the
|
||||
`wasm32-unknown-emscripten` target may be preferable.
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- Hood Chatham, https://github.com/hoodmane
|
||||
- Juniper Tyree, https://github.com/juntyr
|
||||
|
||||
## Requirements
|
||||
|
||||
This target is cross-compiled. The Emscripten compiler toolchain `emcc` must be
|
||||
installed to link WASM binaries for this target. You can install `emcc` using:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/emscripten-core/emsdk.git --depth 1
|
||||
./emsdk/emsdk install 3.1.68
|
||||
./emsdk/emsdk activate 3.1.68
|
||||
source ./emsdk/emsdk_env.sh
|
||||
```
|
||||
|
||||
Please refer to <https://emscripten.org/docs/getting_started/downloads.html> for
|
||||
further details and instructions.
|
||||
|
||||
## Building the target
|
||||
|
||||
Building this target can be done by:
|
||||
|
||||
* Configure the `wasm32-unknown-emscripten` target to get built.
|
||||
* Ensure the `WebAssembly` target backend is not disabled in LLVM.
|
||||
|
||||
These are all controlled through `config.toml` options. It should be possible
|
||||
to build this target on any platform. A minimal example configuration would be:
|
||||
|
||||
```toml
|
||||
[llvm]
|
||||
targets = "WebAssembly"
|
||||
|
||||
[build]
|
||||
build-stage = 1
|
||||
target = ["wasm32-unknown-emscripten"]
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust programs can be compiled by adding this target via rustup:
|
||||
|
||||
```sh
|
||||
$ rustup target add wasm32-unknown-emscripten
|
||||
```
|
||||
|
||||
and then compiling with the target:
|
||||
|
||||
```sh
|
||||
$ rustc foo.rs --target wasm32-unknown-emscripten
|
||||
$ file foo.wasm
|
||||
```
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
This target can be cross-compiled from any host.
|
||||
|
||||
## Emscripten ABI Compatibility
|
||||
|
||||
The Emscripten compiler toolchain does not follow a semantic versioning scheme
|
||||
that clearly indicates when breaking changes to the ABI can be made. Additionally,
|
||||
Emscripten offers many different ABIs even for a single version of Emscripten
|
||||
depending on the linker flags used, e.g. `-fexceptions` and `-sWASM_BIGINT`. If
|
||||
the ABIs mismatch, your code may exhibit undefined behaviour.
|
||||
|
||||
To ensure that the ABIs of your Rust code, of the Rust standard library, and of
|
||||
other code compiled for Emscripten all match, you should rebuild the Rust standard
|
||||
library with your local Emscripten version and settings using:
|
||||
|
||||
```sh
|
||||
cargo +nightly -Zbuild-std build
|
||||
```
|
||||
|
||||
If you still want to use the pre-compiled `std` from rustup, you should ensure
|
||||
that your local Emscripten matches the version used by Rust and be careful about
|
||||
any `-C link-arg`s that you compiled your Rust code with.
|
||||
|
||||
## Testing
|
||||
|
||||
This target is not extensively tested in CI for the rust-lang/rust repository. It
|
||||
can be tested locally, for example, with:
|
||||
|
||||
```sh
|
||||
./x.py test --target wasm32-unknown-emscripten --skip src/tools/linkchecker
|
||||
```
|
||||
|
||||
To run these tests, both `emcc` and `node` need to be in your `$PATH`. You can
|
||||
install `node`, for example, using `nvm` by following the instructions at
|
||||
<https://github.com/nvm-sh/nvm#install--update-script>.
|
||||
|
||||
If you need to test WebAssembly compatibility *in general*, it is recommended
|
||||
to test the [`wasm32-wasip1`](./wasm32-wasip1.md) target instead.
|
||||
|
||||
## Conditionally compiling code
|
||||
|
||||
It's recommended to conditionally compile code for this target with:
|
||||
|
||||
```text
|
||||
#[cfg(target_os = "emscripten")]
|
||||
```
|
||||
|
||||
It may sometimes be necessary to conditionally compile code for WASM targets
|
||||
which do *not* use emscripten, which can be achieved with:
|
||||
|
||||
```text
|
||||
#[cfg(all(target_family = "wasm", not(target_os = "emscripten)))]
|
||||
```
|
||||
|
||||
## Enabled WebAssembly features
|
||||
|
||||
WebAssembly is an evolving standard which adds new features such as new
|
||||
instructions over time. This target's default set of supported WebAssembly
|
||||
features will additionally change over time. The `wasm32-unknown-emscripten` target
|
||||
inherits the default settings of LLVM which typically, but not necessarily, matches
|
||||
the default settings of Emscripten as well. At link time, `emcc` configures the
|
||||
linker to use Emscripten's settings.
|
||||
|
||||
Please refer to the [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md)
|
||||
target's documentation on which WebAssembly features Rust enables by default, how
|
||||
features can be disabled, and how Rust code can be conditionally compiled based on
|
||||
which features are enabled.
|
||||
|
||||
Note that Rust code compiled for `wasm32-unknown-emscripten` currently enables
|
||||
`-fexceptions` (JS exceptions) by default unless the Rust code is compiled with
|
||||
`-Cpanic=abort`. `-fwasm-exceptions` (WASM exceptions) is not yet currently supported,
|
||||
see <https://github.com/rust-lang/rust/issues/112195>.
|
||||
|
||||
Please refer to the [Emscripten ABI compatibility](#emscripten-abi-compatibility)
|
||||
section to ensure that the features that are enabled do not cause an ABI mismatch
|
||||
between your Rust code, the pre-compiled Rust standard library, and other code compiled
|
||||
for Emscripten.
|
||||
|
|
@ -46,8 +46,8 @@ This target currently has no equivalent in C/C++. There is no C/C++ toolchain
|
|||
for this target. While interop is theoretically possible it's recommended to
|
||||
instead use one of:
|
||||
|
||||
* `wasm32-unknown-emscripten` - for web-based use cases the Emscripten
|
||||
toolchain is typically chosen for running C/C++.
|
||||
* [`wasm32-unknown-emscripten`](./wasm32-unknown-emscripten.md) - for web-based
|
||||
use cases the Emscripten toolchain is typically chosen for running C/C++.
|
||||
* [`wasm32-wasip1`](./wasm32-wasip1.md) - the wasi-sdk toolchain is used to
|
||||
compile C/C++ on this target and can interop with Rust code. WASI works on
|
||||
the web so far as there's no blocker, but an implementation of WASI APIs
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ impl TestCx<'_> {
|
|||
let src_root = self.config.src_base.parent().unwrap().parent().unwrap();
|
||||
let src_root = cwd.join(&src_root);
|
||||
|
||||
// FIXME(Zalathar): This should probably be `output_base_dir` to avoid
|
||||
// an unnecessary extra subdirectory, but since legacy Makefile tests
|
||||
// are hopefully going away, it seems safer to leave this perilous code
|
||||
// as-is until it can all be deleted.
|
||||
let tmpdir = cwd.join(self.output_base_name());
|
||||
if tmpdir.exists() {
|
||||
self.aggressive_rm_rf(&tmpdir).unwrap();
|
||||
|
|
@ -213,7 +217,7 @@ impl TestCx<'_> {
|
|||
// `rmake_out/` directory.
|
||||
//
|
||||
// This setup intentionally diverges from legacy Makefile run-make tests.
|
||||
let base_dir = self.output_base_name();
|
||||
let base_dir = self.output_base_dir();
|
||||
if base_dir.exists() {
|
||||
self.aggressive_rm_rf(&base_dir).unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process:
|
|||
structure within `build/<target>/test/run-make/`
|
||||
|
||||
```
|
||||
<test-name>/<test-name>/
|
||||
<test-name>/
|
||||
rmake.exe # recipe binary
|
||||
rmake_out/ # sources from test sources copied over
|
||||
```
|
||||
|
|
|
|||
|
|
@ -14,4 +14,8 @@ fn two() {}
|
|||
//~^ ERROR invalid predicate `target_pointer`
|
||||
fn three() {}
|
||||
|
||||
#[cfg(target(true))]
|
||||
//~^ ERROR `cfg` predicate key must be an identifier
|
||||
fn four() {}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,13 @@ error[E0537]: invalid predicate `target_pointer`
|
|||
LL | #[cfg(target(os = "linux", pointer(width = "64")))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-target-compact-errors.rs:17:14
|
||||
|
|
||||
LL | #[cfg(target(true))]
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0537, E0565.
|
||||
For more information about an error, try `rustc --explain E0537`.
|
||||
|
|
|
|||
13
tests/ui/variance/type-resolve-error-two-structs-deep.rs
Normal file
13
tests/ui/variance/type-resolve-error-two-structs-deep.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Make sure we don't report bivariance errors when nesting structs w/ unresolved
|
||||
// fields into *other* structs.
|
||||
|
||||
struct Hello<'a> {
|
||||
missing: Missing<'a>,
|
||||
//~^ ERROR cannot find type `Missing` in this scope
|
||||
}
|
||||
|
||||
struct Other<'a> {
|
||||
hello: Hello<'a>,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
error[E0412]: cannot find type `Missing` in this scope
|
||||
--> $DIR/type-resolve-error-two-structs-deep.rs:5:14
|
||||
|
|
||||
LL | missing: Missing<'a>,
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue