diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 7f5f9f0386809..bda2225570509 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; @@ -876,7 +878,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_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_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))) 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/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/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; 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/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`. 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 +