From 98481be353b3be34be684a11c467b72992561fde Mon Sep 17 00:00:00 2001
From: "L. E. Segovia"
Date: Wed, 3 Apr 2024 20:08:56 -0300
Subject: [PATCH 1/4] MsvcLinker: allow linking dynamically to Meson and
MinGW-style named libraries
Fixes #122455
---
compiler/rustc_codegen_ssa/src/back/linker.rs | 12 +++++-
compiler/rustc_metadata/src/lib.rs | 3 +-
compiler/rustc_metadata/src/native_libs.rs | 38 +++++++++++++++++++
3 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index cb266247e0dde..1ff0f9cbadb6c 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -7,7 +7,9 @@ use std::{env, iter, mem, str};
use cc::windows_registry;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
-use rustc_metadata::{find_native_static_library, try_find_native_static_library};
+use rustc_metadata::{
+ find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
+};
use rustc_middle::bug;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols;
@@ -878,7 +880,13 @@ impl<'a> Linker for MsvcLinker<'a> {
}
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) {
- self.link_arg(format!("{}{}", name, if verbatim { "" } else { ".lib" }));
+ // On MSVC-like targets rustc supports import libraries using alternative naming
+ // scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
+ if let Some(path) = try_find_native_dynamic_library(self.sess, name, verbatim) {
+ self.link_arg(path);
+ } else {
+ self.link_arg(format!("{}{}", name, if verbatim { "" } else { ".lib" }));
+ }
}
fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 58b352f263de6..02a9ce455b280 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -37,7 +37,8 @@ pub mod locator;
pub use creader::{load_symbol_from_dylib, DylibError};
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
pub use native_libs::{
- find_native_static_library, try_find_native_static_library, walk_native_lib_search_dirs,
+ find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
+ walk_native_lib_search_dirs,
};
pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index a6ad449cb53e8..0329a193d89dd 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -109,6 +109,44 @@ pub fn try_find_native_static_library(
.break_value()
}
+pub fn try_find_native_dynamic_library(
+ sess: &Session,
+ name: &str,
+ verbatim: bool,
+) -> Option {
+ let formats = if verbatim {
+ vec![("".into(), "".into())]
+ } else {
+ // While the official naming convention for MSVC import libraries
+ // is foo.lib...
+ let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
+ // ... Meson follows the libfoo.dll.a convention to
+ // disambiguate .a for static libraries
+ let meson = ("lib".into(), ".dll.a".into());
+ // and MinGW uses .a altogether
+ let mingw = ("lib".into(), ".a".into());
+ vec![os, meson, mingw]
+ };
+
+ walk_native_lib_search_dirs(
+ sess,
+ LinkSelfContainedComponents::empty(),
+ None,
+ |dir, is_framework| {
+ if !is_framework {
+ for (prefix, suffix) in &formats {
+ let test = dir.join(format!("{prefix}{name}{suffix}"));
+ if test.exists() {
+ return ControlFlow::Break(test);
+ }
+ }
+ }
+ ControlFlow::Continue(())
+ },
+ )
+ .break_value()
+}
+
pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
try_find_native_static_library(sess, name, verbatim)
.unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
From 11b42d2763b8ad8358455f997b87ccce5f8f16c0 Mon Sep 17 00:00:00 2001
From: Raoul Strackx
Date: Mon, 16 Sep 2024 16:54:48 +0200
Subject: [PATCH 2/4] Ignore reduce-fadd-unordered on SGX platform
---
tests/assembly/simd/reduce-fadd-unordered.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/assembly/simd/reduce-fadd-unordered.rs b/tests/assembly/simd/reduce-fadd-unordered.rs
index fa9ce6bd35e55..ade60ba184c57 100644
--- a/tests/assembly/simd/reduce-fadd-unordered.rs
+++ b/tests/assembly/simd/reduce-fadd-unordered.rs
@@ -4,6 +4,7 @@
//@[aarch64] only-aarch64
//@[x86_64] only-x86_64
//@[x86_64] compile-flags: -Ctarget-feature=+sse3
+//@ ignore-sgx Test incompatible with LVI mitigations
#![feature(portable_simd)]
#![feature(core_intrinsics)]
use std::intrinsics::simd as intrinsics;
From 1e9fa7eb79072274fbd741f09e9444249e1d4ff0 Mon Sep 17 00:00:00 2001
From: Michael Goulet
Date: Sun, 15 Sep 2024 16:41:00 -0400
Subject: [PATCH 3/4] Don't ICE when RPITIT captures more method args than
trait definition
---
.../src/check/compare_impl_item.rs | 15 ++++---
compiler/rustc_middle/src/ty/generics.rs | 8 ++--
tests/crashes/129850.rs | 9 ----
.../rpitit-captures-more-method-lifetimes.rs | 16 +++++++
...itit-captures-more-method-lifetimes.stderr | 42 +++++++++++++++++++
5 files changed, 73 insertions(+), 17 deletions(-)
delete mode 100644 tests/crashes/129850.rs
create mode 100644 tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs
create mode 100644 tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 388e02b36e02c..cc7a0dff34e41 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
num_trait_args,
num_impl_args,
def_id,
- impl_def_id: impl_m.container_id(tcx),
+ impl_m_def_id: impl_m.def_id,
ty,
return_span,
}) {
@@ -844,12 +844,18 @@ where
struct RemapHiddenTyRegions<'tcx> {
tcx: TyCtxt<'tcx>,
+ /// Map from early/late params of the impl to identity regions of the RPITIT (GAT)
+ /// in the trait.
map: FxIndexMap, ty::Region<'tcx>>,
num_trait_args: usize,
num_impl_args: usize,
+ /// Def id of the RPITIT (GAT) in the *trait*.
def_id: DefId,
- impl_def_id: DefId,
+ /// Def id of the impl method which owns the opaque hidden type we're remapping.
+ impl_m_def_id: DefId,
+ /// The hidden type we're remapping. Useful for diagnostics.
ty: Ty<'tcx>,
+ /// Span of the return type. Useful for diagnostics.
return_span: Span,
}
@@ -885,8 +891,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> {
ty::ReLateParam(_) => {}
// Remap early-bound regions as long as they don't come from the `impl` itself,
// in which case we don't really need to renumber them.
- ty::ReEarlyParam(ebr)
- if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
+ ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
_ => return Ok(region),
}
@@ -899,7 +904,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> {
);
}
} else {
- let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
+ let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
Some(def_id) => {
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
self.tcx.def_span(opaque_ty.def_id)
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index bbc696e0f0814..5f9a89c3a5bda 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -255,7 +255,9 @@ impl<'tcx> Generics {
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Lifetime => param,
- _ => bug!("expected lifetime parameter, but found another generic parameter"),
+ _ => {
+ bug!("expected lifetime parameter, but found another generic parameter: {param:#?}")
+ }
}
}
@@ -264,7 +266,7 @@ impl<'tcx> Generics {
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Type { .. } => param,
- _ => bug!("expected type parameter, but found another generic parameter"),
+ _ => bug!("expected type parameter, but found another generic parameter: {param:#?}"),
}
}
@@ -273,7 +275,7 @@ impl<'tcx> Generics {
let param = self.param_at(param.index as usize, tcx);
match param.kind {
GenericParamDefKind::Const { .. } => param,
- _ => bug!("expected const parameter, but found another generic parameter"),
+ _ => bug!("expected const parameter, but found another generic parameter: {param:#?}"),
}
}
diff --git a/tests/crashes/129850.rs b/tests/crashes/129850.rs
deleted file mode 100644
index 9c04805587a63..0000000000000
--- a/tests/crashes/129850.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: rust-lang/rust#129850
-
-pub trait Foo2 {
- fn bar<'a: 'a>(&'a mut self) -> impl Sized + use<'static>;
-}
-
-impl Foo2 for () {
- fn bar<'a: 'a>(&'a mut self) -> impl Sized + 'a {}
-}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs
new file mode 100644
index 0000000000000..71a91fe319e8d
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs
@@ -0,0 +1,16 @@
+// Make sure we don't ICE when an RPITIT captures more method args than the
+// trait definition, which is not allowed. Due to the default lifetime capture
+// rules of RPITITs, this is only doable if we use precise capturing.
+
+pub trait Foo {
+ fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use;
+ //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+}
+
+impl Foo for () {
+ fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+ //~^ ERROR return type captures more lifetimes than trait definition
+ //~| WARN impl trait in impl method signature does not match trait method signature
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr
new file mode 100644
index 0000000000000..339e2e6335e2d
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr
@@ -0,0 +1,42 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+ --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53
+ |
+LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use;
+ | ^^^^^^^^^
+ |
+ = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: return type captures more lifetimes than trait definition
+ --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
+ |
+LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+ | --- ^^^^^^^^^^^^^^^^
+ | |
+ | this lifetime was captured
+ |
+note: hidden type must only reference lifetimes captured by this impl trait
+ --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
+ |
+LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ = note: hidden type inferred to be `impl Sized + 'im`
+
+warning: impl trait in impl method signature does not match trait method signature
+ --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
+ |
+LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use;
+ | ---------------------- return type from trait method defined here
+...
+LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+ = note: we are soliciting feedback, see issue #121718 for more information
+ = note: `#[warn(refining_impl_trait_reachable)]` on by default
+help: replace the return type so that it matches the trait
+ |
+LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized {}
+ | ~~~~~~~~~~
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
From 57a7e514a4fee2d76bae4b6f2ee72a760518f892 Mon Sep 17 00:00:00 2001
From: Michael Goulet
Date: Sun, 15 Sep 2024 16:07:08 -0400
Subject: [PATCH 4/4] Don't ICE when generating Fn shim for async closure with
borrowck error
---
compiler/rustc_mir_transform/src/shim.rs | 17 +++++++++----
.../closure-shim-borrowck-error.rs} | 2 +-
.../closure-shim-borrowck-error.stderr | 24 +++++++++++++++++++
3 files changed, 37 insertions(+), 6 deletions(-)
rename tests/{crashes/129262.rs => ui/async-await/async-closures/closure-shim-borrowck-error.rs} (87%)
create mode 100644 tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index f1bd803d83530..47d04d8a00bf0 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -1070,19 +1070,26 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
let locals = local_decls_for_sig(&sig, span);
let mut fields = vec![];
+
+ // Move all of the closure args.
for idx in 1..sig.inputs().len() {
fields.push(Operand::Move(Local::from_usize(idx + 1).into()));
}
+
for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
if receiver_by_ref {
// The only situation where it's possible is when we capture immuatable references,
// since those don't need to be reborrowed with the closure's env lifetime. Since
// references are always `Copy`, just emit a copy.
- assert_matches!(
- ty.kind(),
- ty::Ref(_, _, hir::Mutability::Not),
- "field should be captured by immutable ref if we have an `Fn` instance"
- );
+ if !matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) {
+ // This copy is only sound if it's a `&T`. This may be
+ // reachable e.g. when eagerly computing the `Fn` instance
+ // of an async closure that doesn't borrowck.
+ tcx.dcx().delayed_bug(format!(
+ "field should be captured by immutable ref if we have \
+ an `Fn` instance, but it was: {ty}"
+ ));
+ }
fields.push(Operand::Copy(tcx.mk_place_field(
self_local,
FieldIdx::from_usize(idx),
diff --git a/tests/crashes/129262.rs b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
similarity index 87%
rename from tests/crashes/129262.rs
rename to tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
index c430af35988d8..4cbbefb0f5298 100644
--- a/tests/crashes/129262.rs
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
@@ -1,4 +1,3 @@
-//@ known-bug: rust-lang/rust#129262
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
#![feature(async_closure)]
@@ -11,6 +10,7 @@ fn needs_fn_mut(mut x: impl FnMut() -> T) {
fn hello(x: Ty) {
needs_fn_mut(async || {
+ //~^ ERROR cannot move out of `x`
x.hello();
});
}
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
new file mode 100644
index 0000000000000..bab26c1948217
--- /dev/null
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
@@ -0,0 +1,24 @@
+error[E0507]: cannot move out of `x` which is behind a mutable reference
+ --> $DIR/closure-shim-borrowck-error.rs:12:18
+ |
+LL | needs_fn_mut(async || {
+ | ^^^^^^^^ `x` is moved here
+LL |
+LL | x.hello();
+ | -
+ | |
+ | variable moved due to use in coroutine
+ | move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
+ |
+note: if `Ty` implemented `Clone`, you could clone the value
+ --> $DIR/closure-shim-borrowck-error.rs:18:1
+ |
+LL | x.hello();
+ | - you could clone this value
+...
+LL | struct Ty;
+ | ^^^^^^^^^ consider implementing `Clone` for this type
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0507`.