Skip to content

Commit 9e350cf

Browse files
committed
Auto merge of rust-lang#120731 - matthiaskrgr:rollup-wsmujwc, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#119162 (Add unstable `-Z direct-access-external-data` cmdline flag for `rustc`) - rust-lang#119592 (resolve: Unload speculatively resolved crates before freezing cstore) - rust-lang#120103 (Make it so that async-fn-in-trait is compatible with a concrete future in implementation) - rust-lang#120455 ( Add FileCheck annotations to MIR-opt SROA tests) - rust-lang#120470 (Mark "unused binding" suggestion as maybe incorrect) - rust-lang#120619 (Assert that params with the same *index* have the same *name*) - rust-lang#120633 (pattern_analysis: gather up place-relevant info) - rust-lang#120726 (Don't use bashism in checktools.sh) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d4f6f9e + 8924c26 commit 9e350cf

File tree

37 files changed

+520
-179
lines changed

37 files changed

+520
-179
lines changed

compiler/rustc_codegen_llvm/src/mono_item.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -123,25 +123,30 @@ impl CodegenCx<'_, '_> {
123123
return false;
124124
}
125125

126+
// Match clang by only supporting COFF and ELF for now.
127+
if self.tcx.sess.target.is_like_osx {
128+
return false;
129+
}
130+
131+
// With pie relocation model calls of functions defined in the translation
132+
// unit can use copy relocations.
133+
if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration {
134+
return true;
135+
}
136+
126137
// Thread-local variables generally don't support copy relocations.
127138
let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
128139
.is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
129140
if is_thread_local_var {
130141
return false;
131142
}
132143

133-
// Match clang by only supporting COFF and ELF for now.
134-
if self.tcx.sess.target.is_like_osx {
135-
return false;
144+
// Respect the direct-access-external-data to override default behavior if present.
145+
if let Some(direct) = self.tcx.sess.direct_access_external_data() {
146+
return direct;
136147
}
137148

138149
// Static relocation model should force copy relocations everywhere.
139-
if self.tcx.sess.relocation_model() == RelocModel::Static {
140-
return true;
141-
}
142-
143-
// With pie relocation model calls of functions defined in the translation
144-
// unit can use copy relocations.
145-
self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration
150+
self.tcx.sess.relocation_model() == RelocModel::Static
146151
}
147152
}

compiler/rustc_hir_analysis/messages.ftl

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the as
3333
3434
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
3535
36-
hir_analysis_async_trait_impl_should_be_async =
37-
method `{$method_name}` should be async because the method from the trait is async
38-
.trait_item_label = required because the trait method is async
39-
4036
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
4137
.label = deref recursion limit reached
4238
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
@@ -210,6 +206,9 @@ hir_analysis_manual_implementation =
210206
.label = manual implementations of `{$trait_name}` are experimental
211207
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
212208
209+
hir_analysis_method_should_return_future = method should be `async` or return a future, but it is synchronous
210+
.note = this method is `async` so it expects a future to be returned
211+
213212
hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}`
214213
.label = missing one of `{$missing_items_msg}` in implementation
215214
.note = required because of this annotation

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+53-35
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::potentially_plural_count;
2-
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
2+
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
33
use hir::def_id::{DefId, DefIdMap, LocalDefId};
44
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
55
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -10,7 +10,7 @@ use rustc_hir::{GenericParamKind, ImplItemKind};
1010
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1111
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1212
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
13-
use rustc_infer::traits::util;
13+
use rustc_infer::traits::{util, FulfillmentError};
1414
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1515
use rustc_middle::ty::fold::BottomUpFolder;
1616
use rustc_middle::ty::util::ExplicitSelf;
@@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>(
7474
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
7575
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
7676
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
77-
compare_asyncness(tcx, impl_m, trait_m, delay)?;
7877
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
7978
Ok(())
8079
}
@@ -414,36 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
414413
}
415414
}
416415

417-
fn compare_asyncness<'tcx>(
418-
tcx: TyCtxt<'tcx>,
419-
impl_m: ty::AssocItem,
420-
trait_m: ty::AssocItem,
421-
delay: bool,
422-
) -> Result<(), ErrorGuaranteed> {
423-
if tcx.asyncness(trait_m.def_id).is_async() {
424-
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
425-
ty::Alias(ty::Opaque, ..) => {
426-
// allow both `async fn foo()` and `fn foo() -> impl Future`
427-
}
428-
ty::Error(_) => {
429-
// We don't know if it's ok, but at least it's already an error.
430-
}
431-
_ => {
432-
return Err(tcx
433-
.dcx()
434-
.create_err(crate::errors::AsyncTraitImplShouldBeAsync {
435-
span: tcx.def_span(impl_m.def_id),
436-
method_name: trait_m.name,
437-
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
438-
})
439-
.emit_unless(delay));
440-
}
441-
};
442-
}
443-
444-
Ok(())
445-
}
446-
447416
/// Given a method def-id in an impl, compare the method signature of the impl
448417
/// against the trait that it's implementing. In doing so, infer the hidden types
449418
/// that this method's signature provides to satisfy each return-position `impl Trait`
@@ -695,8 +664,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
695664
// RPITs.
696665
let errors = ocx.select_all_or_error();
697666
if !errors.is_empty() {
698-
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
699-
return Err(reported);
667+
if let Err(guar) = try_report_async_mismatch(tcx, infcx, &errors, trait_m, impl_m, impl_sig)
668+
{
669+
return Err(guar);
670+
}
671+
672+
let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
673+
return Err(guar);
700674
}
701675

702676
// Finally, resolve all regions. This catches wily misuses of
@@ -2248,3 +2222,47 @@ fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
22482222
ty::AssocKind::Type => "type",
22492223
}
22502224
}
2225+
2226+
/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
2227+
/// and extract a better error if so.
2228+
fn try_report_async_mismatch<'tcx>(
2229+
tcx: TyCtxt<'tcx>,
2230+
infcx: &InferCtxt<'tcx>,
2231+
errors: &[FulfillmentError<'tcx>],
2232+
trait_m: ty::AssocItem,
2233+
impl_m: ty::AssocItem,
2234+
impl_sig: ty::FnSig<'tcx>,
2235+
) -> Result<(), ErrorGuaranteed> {
2236+
if !tcx.asyncness(trait_m.def_id).is_async() {
2237+
return Ok(());
2238+
}
2239+
2240+
let ty::Alias(ty::Projection, ty::AliasTy { def_id: async_future_def_id, .. }) =
2241+
*tcx.fn_sig(trait_m.def_id).skip_binder().skip_binder().output().kind()
2242+
else {
2243+
bug!("expected `async fn` to return an RPITIT");
2244+
};
2245+
2246+
for error in errors {
2247+
if let traits::BindingObligation(def_id, _) = *error.root_obligation.cause.code()
2248+
&& def_id == async_future_def_id
2249+
&& let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred()
2250+
&& let Some(proj) = proj.no_bound_vars()
2251+
&& infcx.can_eq(
2252+
error.root_obligation.param_env,
2253+
proj.term.ty().unwrap(),
2254+
impl_sig.output(),
2255+
)
2256+
{
2257+
// FIXME: We should suggest making the fn `async`, but extracting
2258+
// the right span is a bit difficult.
2259+
return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture {
2260+
span: tcx.def_span(impl_m.def_id),
2261+
method_name: trait_m.name,
2262+
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
2263+
}));
2264+
}
2265+
}
2266+
2267+
Ok(())
2268+
}

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
1212
use rustc_hir as hir;
1313
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1414
use rustc_middle::ty::{self, Ty, TyCtxt};
15-
use rustc_span::symbol::{kw, sym, Symbol};
15+
use rustc_span::symbol::{kw, sym};
1616
use rustc_target::spec::abi::Abi;
1717

1818
fn equate_intrinsic_type<'tcx>(
@@ -132,7 +132,17 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
132132
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
133133
/// and in `library/core/src/intrinsics.rs`.
134134
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
135-
let param = |n| Ty::new_param(tcx, n, Symbol::intern(&format!("P{n}")));
135+
let generics = tcx.generics_of(it.owner_id);
136+
let param = |n| {
137+
if let Some(&ty::GenericParamDef {
138+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
139+
}) = generics.opt_param_at(n as usize, tcx)
140+
{
141+
Ty::new_param(tcx, n, name)
142+
} else {
143+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
144+
}
145+
};
136146
let intrinsic_id = it.owner_id.to_def_id();
137147
let intrinsic_name = tcx.item_name(intrinsic_id);
138148
let name_str = intrinsic_name.as_str();
@@ -475,9 +485,16 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
475485

476486
/// Type-check `extern "platform-intrinsic" { ... }` functions.
477487
pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
488+
let generics = tcx.generics_of(it.owner_id);
478489
let param = |n| {
479-
let name = Symbol::intern(&format!("P{n}"));
480-
Ty::new_param(tcx, n, name)
490+
if let Some(&ty::GenericParamDef {
491+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
492+
}) = generics.opt_param_at(n as usize, tcx)
493+
{
494+
Ty::new_param(tcx, n, name)
495+
} else {
496+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
497+
}
481498
};
482499

483500
let name = it.ident.name;

compiler/rustc_hir_analysis/src/errors.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,6 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
166166
pub ident: Ident,
167167
}
168168

169-
#[derive(Diagnostic)]
170-
#[diag(hir_analysis_async_trait_impl_should_be_async)]
171-
pub struct AsyncTraitImplShouldBeAsync {
172-
#[primary_span]
173-
// #[label]
174-
pub span: Span,
175-
#[label(hir_analysis_trait_item_label)]
176-
pub trait_item_span: Option<Span>,
177-
pub method_name: Symbol,
178-
}
179-
180169
#[derive(Diagnostic)]
181170
#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
182171
pub struct DropImplOnWrongItem {
@@ -1512,6 +1501,16 @@ pub struct NotSupportedDelegation<'a> {
15121501
pub callee_span: Span,
15131502
}
15141503

1504+
#[derive(Diagnostic)]
1505+
#[diag(hir_analysis_method_should_return_future)]
1506+
pub struct MethodShouldReturnFuture {
1507+
#[primary_span]
1508+
pub span: Span,
1509+
pub method_name: Symbol,
1510+
#[note]
1511+
pub trait_item_span: Option<Span>,
1512+
}
1513+
15151514
#[derive(Diagnostic)]
15161515
#[diag(hir_analysis_unused_generic_parameter)]
15171516
pub(crate) struct UnusedGenericParameter {

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ fn test_unstable_options_tracking_hash() {
749749
tracked!(debug_macros, true);
750750
tracked!(default_hidden_visibility, Some(true));
751751
tracked!(dep_info_omit_d_target, true);
752+
tracked!(direct_access_external_data, Some(true));
752753
tracked!(dual_proc_macros, true);
753754
tracked!(dwarf_version, Some(5));
754755
tracked!(emit_thin_lto, false);

compiler/rustc_metadata/src/creader.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
534534
) -> Option<CrateNum> {
535535
self.used_extern_options.insert(name);
536536
match self.maybe_resolve_crate(name, dep_kind, None) {
537-
Ok(cnum) => Some(cnum),
537+
Ok(cnum) => {
538+
self.cstore.set_used_recursively(cnum);
539+
Some(cnum)
540+
}
538541
Err(err) => {
539542
let missing_core =
540543
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
@@ -1067,6 +1070,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10671070
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
10681071
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
10691072
}
1073+
1074+
pub fn unload_unused_crates(&mut self) {
1075+
for opt_cdata in &mut self.cstore.metas {
1076+
if let Some(cdata) = opt_cdata
1077+
&& !cdata.used()
1078+
{
1079+
*opt_cdata = None;
1080+
}
1081+
}
1082+
}
10701083
}
10711084

10721085
fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {

compiler/rustc_metadata/src/rmeta/decoder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ pub(crate) struct CrateMetadata {
106106
private_dep: bool,
107107
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
108108
host_hash: Option<Svh>,
109+
/// The crate was used non-speculatively.
110+
used: bool,
109111

110112
/// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
111113
/// and `ExpnId`).
@@ -1811,6 +1813,7 @@ impl CrateMetadata {
18111813
source: Lrc::new(source),
18121814
private_dep,
18131815
host_hash,
1816+
used: false,
18141817
extern_crate: None,
18151818
hygiene_context: Default::default(),
18161819
def_key_cache: Default::default(),
@@ -1860,6 +1863,10 @@ impl CrateMetadata {
18601863
self.private_dep &= private_dep;
18611864
}
18621865

1866+
pub(crate) fn used(&self) -> bool {
1867+
self.used
1868+
}
1869+
18631870
pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
18641871
self.root.required_panic_strategy
18651872
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_span::symbol::{kw, Symbol};
2626
use rustc_span::Span;
2727

2828
use std::any::Any;
29+
use std::mem;
2930

3031
use super::{Decodable, DecodeContext, DecodeIterator};
3132

@@ -576,12 +577,24 @@ impl CStore {
576577
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
577578
}
578579

580+
pub fn set_used_recursively(&mut self, cnum: CrateNum) {
581+
let cmeta = self.get_crate_data_mut(cnum);
582+
if !cmeta.used {
583+
cmeta.used = true;
584+
let dependencies = mem::take(&mut cmeta.dependencies);
585+
for &dep_cnum in &dependencies {
586+
self.set_used_recursively(dep_cnum);
587+
}
588+
self.get_crate_data_mut(cnum).dependencies = dependencies;
589+
}
590+
}
591+
579592
pub(crate) fn update_extern_crate(&mut self, cnum: CrateNum, extern_crate: ExternCrate) {
580593
let cmeta = self.get_crate_data_mut(cnum);
581594
if cmeta.update_extern_crate(extern_crate) {
582595
// Propagate the extern crate info to dependencies if it was updated.
583596
let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
584-
let dependencies = std::mem::take(&mut cmeta.dependencies);
597+
let dependencies = mem::take(&mut cmeta.dependencies);
585598
for &dep_cnum in &dependencies {
586599
self.update_extern_crate(dep_cnum, extern_crate);
587600
}

compiler/rustc_middle/src/ty/relate.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
435435
Ok(a)
436436
}
437437

438-
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => Ok(a),
438+
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => {
439+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
440+
Ok(a)
441+
}
439442

440443
(ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
441444

@@ -593,7 +596,10 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
593596
(ty::ConstKind::Error(_), _) => return Ok(a),
594597
(_, ty::ConstKind::Error(_)) => return Ok(b),
595598

596-
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) => a_p.index == b_p.index,
599+
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
600+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
601+
true
602+
}
597603
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
598604
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val,
599605

0 commit comments

Comments
 (0)