Skip to content

Commit ed4dd0c

Browse files
committed
cool new attribute
1 parent 2f320a2 commit ed4dd0c

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
605605
rustc_attr!(
606606
rustc_conversion_suggestion, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE
607607
),
608+
609+
rustc_attr!(
610+
rustc_select_quick_discard, Normal, template!(Word), ErrorFollowing, INTERNAL_UNSTABLE
611+
),
612+
608613
// Prevents field reads in the marked trait or method to be considered
609614
// during dead code analysis.
610615
rustc_attr!(

compiler/rustc_passes/src/check_attr.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ impl CheckAttrVisitor<'_> {
121121
sym::rustc_lint_diagnostics => {
122122
self.check_rustc_lint_diagnostics(&attr, span, target)
123123
}
124+
sym::rustc_select_quick_discard => {
125+
self.check_rustc_select_quick_discard(&attr, span, target)
126+
}
124127
sym::rustc_clean
125128
| sym::rustc_dirty
126129
| sym::rustc_if_this_changed
@@ -1431,6 +1434,24 @@ impl CheckAttrVisitor<'_> {
14311434
self.check_applied_to_fn_or_method(attr, span, target)
14321435
}
14331436

1437+
fn check_rustc_select_quick_discard(
1438+
&self,
1439+
attr: &Attribute,
1440+
span: Span,
1441+
target: Target,
1442+
) -> bool {
1443+
if matches!(target, Target::Impl) {
1444+
true
1445+
} else {
1446+
self.tcx
1447+
.sess
1448+
.struct_span_err(attr.span, "attribute should be applied to an impl")
1449+
.span_label(span, "not an impl")
1450+
.emit();
1451+
false
1452+
}
1453+
}
1454+
14341455
/// Checks that the dep-graph debugging attributes are only present when the query-dep-graph
14351456
/// option is passed to the compiler.
14361457
fn check_rustc_dirty_clean(&self, attr: &Attribute) -> bool {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ symbols! {
12601260
rustc_promotable,
12611261
rustc_regions,
12621262
rustc_reservation_impl,
1263+
rustc_select_quick_discard,
12631264
rustc_serialize,
12641265
rustc_skip_array_during_method_dispatch,
12651266
rustc_specialization_trait,

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
1313
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
1414
use rustc_middle::ty::print::with_no_trimmed_paths;
1515
use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
16+
use rustc_span::sym;
1617
use rustc_target::spec::abi::Abi;
1718

1819
use crate::traits;
@@ -135,8 +136,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
135136
// candidate which assumes $0 == int, one that assumes `$0 ==
136137
// usize`, etc. This spells an ambiguity.
137138

138-
let mut candidates = self.filter_impls(candidates, stack.obligation);
139-
139+
let candidates = self.filter_impls(candidates, stack.obligation);
140+
let mut candidates = candidates
141+
.into_iter()
142+
.map(|c| match c {
143+
ImplCandidate(impl_def)
144+
if self.tcx().has_attr(impl_def, sym::rustc_select_quick_discard) =>
145+
{
146+
match self.evaluate_candidate(stack, &c) {
147+
Ok(eval) if eval.may_apply() => Ok(Some(c)),
148+
Ok(_) => Ok(None),
149+
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
150+
Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
151+
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
152+
}
153+
}
154+
_ => Ok(Some(c)),
155+
})
156+
.flat_map(Result::transpose)
157+
.collect::<Result<Vec<_>, _>>()?;
140158
// If there is more than one candidate, first winnow them down
141159
// by considering extra conditions (nested obligations and so
142160
// forth). We don't winnow if there is exactly one

0 commit comments

Comments
 (0)