Skip to content

Commit 801bc19

Browse files
committed
Auto merge of #153783 - JonathanBrouwer:rollup-xAG0lwn, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - #153705 (Always generate generics in delegation that match trait in trait impl scenario) - #153751 (Detect existing turbofish on method calls to suppress useless suggestion) - #153780 (Remove `MTLock`) - #151572 (Fix Hexagon ABI calling convention for small aggregates) - #153725 (Fix that `./x test --no-doc` actually keeps the same behaviour for backwards compatability)
2 parents d097a0c + 8088898 commit 801bc19

File tree

16 files changed

+467
-211
lines changed

16 files changed

+467
-211
lines changed

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
725725
result: &mut GenericsGenerationResult<'hir>,
726726
add_lifetimes: bool,
727727
) -> hir::PathSegment<'hir> {
728+
let details = result.generics.args_propagation_details();
729+
728730
// The first condition is needed when there is SelfAndUserSpecified case,
729731
// we don't want to propagate generics params in this situation.
730-
let segment = if !result.generics.is_user_specified()
732+
let segment = if details.should_propagate
731733
&& let Some(args) = result
732734
.generics
733735
.into_hir_generics(self, item_id, span)
@@ -738,7 +740,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
738740
segment.clone()
739741
};
740742

741-
if result.generics.is_user_specified() {
743+
if details.use_args_in_sig_inheritance {
742744
result.args_segment_id = Some(segment.hir_id);
743745
}
744746

compiler/rustc_ast_lowering/src/delegation/generics.rs

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ pub(super) enum DelegationGenerics<T> {
2020
/// In free-to-trait reuse, when user specified args for trait `reuse Trait::<i32>::foo;`
2121
/// in this case we need to both generate `Self` and process user args.
2222
SelfAndUserSpecified(Option<T>),
23+
/// In delegations from trait impl to other entities like free functions or trait functions,
24+
/// we want to generate a function whose generics matches generics of signature function
25+
/// in trait.
26+
TraitImpl(Option<T>, bool /* Has user-specified args */),
2327
}
2428

2529
/// Used for storing either AST generics or their lowered HIR version. Firstly we obtain
@@ -48,12 +52,29 @@ pub(super) struct GenericsGenerationResults<'hir> {
4852
pub(super) child: GenericsGenerationResult<'hir>,
4953
}
5054

55+
pub(super) struct GenericArgsPropagationDetails {
56+
pub(super) should_propagate: bool,
57+
pub(super) use_args_in_sig_inheritance: bool,
58+
}
59+
5160
impl<T> DelegationGenerics<T> {
52-
fn is_user_specified(&self) -> bool {
53-
matches!(
54-
self,
55-
DelegationGenerics::UserSpecified | DelegationGenerics::SelfAndUserSpecified { .. }
56-
)
61+
fn args_propagation_details(&self) -> GenericArgsPropagationDetails {
62+
match self {
63+
DelegationGenerics::UserSpecified | DelegationGenerics::SelfAndUserSpecified { .. } => {
64+
GenericArgsPropagationDetails {
65+
should_propagate: false,
66+
use_args_in_sig_inheritance: true,
67+
}
68+
}
69+
DelegationGenerics::TraitImpl(_, user_specified) => GenericArgsPropagationDetails {
70+
should_propagate: !*user_specified,
71+
use_args_in_sig_inheritance: false,
72+
},
73+
DelegationGenerics::Default(_) => GenericArgsPropagationDetails {
74+
should_propagate: true,
75+
use_args_in_sig_inheritance: false,
76+
},
77+
}
5778
}
5879
}
5980

@@ -77,6 +98,12 @@ impl<'hir> HirOrAstGenerics<'hir> {
7798
DelegationGenerics::SelfAndUserSpecified(generics) => {
7899
DelegationGenerics::SelfAndUserSpecified(generics.as_mut().map(process_params))
79100
}
101+
DelegationGenerics::TraitImpl(generics, user_specified) => {
102+
DelegationGenerics::TraitImpl(
103+
generics.as_mut().map(process_params),
104+
*user_specified,
105+
)
106+
}
80107
};
81108

82109
*self = HirOrAstGenerics::Hir(hir_generics);
@@ -91,7 +118,8 @@ impl<'hir> HirOrAstGenerics<'hir> {
91118
HirOrAstGenerics::Hir(hir_generics) => match hir_generics {
92119
DelegationGenerics::UserSpecified => hir::Generics::empty(),
93120
DelegationGenerics::Default(generics)
94-
| DelegationGenerics::SelfAndUserSpecified(generics) => {
121+
| DelegationGenerics::SelfAndUserSpecified(generics)
122+
| DelegationGenerics::TraitImpl(generics, _) => {
95123
generics.unwrap_or(hir::Generics::empty())
96124
}
97125
},
@@ -111,17 +139,18 @@ impl<'hir> HirOrAstGenerics<'hir> {
111139
HirOrAstGenerics::Hir(hir_generics) => match hir_generics {
112140
DelegationGenerics::UserSpecified => None,
113141
DelegationGenerics::Default(generics)
114-
| DelegationGenerics::SelfAndUserSpecified(generics) => generics.map(|generics| {
142+
| DelegationGenerics::SelfAndUserSpecified(generics)
143+
| DelegationGenerics::TraitImpl(generics, _) => generics.map(|generics| {
115144
ctx.create_generics_args_from_params(generics.params, add_lifetimes, span)
116145
}),
117146
},
118147
}
119148
}
120149

121-
pub(super) fn is_user_specified(&self) -> bool {
150+
pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails {
122151
match self {
123-
HirOrAstGenerics::Ast(ast_generics) => ast_generics.is_user_specified(),
124-
HirOrAstGenerics::Hir(hir_generics) => hir_generics.is_user_specified(),
152+
HirOrAstGenerics::Ast(ast_generics) => ast_generics.args_propagation_details(),
153+
HirOrAstGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(),
125154
}
126155
}
127156
}
@@ -215,10 +244,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
215244
item_id: NodeId,
216245
span: Span,
217246
) -> GenericsGenerationResults<'hir> {
218-
let delegation_in_free_ctx = !matches!(
219-
self.tcx.def_kind(self.tcx.local_parent(self.local_def_id(item_id))),
220-
DefKind::Trait | DefKind::Impl { .. }
221-
);
247+
let delegation_parent_kind =
248+
self.tcx.def_kind(self.tcx.local_parent(self.local_def_id(item_id)));
249+
250+
let segments = &delegation.path.segments;
251+
let len = segments.len();
252+
let child_user_specified = segments[len - 1].args.is_some();
253+
254+
// If we are in trait impl always generate function whose generics matches
255+
// those that are defined in trait.
256+
if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) {
257+
// Considering parent generics, during signature inheritance
258+
// we will take those args that are in trait impl header trait ref.
259+
let parent = GenericsGenerationResult::new(DelegationGenerics::Default(None));
260+
261+
let generics = self.get_fn_like_generics(root_fn_id, span);
262+
let child = DelegationGenerics::TraitImpl(generics, child_user_specified);
263+
let child = GenericsGenerationResult::new(child);
264+
265+
return GenericsGenerationResults { parent, child };
266+
}
267+
268+
let delegation_in_free_ctx =
269+
!matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
222270

223271
let root_function_in_trait =
224272
matches!(self.tcx.def_kind(self.tcx.parent(root_fn_id)), DefKind::Trait);
@@ -234,9 +282,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
234282
)
235283
};
236284

237-
let segments = &delegation.path.segments;
238-
let len = segments.len();
239-
240285
let can_add_generics_to_parent = len >= 2
241286
&& self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| {
242287
matches!(self.tcx.def_kind(def_id), DefKind::Trait | DefKind::TraitAlias)
@@ -256,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
256301
DelegationGenerics::Default(None)
257302
};
258303

259-
let child_generics = if segments[len - 1].args.is_some() {
304+
let child_generics = if child_user_specified {
260305
DelegationGenerics::UserSpecified
261306
} else {
262307
DelegationGenerics::Default(self.get_fn_like_generics(root_fn_id, span))

compiler/rustc_data_structures/src/sync.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@
2121
//! | `Lock<T>` | `RefCell<T>` | `RefCell<T>` or |
2222
//! | | | `parking_lot::Mutex<T>` |
2323
//! | `RwLock<T>` | `RefCell<T>` | `parking_lot::RwLock<T>` |
24-
//! | `MTLock<T>` [^1] | `T` | `Lock<T>` |
25-
//!
26-
//! [^1]: `MTLock` is similar to `Lock`, but the serial version avoids the cost
27-
//! of a `RefCell`. This is appropriate when interior mutability is not
28-
//! required.
2924
3025
use std::collections::HashMap;
3126
use std::hash::{BuildHasher, Hash};
@@ -106,38 +101,6 @@ mod mode {
106101
}
107102
}
108103

109-
// FIXME(parallel_compiler): Get rid of these aliases across the compiler.
110-
111-
#[derive(Debug, Default)]
112-
pub struct MTLock<T>(Lock<T>);
113-
114-
impl<T> MTLock<T> {
115-
#[inline(always)]
116-
pub fn new(inner: T) -> Self {
117-
MTLock(Lock::new(inner))
118-
}
119-
120-
#[inline(always)]
121-
pub fn into_inner(self) -> T {
122-
self.0.into_inner()
123-
}
124-
125-
#[inline(always)]
126-
pub fn get_mut(&mut self) -> &mut T {
127-
self.0.get_mut()
128-
}
129-
130-
#[inline(always)]
131-
pub fn lock(&self) -> LockGuard<'_, T> {
132-
self.0.lock()
133-
}
134-
135-
#[inline(always)]
136-
pub fn lock_mut(&self) -> LockGuard<'_, T> {
137-
self.lock()
138-
}
139-
}
140-
141104
/// This makes locks panic if they are already held.
142105
/// It is only useful when you are running in a single thread
143106
const ERROR_CHECKING: bool = false;

compiler/rustc_hir_analysis/src/delegation.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,14 @@ fn create_generic_args<'tcx>(
339339
| (FnKind::AssocTrait, FnKind::AssocTrait) => delegation_args,
340340

341341
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
342-
// Special case, as user specifies Trait args in impl trait header, we want to treat
343-
// them as parent args.
342+
// Special case, as user specifies Trait args in trait impl header, we want to treat
343+
// them as parent args. We always generate a function whose generics match
344+
// child generics in trait.
344345
let parent = tcx.local_parent(delegation_id);
345346
parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().args;
347+
348+
assert!(child_args.is_empty(), "Child args can not be used in trait impl case");
349+
346350
tcx.mk_args(&delegation_args[delegation_parent_args_count..])
347351
}
348352

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ use std::cell::OnceCell;
209209
use std::ops::ControlFlow;
210210

211211
use rustc_data_structures::fx::FxIndexMap;
212-
use rustc_data_structures::sync::{MTLock, par_for_each_in};
212+
use rustc_data_structures::sync::{Lock, par_for_each_in};
213213
use rustc_data_structures::unord::{UnordMap, UnordSet};
214214
use rustc_hir as hir;
215215
use rustc_hir::attrs::InlineAttr;
@@ -251,12 +251,12 @@ pub(crate) enum MonoItemCollectionStrategy {
251251
/// The state that is shared across the concurrent threads that are doing collection.
252252
struct SharedState<'tcx> {
253253
/// Items that have been or are currently being recursively collected.
254-
visited: MTLock<UnordSet<MonoItem<'tcx>>>,
254+
visited: Lock<UnordSet<MonoItem<'tcx>>>,
255255
/// Items that have been or are currently being recursively treated as "mentioned", i.e., their
256256
/// consts are evaluated but nothing is added to the collection.
257-
mentioned: MTLock<UnordSet<MonoItem<'tcx>>>,
257+
mentioned: Lock<UnordSet<MonoItem<'tcx>>>,
258258
/// Which items are being used where, for better errors.
259-
usage_map: MTLock<UsageMap<'tcx>>,
259+
usage_map: Lock<UsageMap<'tcx>>,
260260
}
261261

262262
pub(crate) struct UsageMap<'tcx> {
@@ -359,7 +359,7 @@ fn collect_items_root<'tcx>(
359359
state: &SharedState<'tcx>,
360360
recursion_limit: Limit,
361361
) {
362-
if !state.visited.lock_mut().insert(starting_item.node) {
362+
if !state.visited.lock().insert(starting_item.node) {
363363
// We've been here already, no need to search again.
364364
return;
365365
}
@@ -568,21 +568,21 @@ fn collect_items_rec<'tcx>(
568568
// This is part of the output of collection and hence only relevant for "used" items.
569569
// ("Mentioned" items are only considered internally during collection.)
570570
if mode == CollectionMode::UsedItems {
571-
state.usage_map.lock_mut().record_used(starting_item.node, &used_items);
571+
state.usage_map.lock().record_used(starting_item.node, &used_items);
572572
}
573573

574574
{
575575
let mut visited = OnceCell::default();
576576
if mode == CollectionMode::UsedItems {
577577
used_items
578578
.items
579-
.retain(|k, _| visited.get_mut_or_init(|| state.visited.lock_mut()).insert(*k));
579+
.retain(|k, _| visited.get_mut_or_init(|| state.visited.lock()).insert(*k));
580580
}
581581

582582
let mut mentioned = OnceCell::default();
583583
mentioned_items.items.retain(|k, _| {
584584
!visited.get_or_init(|| state.visited.lock()).contains(k)
585-
&& mentioned.get_mut_or_init(|| state.mentioned.lock_mut()).insert(*k)
585+
&& mentioned.get_mut_or_init(|| state.mentioned.lock()).insert(*k)
586586
});
587587
}
588588
if mode == CollectionMode::MentionedItems {
@@ -1810,9 +1810,9 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
18101810
debug!("building mono item graph, beginning at roots");
18111811

18121812
let state = SharedState {
1813-
visited: MTLock::new(UnordSet::default()),
1814-
mentioned: MTLock::new(UnordSet::default()),
1815-
usage_map: MTLock::new(UsageMap::new()),
1813+
visited: Lock::new(UnordSet::default()),
1814+
mentioned: Lock::new(UnordSet::default()),
1815+
usage_map: Lock::new(UsageMap::new()),
18161816
};
18171817
let recursion_limit = tcx.recursion_limit();
18181818

compiler/rustc_target/src/callconv/hexagon.rs

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,76 @@
1-
use rustc_abi::TyAbiInterface;
1+
use rustc_abi::{HasDataLayout, TyAbiInterface};
22

3-
use crate::callconv::{ArgAbi, FnAbi};
3+
use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
44

5-
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
6-
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
7-
ret.make_indirect();
8-
} else {
5+
fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
6+
where
7+
Ty: TyAbiInterface<'a, C> + Copy,
8+
C: HasDataLayout,
9+
{
10+
if !ret.layout.is_sized() {
11+
return;
12+
}
13+
14+
if !ret.layout.is_aggregate() {
915
ret.extend_integer_width_to(32);
16+
return;
17+
}
18+
19+
// Per the Hexagon ABI:
20+
// - Aggregates up to 32 bits are returned in R0
21+
// - Aggregates 33-64 bits are returned in R1:R0
22+
// - Aggregates > 64 bits are returned indirectly via hidden first argument
23+
let size = ret.layout.size;
24+
let bits = size.bits();
25+
if bits <= 32 {
26+
ret.cast_to(Uniform::new(Reg::i32(), size));
27+
} else if bits <= 64 {
28+
ret.cast_to(Uniform::new(Reg::i64(), size));
29+
} else {
30+
ret.make_indirect();
1031
}
1132
}
1233

1334
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
1435
where
1536
Ty: TyAbiInterface<'a, C> + Copy,
37+
C: HasDataLayout,
1638
{
39+
if !arg.layout.is_sized() {
40+
return;
41+
}
1742
if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
1843
arg.make_indirect();
1944
return;
2045
}
21-
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
22-
arg.make_indirect();
23-
} else {
46+
47+
if !arg.layout.is_aggregate() {
2448
arg.extend_integer_width_to(32);
49+
return;
50+
}
51+
52+
// Per the Hexagon ABI:
53+
// - Aggregates up to 32 bits are passed in a single register
54+
// - Aggregates 33-64 bits are passed in a register pair
55+
// - Aggregates > 64 bits are passed on the stack
56+
let size = arg.layout.size;
57+
let bits = size.bits();
58+
if bits <= 32 {
59+
arg.cast_to(Uniform::new(Reg::i32(), size));
60+
} else if bits <= 64 {
61+
arg.cast_to(Uniform::new(Reg::i64(), size));
62+
} else {
63+
arg.pass_by_stack_offset(None);
2564
}
2665
}
2766

2867
pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
2968
where
3069
Ty: TyAbiInterface<'a, C> + Copy,
70+
C: HasDataLayout,
3171
{
3272
if !fn_abi.ret.is_ignore() {
33-
classify_ret(&mut fn_abi.ret);
73+
classify_ret(cx, &mut fn_abi.ret);
3474
}
3575

3676
for arg in fn_abi.args.iter_mut() {

0 commit comments

Comments
 (0)