about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs67
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs39
-rw-r--r--compiler/stable_mir/src/fold.rs25
-rw-r--r--compiler/stable_mir/src/ty.rs46
-rw-r--r--compiler/stable_mir/src/visitor.rs20
-rw-r--r--library/core/src/sync/exclusive.rs46
-rw-r--r--src/ci/docker/README.md4
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile5
-rw-r--r--src/ci/docker/scripts/crosstool-ng-git.sh17
-rw-r--r--src/ci/docker/scripts/crosstool-ng.sh2
-rw-r--r--src/tools/compiletest/src/common.rs6
-rw-r--r--src/tools/compiletest/src/header/needs.rs5
-rw-r--r--tests/incremental/change_crate_dep_kind.rs1
-rw-r--r--tests/ui/abi/compatibility.rs183
-rw-r--r--tests/ui/abi/relocation_model_pic.rs3
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.run.stderr2
-rw-r--r--tests/ui/suggestions/auxiliary/extern-issue-98562.rs26
-rw-r--r--tests/ui/suggestions/issue-98562.rs12
-rw-r--r--tests/ui/suggestions/issue-98562.stderr11
-rw-r--r--tests/ui/suggestions/missing-assoc-fn.stderr2
24 files changed, 450 insertions, 80 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 88c98fa979e..5fa65f33c76 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -329,41 +329,52 @@ fn bounds_from_generic_predicates<'tcx>(
             _ => {}
         }
     }
-    let generics = if types.is_empty() {
-        "".to_string()
-    } else {
-        format!(
-            "<{}>",
-            types
-                .keys()
-                .filter_map(|t| match t.kind() {
-                    ty::Param(_) => Some(t.to_string()),
-                    // Avoid suggesting the following:
-                    // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
-                    _ => None,
-                })
-                .collect::<Vec<_>>()
-                .join(", ")
-        )
-    };
+
     let mut where_clauses = vec![];
+    let mut types_str = vec![];
     for (ty, bounds) in types {
-        where_clauses
-            .extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))));
-    }
-    for projection in &projections {
-        let p = projection.skip_binder();
-        // FIXME: this is not currently supported syntax, we should be looking at the `types` and
-        // insert the associated types where they correspond, but for now let's be "lazy" and
-        // propose this instead of the following valid resugaring:
-        // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
-        where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term));
+        if let ty::Param(_) = ty.kind() {
+            let mut bounds_str = vec![];
+            for bound in bounds {
+                let mut projections_str = vec![];
+                for projection in &projections {
+                    let p = projection.skip_binder();
+                    let alias_ty = p.projection_ty;
+                    if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty {
+                        let name = tcx.item_name(alias_ty.def_id);
+                        projections_str.push(format!("{} = {}", name, p.term));
+                    }
+                }
+                let bound_def_path = tcx.def_path_str(bound);
+                if projections_str.is_empty() {
+                    where_clauses.push(format!("{}: {}", ty, bound_def_path));
+                } else {
+                    bounds_str.push(format!("{}<{}>", bound_def_path, projections_str.join(", ")));
+                }
+            }
+            if bounds_str.is_empty() {
+                types_str.push(ty.to_string());
+            } else {
+                types_str.push(format!("{}: {}", ty, bounds_str.join(" + ")));
+            }
+        } else {
+            // Avoid suggesting the following:
+            // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
+            where_clauses.extend(
+                bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))),
+            );
+        }
     }
+
+    let generics =
+        if types_str.is_empty() { "".to_string() } else { format!("<{}>", types_str.join(", ")) };
+
     let where_clauses = if where_clauses.is_empty() {
-        String::new()
+        "".to_string()
     } else {
         format!(" where {}", where_clauses.join(", "))
     };
+
     (generics, where_clauses)
 }
 
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 441aafd1257..1a9dea99f64 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -86,6 +86,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::ImplDef(self.create_def_id(did))
     }
 
+    pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
+        stable_mir::ty::RegionDef(self.create_def_id(did))
+    }
+
     pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
         stable_mir::ty::Prov(self.create_alloc_id(aid))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 5ff17613b4e..c6c97ce35e8 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,7 +7,8 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use hir::def::DefKind;
+use crate::rustc_smir::hir::def::DefKind;
+use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
@@ -1500,9 +1501,39 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
 impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
     type T = stable_mir::ty::Region;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
-        // FIXME: add a real implementation of stable regions
-        opaque(self)
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        Region { kind: self.kind().stable(tables) }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
+    type T = stable_mir::ty::RegionKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use stable_mir::ty::RegionKind;
+        match self {
+            ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
+                def_id: tables.region_def(early_reg.def_id),
+                index: early_reg.index,
+                name: early_reg.name.to_string(),
+            }),
+            ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound(
+                db_index.as_u32(),
+                BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
+            ),
+            ty::ReStatic => RegionKind::ReStatic,
+            ty::RePlaceholder(place_holder) => {
+                RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
+                    universe: place_holder.universe.as_u32(),
+                    bound: BoundRegion {
+                        var: place_holder.bound.var.as_u32(),
+                        kind: place_holder.bound.kind.stable(tables),
+                    },
+                })
+            }
+            ty::ReErased => RegionKind::ReErased,
+            _ => unreachable!("{self:?}"),
+        }
     }
 }
 
diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
index 1da123e922b..6471b2c2a3a 100644
--- a/compiler/stable_mir/src/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -4,17 +4,20 @@ use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
-    GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
+    GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
 };
 
 pub trait Folder: Sized {
     type Break;
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ty.super_fold(self)
     }
     fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
         c.super_fold(self)
     }
+    fn fold_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
+        reg.super_fold(self)
+    }
 }
 
 pub trait Foldable: Sized + Clone {
@@ -26,7 +29,7 @@ pub trait Foldable: Sized + Clone {
 
 impl Foldable for Ty {
     fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.visit_ty(self)
+        folder.fold_ty(self)
     }
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut kind = self.kind();
@@ -106,6 +109,15 @@ impl Foldable for GenericArgs {
     }
 }
 
+impl Foldable for Region {
+    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
+        folder.fold_reg(self)
+    }
+    fn super_fold<V: Folder>(&self, _: &mut V) -> ControlFlow<V::Break, Self> {
+        ControlFlow::Continue(self.clone())
+    }
+}
+
 impl Foldable for GenericArgKind {
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut this = self.clone();
@@ -136,7 +148,10 @@ impl Foldable for RigidTy {
             }
             RigidTy::Slice(inner) => *inner = inner.fold(folder)?,
             RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?,
-            RigidTy::Ref(_, ty, _) => *ty = ty.fold(folder)?,
+            RigidTy::Ref(reg, ty, _) => {
+                *reg = reg.fold(folder)?;
+                *ty = ty.fold(folder)?
+            }
             RigidTy::FnDef(_, args) => *args = args.fold(folder)?,
             RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?,
             RigidTy::Closure(_, args) => *args = args.fold(folder)?,
@@ -214,7 +229,7 @@ pub enum Never {}
 impl Folder for GenericArgs {
     type Break = Never;
 
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ControlFlow::Continue(match ty.kind() {
             TyKind::Param(p) => self[p],
             _ => *ty,
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 82007e30683..6029e3c11ad 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1,7 +1,7 @@
 use super::{
     mir::Safety,
     mir::{Body, Mutability},
-    with, AllocId, DefId,
+    with, AllocId, DefId, Symbol,
 };
 use crate::Opaque;
 use std::fmt::{self, Debug, Formatter};
@@ -34,7 +34,46 @@ pub struct Const {
 }
 
 type Ident = Opaque;
-pub type Region = Opaque;
+
+#[derive(Debug, Clone)]
+pub struct Region {
+    pub kind: RegionKind,
+}
+
+#[derive(Debug, Clone)]
+pub enum RegionKind {
+    ReEarlyBound(EarlyBoundRegion),
+    ReLateBound(DebruijnIndex, BoundRegion),
+    ReStatic,
+    RePlaceholder(Placeholder<BoundRegion>),
+    ReErased,
+}
+
+pub(crate) type DebruijnIndex = u32;
+
+#[derive(Debug, Clone)]
+pub struct EarlyBoundRegion {
+    pub def_id: RegionDef,
+    pub index: u32,
+    pub name: Symbol,
+}
+
+pub(crate) type BoundVar = u32;
+
+#[derive(Debug, Clone)]
+pub struct BoundRegion {
+    pub var: BoundVar,
+    pub kind: BoundRegionKind,
+}
+
+pub(crate) type UniverseIndex = u32;
+
+#[derive(Debug, Clone)]
+pub struct Placeholder<T> {
+    pub universe: UniverseIndex,
+    pub bound: T,
+}
+
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub struct Span(pub usize);
 
@@ -152,6 +191,9 @@ pub struct ConstDef(pub DefId);
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct ImplDef(pub DefId);
 
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct RegionDef(pub DefId);
+
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
 
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index 9c3b4cd994a..96100958138 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -4,7 +4,7 @@ use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
-    Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
+    Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
 };
 
 pub trait Visitor: Sized {
@@ -15,6 +15,9 @@ pub trait Visitor: Sized {
     fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
         c.super_visit(self)
     }
+    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
+        reg.super_visit(self)
+    }
 }
 
 pub trait Visitable {
@@ -101,6 +104,16 @@ impl Visitable for GenericArgs {
     }
 }
 
+impl Visitable for Region {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        visitor.visit_reg(self)
+    }
+
+    fn super_visit<V: Visitor>(&self, _: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
 impl Visitable for GenericArgKind {
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match self {
@@ -128,7 +141,10 @@ impl Visitable for RigidTy {
             }
             RigidTy::Slice(inner) => inner.visit(visitor),
             RigidTy::RawPtr(ty, _) => ty.visit(visitor),
-            RigidTy::Ref(_, ty, _) => ty.visit(visitor),
+            RigidTy::Ref(reg, ty, _) => {
+                reg.visit(visitor);
+                ty.visit(visitor)
+            }
             RigidTy::FnDef(_, args) => args.visit(visitor),
             RigidTy::FnPtr(sig) => sig.visit(visitor),
             RigidTy::Closure(_, args) => args.visit(visitor),
diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs
index 3f3e19c55d4..ff538d55c60 100644
--- a/library/core/src/sync/exclusive.rs
+++ b/library/core/src/sync/exclusive.rs
@@ -2,6 +2,8 @@
 
 use core::fmt;
 use core::future::Future;
+use core::marker::Tuple;
+use core::ops::{Generator, GeneratorState};
 use core::pin::Pin;
 use core::task::{Context, Poll};
 
@@ -168,10 +170,52 @@ impl<T> From<T> for Exclusive<T> {
 }
 
 #[unstable(feature = "exclusive_wrapper", issue = "98407")]
-impl<T: Future + ?Sized> Future for Exclusive<T> {
+impl<F, Args> FnOnce<Args> for Exclusive<F>
+where
+    F: FnOnce<Args>,
+    Args: Tuple,
+{
+    type Output = F::Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
+        self.into_inner().call_once(args)
+    }
+}
+
+#[unstable(feature = "exclusive_wrapper", issue = "98407")]
+impl<F, Args> FnMut<Args> for Exclusive<F>
+where
+    F: FnMut<Args>,
+    Args: Tuple,
+{
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
+        self.get_mut().call_mut(args)
+    }
+}
+
+#[unstable(feature = "exclusive_wrapper", issue = "98407")]
+impl<T> Future for Exclusive<T>
+where
+    T: Future + ?Sized,
+{
     type Output = T::Output;
+
     #[inline]
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         self.get_pin_mut().poll(cx)
     }
 }
+
+#[unstable(feature = "generator_trait", issue = "43122")] // also #98407
+impl<R, G> Generator<R> for Exclusive<G>
+where
+    G: Generator<R> + ?Sized,
+{
+    type Yield = G::Yield;
+    type Return = G::Return;
+
+    #[inline]
+    fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+        G::resume(self.get_pin_mut(), arg)
+    }
+}
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index b83b198780b..2e645683713 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -271,7 +271,7 @@ For targets: `loongarch64-unknown-linux-gnu`
 - Operating System > Linux kernel version = 5.19.16
 - Binary utilities > Version of binutils = 2.40
 - C-library > glibc version = 2.36
-- C compiler > gcc version = 13.1.0
+- C compiler > gcc version = 13.2.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
 ### `mips-linux-gnu.defconfig`
@@ -407,7 +407,7 @@ For targets: `riscv64-unknown-linux-gnu`
 - Target options > Bitness = 64-bit
 - Operating System > Target OS = linux
 - Operating System > Linux kernel version = 4.20.17
-- Binary utilities > Version of binutils = 2.32
+- Binary utilities > Version of binutils = 2.36.1
 - C-library > glibc version = 2.29
 - C compiler > gcc version = 8.5.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
index 78689c429c2..55c737bd0aa 100644
--- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
@@ -3,9 +3,8 @@ FROM ubuntu:22.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-# The latest released version does not support LoongArch.
-COPY scripts/crosstool-ng-git.sh /scripts/
-RUN sh /scripts/crosstool-ng-git.sh
+COPY scripts/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh
deleted file mode 100644
index b8d39915327..00000000000
--- a/src/ci/docker/scripts/crosstool-ng-git.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-set -ex
-
-URL=https://github.com/crosstool-ng/crosstool-ng
-REV=227d99d7f3115f3a078595a580d2b307dcd23e93
-
-mkdir crosstool-ng
-cd crosstool-ng
-git init
-git fetch --depth=1 ${URL} ${REV}
-git reset --hard FETCH_HEAD
-./bootstrap
-./configure --prefix=/usr/local
-make -j$(nproc)
-make install
-cd ..
-rm -rf crosstool-ng
diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh
index a28d7bde2ac..c3ee19b8d2c 100644
--- a/src/ci/docker/scripts/crosstool-ng.sh
+++ b/src/ci/docker/scripts/crosstool-ng.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 set -ex
 
-CT_NG=1.25.0
+CT_NG=1.26.0
 
 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz"
 curl -Lf $url | tar xzf -
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index ba273489eb8..0e1bf0c6c2d 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -580,6 +580,8 @@ pub struct TargetCfg {
     pub(crate) sanitizers: Vec<Sanitizer>,
     #[serde(rename = "supports-xray", default)]
     pub(crate) xray: bool,
+    #[serde(default = "default_reloc_model")]
+    pub(crate) relocation_model: String,
 }
 
 impl TargetCfg {
@@ -592,6 +594,10 @@ fn default_os() -> String {
     "none".into()
 }
 
+fn default_reloc_model() -> String {
+    "pic".into()
+}
+
 #[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
 #[serde(rename_all = "kebab-case")]
 pub enum Endian {
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 1113721fff6..2b7a4387ceb 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -134,6 +134,11 @@ pub(super) fn handle_needs(
             condition: config.target_cfg().dynamic_linking,
             ignore_reason: "ignored on targets without dynamic linking",
         },
+        Need {
+            name: "needs-relocation-model-pic",
+            condition: config.target_cfg().relocation_model == "pic",
+            ignore_reason: "ignored on targets without PIC relocation model",
+        },
     ];
 
     let (name, comment) = match ln.split_once([':', ' ']) {
diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs
index f518266016e..b9f74340472 100644
--- a/tests/incremental/change_crate_dep_kind.rs
+++ b/tests/incremental/change_crate_dep_kind.rs
@@ -5,6 +5,7 @@
 // needs-unwind
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph -Cpanic=unwind
+// needs-unwind
 // build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(panic_unwind)]
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 249e8176283..1f049b1785a 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -1,16 +1,174 @@
 // check-pass
+// revisions: host
+// revisions: arm
+//[arm] compile-flags: --target arm-unknown-linux-gnueabi
+//[arm] needs-llvm-components: arm
+// revisions: aarch64
+//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64] needs-llvm-components: aarch64
+// revisions: s390x
+//[s390x] compile-flags: --target s390x-unknown-linux-gnu
+//[s390x] needs-llvm-components: systemz
+// revisions: mips
+//[mips] compile-flags: --target mips-unknown-linux-gnu
+//[mips] needs-llvm-components: mips
+// revisions: mips64
+//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
+//[mips64] needs-llvm-components: mips
+// revisions: sparc
+//[sparc] compile-flags: --target sparc-unknown-linux-gnu
+//[sparc] needs-llvm-components: sparc
+// revisions: sparc64
+//[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
+//[sparc64] needs-llvm-components: sparc
+// revisions: powerpc64
+//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
+//[powerpc64] needs-llvm-components: powerpc
+// revisions: riscv
+//[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu
+//[riscv] needs-llvm-components: riscv
+// revisions: loongarch64
+//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
+//[loongarch64] needs-llvm-components: loongarch
+// revisions: wasm
+//[wasm] compile-flags: --target wasm32-unknown-unknown
+//[wasm] needs-llvm-components: webassembly
+// revisions: wasi
+//[wasi] compile-flags: --target wasm32-wasi
+//[wasi] needs-llvm-components: webassembly
+// revisions: nvptx64
+//[nvptx64] compile-flags: --target nvptx64-nvidia-cuda
+//[nvptx64] needs-llvm-components: nvptx
 #![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
+#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
 #![allow(unused, improper_ctypes_definitions, internal_features)]
-use std::marker::PhantomData;
-use std::mem::ManuallyDrop;
-use std::num::NonZeroI32;
-use std::ptr::NonNull;
 
-// FIXME: a bunch of targets are broken in various ways.
+// FIXME: some targets are broken in various ways.
 // Hence there are `cfg` throughout this test to disable parts of it on those targets.
 // sparc64: https://github.com/rust-lang/rust/issues/115336
 // mips64: https://github.com/rust-lang/rust/issues/115404
 
+#[cfg(host)]
+use std::{
+    any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZeroI32, ptr::NonNull, rc::Rc,
+    sync::Arc,
+};
+
+/// To work cross-target this test must be no_core.
+/// This little prelude supplies what we need.
+#[cfg(not(host))]
+mod prelude {
+    #[lang = "sized"]
+    pub trait Sized {}
+
+    #[lang = "receiver"]
+    pub trait Receiver {}
+    impl<T: ?Sized> Receiver for &T {}
+    impl<T: ?Sized> Receiver for &mut T {}
+
+    #[lang = "copy"]
+    pub trait Copy: Sized {}
+    impl Copy for i32 {}
+    impl Copy for f32 {}
+    impl<T: ?Sized> Copy for &T {}
+    impl<T: ?Sized> Copy for *const T {}
+    impl<T: ?Sized> Copy for *mut T {}
+
+    #[lang = "clone"]
+    pub trait Clone: Sized {
+        fn clone(&self) -> Self;
+    }
+
+    #[lang = "phantom_data"]
+    pub struct PhantomData<T: ?Sized>;
+    impl<T: ?Sized> Copy for PhantomData<T> {}
+
+    #[lang = "unsafe_cell"]
+    #[repr(transparent)]
+    pub struct UnsafeCell<T: ?Sized> {
+        value: T,
+    }
+
+    pub trait Any: 'static {}
+
+    pub enum Option<T> {
+        None,
+        Some(T),
+    }
+    impl<T: Copy> Copy for Option<T> {}
+
+    pub enum Result<T, E> {
+        Ok(T),
+        Err(E),
+    }
+    impl<T: Copy, E: Copy> Copy for Result<T, E> {}
+
+    #[lang = "manually_drop"]
+    #[repr(transparent)]
+    pub struct ManuallyDrop<T: ?Sized> {
+        value: T,
+    }
+    impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
+
+    #[repr(transparent)]
+    #[rustc_layout_scalar_valid_range_start(1)]
+    #[rustc_nonnull_optimization_guaranteed]
+    pub struct NonNull<T: ?Sized> {
+        pointer: *const T,
+    }
+    impl<T: ?Sized> Copy for NonNull<T> {}
+
+    #[repr(transparent)]
+    #[rustc_layout_scalar_valid_range_start(1)]
+    #[rustc_nonnull_optimization_guaranteed]
+    pub struct NonZeroI32(i32);
+
+    // This just stands in for a non-trivial type.
+    pub struct Vec<T> {
+        ptr: NonNull<T>,
+        cap: usize,
+        len: usize,
+    }
+
+    pub struct Unique<T: ?Sized> {
+        pub pointer: NonNull<T>,
+        pub _marker: PhantomData<T>,
+    }
+
+    pub struct Global;
+
+    #[lang = "owned_box"]
+    pub struct Box<T: ?Sized, A = Global>(Unique<T>, A);
+
+    #[repr(C)]
+    struct RcBox<T: ?Sized> {
+        strong: UnsafeCell<usize>,
+        weak: UnsafeCell<usize>,
+        value: T,
+    }
+    pub struct Rc<T: ?Sized, A = Global> {
+        ptr: NonNull<RcBox<T>>,
+        phantom: PhantomData<RcBox<T>>,
+        alloc: A,
+    }
+
+    #[repr(C, align(8))]
+    struct AtomicUsize(usize);
+    #[repr(C)]
+    struct ArcInner<T: ?Sized> {
+        strong: AtomicUsize,
+        weak: AtomicUsize,
+        data: T,
+    }
+    pub struct Arc<T: ?Sized, A = Global> {
+        ptr: NonNull<ArcInner<T>>,
+        phantom: PhantomData<ArcInner<T>>,
+        alloc: A,
+    }
+}
+#[cfg(not(host))]
+use prelude::*;
+
 macro_rules! assert_abi_compatible {
     ($name:ident, $t1:ty, $t2:ty) => {
         mod $name {
@@ -26,8 +184,13 @@ macro_rules! assert_abi_compatible {
     };
 }
 
-#[derive(Copy, Clone)]
 struct Zst;
+impl Copy for Zst {}
+impl Clone for Zst {
+    fn clone(&self) -> Self {
+        Zst
+    }
+}
 
 #[repr(C)]
 struct ReprC1<T: ?Sized>(T);
@@ -85,8 +248,8 @@ test_abi_compatible!(nonzero_int, NonZeroI32, i32);
 
 // `DispatchFromDyn` relies on ABI compatibility.
 // This is interesting since these types are not `repr(transparent)`.
-test_abi_compatible!(rc, std::rc::Rc<i32>, *mut i32);
-test_abi_compatible!(arc, std::sync::Arc<i32>, *mut i32);
+test_abi_compatible!(rc, Rc<i32>, *mut i32);
+test_abi_compatible!(arc, Arc<i32>, *mut i32);
 
 // `repr(transparent)` compatibility.
 #[repr(transparent)]
@@ -160,7 +323,7 @@ mod unsized_ {
     use super::*;
     test_transparent_unsized!(str_, str);
     test_transparent_unsized!(slice, [u8]);
-    test_transparent_unsized!(dyn_trait, dyn std::any::Any);
+    test_transparent_unsized!(dyn_trait, dyn Any);
 }
 
 // RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>.
@@ -185,7 +348,7 @@ test_nonnull!(ref_unsized, &[i32]);
 test_nonnull!(mut_unsized, &mut [i32]);
 test_nonnull!(fn_, fn());
 test_nonnull!(nonnull, NonNull<i32>);
-test_nonnull!(nonnull_unsized, NonNull<dyn std::fmt::Debug>);
+test_nonnull!(nonnull_unsized, NonNull<dyn Any>);
 test_nonnull!(non_zero, NonZeroI32);
 
 fn main() {}
diff --git a/tests/ui/abi/relocation_model_pic.rs b/tests/ui/abi/relocation_model_pic.rs
index 0cfc44cd09d..cca2e8db74d 100644
--- a/tests/ui/abi/relocation_model_pic.rs
+++ b/tests/ui/abi/relocation_model_pic.rs
@@ -1,7 +1,6 @@
 // run-pass
 // compile-flags: -C relocation-model=pic
-// ignore-emscripten no pic
-// ignore-wasm
+// needs-relocation-model-pic
 
 #![feature(cfg_relocation_model)]
 
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
index 38a80f8b670..751959f55bb 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
@@ -2,6 +2,7 @@
 // run-fail
 // check-run-results
 // exec-env:RUST_BACKTRACE=1
+// needs-unwind
 // ignore-android FIXME #17520
 // ignore-wasm no panic support
 // ignore-openbsd no support for libbacktrace without filename
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
index 2b648a0cad2..664ebaa4c51 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:56:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:57:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs
index c872084f033..134e13233da 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames.rs
@@ -2,6 +2,7 @@
 // run-fail
 // check-run-results
 // exec-env:RUST_BACKTRACE=1
+// needs-unwind
 // ignore-android FIXME #17520
 // ignore-wasm no panic support
 // ignore-openbsd no support for libbacktrace without filename
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
index 5b372684096..bc252fde1f6 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:52:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:53:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/suggestions/auxiliary/extern-issue-98562.rs b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs
new file mode 100644
index 00000000000..948e40549c6
--- /dev/null
+++ b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs
@@ -0,0 +1,26 @@
+pub trait TraitE {
+    type I3;
+}
+
+pub trait TraitD {
+    type I3;
+}
+
+pub trait TraitC {
+    type I1;
+    type I2;
+}
+
+pub trait TraitB {
+    type Item;
+}
+
+pub trait TraitA<G1, G2, G3> {
+    fn baz<
+        U: TraitC<I1 = G1, I2 = G2> + TraitD<I3 = G3> + TraitE,
+        V: TraitD<I3 = G1>
+    >(_: U, _: V) -> Self
+    where
+        U: TraitB,
+        <U as TraitB>::Item: Copy;
+}
diff --git a/tests/ui/suggestions/issue-98562.rs b/tests/ui/suggestions/issue-98562.rs
new file mode 100644
index 00000000000..de04050d593
--- /dev/null
+++ b/tests/ui/suggestions/issue-98562.rs
@@ -0,0 +1,12 @@
+// aux-build:extern-issue-98562.rs
+
+extern crate extern_issue_98562;
+use extern_issue_98562::TraitA;
+
+struct X;
+impl TraitA<u8, u16, u32> for X {
+    //~^ ERROR not all trait items implemented
+}
+//~^ HELP implement the missing item: `fn baz<U: TraitC<I1 = u8, I2 = u16> + TraitD<I3 = u32>, V: TraitD<I3 = u8>>(_: U, _: V) -> Self where U: TraitE, U: TraitB, <U as TraitB>::Item: Copy { todo!() }`
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-98562.stderr b/tests/ui/suggestions/issue-98562.stderr
new file mode 100644
index 00000000000..7897fa441a2
--- /dev/null
+++ b/tests/ui/suggestions/issue-98562.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `baz`
+  --> $DIR/issue-98562.rs:7:1
+   |
+LL | impl TraitA<u8, u16, u32> for X {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `baz` in implementation
+   |
+   = help: implement the missing item: `fn baz<U: TraitC<I1 = u8, I2 = u16> + TraitD<I3 = u32>, V: TraitD<I3 = u8>>(_: U, _: V) -> Self where U: TraitE, U: TraitB, <U as TraitB>::Item: Copy { todo!() }`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr
index 77fa9562878..84cb6e98553 100644
--- a/tests/ui/suggestions/missing-assoc-fn.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn.stderr
@@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
 LL | impl FromIterator<()> for X {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
    |
-   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
+   = help: implement the missing item: `fn from_iter<T: IntoIterator<Item = ()>>(_: T) -> Self { todo!() }`
 
 error: aborting due to 3 previous errors