Auto merge of #130439 - matthiaskrgr:rollup-1lkzo74, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #123436 (linker: Allow MSVC to use import libraries following the Meson/MinGW convention) - #130410 (Don't ICE when generating `Fn` shim for async closure with borrowck error) - #130412 (Don't ICE when RPITIT captures more method args than trait definition) - #130436 (Ignore reduce-fadd-unordered on SGX platform) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fd2c811d25
12 changed files with 161 additions and 26 deletions
|
@ -7,7 +7,9 @@ use std::{env, iter, mem, str};
|
||||||
|
|
||||||
use cc::windows_registry;
|
use cc::windows_registry;
|
||||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
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::bug;
|
||||||
use rustc_middle::middle::dependency_format::Linkage;
|
use rustc_middle::middle::dependency_format::Linkage;
|
||||||
use rustc_middle::middle::exported_symbols;
|
use rustc_middle::middle::exported_symbols;
|
||||||
|
@ -876,7 +878,13 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) {
|
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) {
|
fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) {
|
||||||
|
|
|
@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
num_trait_args,
|
num_trait_args,
|
||||||
num_impl_args,
|
num_impl_args,
|
||||||
def_id,
|
def_id,
|
||||||
impl_def_id: impl_m.container_id(tcx),
|
impl_m_def_id: impl_m.def_id,
|
||||||
ty,
|
ty,
|
||||||
return_span,
|
return_span,
|
||||||
}) {
|
}) {
|
||||||
|
@ -844,12 +844,18 @@ where
|
||||||
|
|
||||||
struct RemapHiddenTyRegions<'tcx> {
|
struct RemapHiddenTyRegions<'tcx> {
|
||||||
tcx: TyCtxt<'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>, ty::Region<'tcx>>,
|
map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
|
||||||
num_trait_args: usize,
|
num_trait_args: usize,
|
||||||
num_impl_args: usize,
|
num_impl_args: usize,
|
||||||
|
/// Def id of the RPITIT (GAT) in the *trait*.
|
||||||
def_id: DefId,
|
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>,
|
ty: Ty<'tcx>,
|
||||||
|
/// Span of the return type. Useful for diagnostics.
|
||||||
return_span: Span,
|
return_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,8 +891,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||||
ty::ReLateParam(_) => {}
|
ty::ReLateParam(_) => {}
|
||||||
// Remap early-bound regions as long as they don't come from the `impl` itself,
|
// 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.
|
// in which case we don't really need to renumber them.
|
||||||
ty::ReEarlyParam(ebr)
|
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
|
||||||
if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
|
|
||||||
_ => return Ok(region),
|
_ => return Ok(region),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,7 +904,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} 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) => {
|
Some(def_id) => {
|
||||||
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
||||||
self.tcx.def_span(opaque_ty.def_id)
|
self.tcx.def_span(opaque_ty.def_id)
|
||||||
|
|
|
@ -37,7 +37,8 @@ pub mod locator;
|
||||||
pub use creader::{load_symbol_from_dylib, DylibError};
|
pub use creader::{load_symbol_from_dylib, DylibError};
|
||||||
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
|
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
|
||||||
pub use native_libs::{
|
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};
|
pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,44 @@ pub fn try_find_native_static_library(
|
||||||
.break_value()
|
.break_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_find_native_dynamic_library(
|
||||||
|
sess: &Session,
|
||||||
|
name: &str,
|
||||||
|
verbatim: bool,
|
||||||
|
) -> Option<PathBuf> {
|
||||||
|
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 {
|
pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
|
||||||
try_find_native_static_library(sess, name, verbatim)
|
try_find_native_static_library(sess, name, verbatim)
|
||||||
.unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
|
.unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
|
||||||
|
|
|
@ -255,7 +255,9 @@ impl<'tcx> Generics {
|
||||||
let param = self.param_at(param.index as usize, tcx);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => param,
|
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);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Type { .. } => param,
|
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);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Const { .. } => param,
|
GenericParamDefKind::Const { .. } => param,
|
||||||
_ => bug!("expected const parameter, but found another generic parameter"),
|
_ => bug!("expected const parameter, but found another generic parameter: {param:#?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1070,19 +1070,26 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
|
||||||
let locals = local_decls_for_sig(&sig, span);
|
let locals = local_decls_for_sig(&sig, span);
|
||||||
|
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
|
|
||||||
|
// Move all of the closure args.
|
||||||
for idx in 1..sig.inputs().len() {
|
for idx in 1..sig.inputs().len() {
|
||||||
fields.push(Operand::Move(Local::from_usize(idx + 1).into()));
|
fields.push(Operand::Move(Local::from_usize(idx + 1).into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
|
for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
|
||||||
if receiver_by_ref {
|
if receiver_by_ref {
|
||||||
// The only situation where it's possible is when we capture immuatable references,
|
// 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
|
// since those don't need to be reborrowed with the closure's env lifetime. Since
|
||||||
// references are always `Copy`, just emit a copy.
|
// references are always `Copy`, just emit a copy.
|
||||||
assert_matches!(
|
if !matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) {
|
||||||
ty.kind(),
|
// This copy is only sound if it's a `&T`. This may be
|
||||||
ty::Ref(_, _, hir::Mutability::Not),
|
// reachable e.g. when eagerly computing the `Fn` instance
|
||||||
"field should be captured by immutable ref if we have an `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(
|
fields.push(Operand::Copy(tcx.mk_place_field(
|
||||||
self_local,
|
self_local,
|
||||||
FieldIdx::from_usize(idx),
|
FieldIdx::from_usize(idx),
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//@[aarch64] only-aarch64
|
//@[aarch64] only-aarch64
|
||||||
//@[x86_64] only-x86_64
|
//@[x86_64] only-x86_64
|
||||||
//@[x86_64] compile-flags: -Ctarget-feature=+sse3
|
//@[x86_64] compile-flags: -Ctarget-feature=+sse3
|
||||||
|
//@ ignore-sgx Test incompatible with LVI mitigations
|
||||||
#![feature(portable_simd)]
|
#![feature(portable_simd)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
use std::intrinsics::simd as intrinsics;
|
use std::intrinsics::simd as intrinsics;
|
||||||
|
|
|
@ -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 {}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
//@ known-bug: rust-lang/rust#129262
|
|
||||||
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
|
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
@ -11,6 +10,7 @@ fn needs_fn_mut<T>(mut x: impl FnMut() -> T) {
|
||||||
|
|
||||||
fn hello(x: Ty) {
|
fn hello(x: Ty) {
|
||||||
needs_fn_mut(async || {
|
needs_fn_mut(async || {
|
||||||
|
//~^ ERROR cannot move out of `x`
|
||||||
x.hello();
|
x.hello();
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -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`.
|
|
@ -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<Self>;
|
||||||
|
//~^ 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() {}
|
|
@ -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<Self>;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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<Self>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= 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<Self>;
|
||||||
|
| ---------------------- 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 <https://github.com/rust-lang/rust/issues/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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue