Skip to content

Commit 312a799

Browse files
committed
Auto merge of #93343 - lqd:attrs, r=spastorino
Only traverse attrs once while checking for coherence override attributes In coherence, while checking for negative impls override attributes: only traverse the `DefId`s' attributes once. This PR is an easy way to get back some of the small perf loss in #93175
2 parents 5ab502c + 644c22d commit 312a799

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::traits::{
1313
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
1414
PredicateObligations, SelectionContext,
1515
};
16+
use rustc_ast::Attribute;
1617
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1718
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
1819
use rustc_middle::ty::fold::TypeFoldable;
@@ -160,24 +161,30 @@ impl OverlapMode {
160161
}
161162

162163
fn overlap_mode<'tcx>(tcx: TyCtxt<'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> OverlapMode {
163-
if tcx.has_attr(impl1_def_id, sym::rustc_strict_coherence)
164-
!= tcx.has_attr(impl2_def_id, sym::rustc_strict_coherence)
165-
{
166-
bug!("Use strict coherence on both impls",);
167-
}
168-
169-
if tcx.has_attr(impl1_def_id, sym::rustc_with_negative_coherence)
170-
!= tcx.has_attr(impl2_def_id, sym::rustc_with_negative_coherence)
171-
{
172-
bug!("Use with negative coherence on both impls",);
173-
}
174-
175-
if tcx.has_attr(impl1_def_id, sym::rustc_strict_coherence) {
176-
OverlapMode::Strict
177-
} else if tcx.has_attr(impl1_def_id, sym::rustc_with_negative_coherence) {
178-
OverlapMode::WithNegative
179-
} else {
180-
OverlapMode::Stable
164+
// Find the possible coherence mode override opt-in attributes for each `DefId`
165+
let find_coherence_attr = |attr: &Attribute| {
166+
let name = attr.name_or_empty();
167+
match name {
168+
sym::rustc_with_negative_coherence | sym::rustc_strict_coherence => Some(name),
169+
_ => None,
170+
}
171+
};
172+
let impl1_coherence_mode = tcx.get_attrs(impl1_def_id).iter().find_map(find_coherence_attr);
173+
let impl2_coherence_mode = tcx.get_attrs(impl2_def_id).iter().find_map(find_coherence_attr);
174+
175+
// If there are any (that currently happens in tests), they need to match. Otherwise, the
176+
// default 1.0 rules are used.
177+
match (impl1_coherence_mode, impl2_coherence_mode) {
178+
(None, None) => OverlapMode::Stable,
179+
(Some(sym::rustc_with_negative_coherence), Some(sym::rustc_with_negative_coherence)) => {
180+
OverlapMode::WithNegative
181+
}
182+
(Some(sym::rustc_strict_coherence), Some(sym::rustc_strict_coherence)) => {
183+
OverlapMode::Strict
184+
}
185+
(Some(mode), _) | (_, Some(mode)) => {
186+
bug!("Use the same coherence mode on both impls: {}", mode)
187+
}
181188
}
182189
}
183190

0 commit comments

Comments
 (0)