Skip to content

Commit 14e4661

Browse files
committed
Auto merge of #157696 - CrooseGit:dev/reucru01/contextual_only, r=<try>
crater: contextual implementation of `only` trait bound modifier
2 parents ab26b17 + 9ba2423 commit 14e4661

15 files changed

Lines changed: 239 additions & 13 deletions

File tree

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,6 +3179,8 @@ pub enum BoundPolarity {
31793179
Negative(Span),
31803180
/// `Type: ?Trait`
31813181
Maybe(Span),
3182+
/// `Type: only Trait`,
3183+
Only(Span),
31823184
}
31833185

31843186
impl BoundPolarity {
@@ -3187,6 +3189,7 @@ impl BoundPolarity {
31873189
Self::Positive => "",
31883190
Self::Negative(_) => "!",
31893191
Self::Maybe(_) => "?",
3192+
Self::Only(_) => "only",
31903193
}
31913194
}
31923195
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
22372237

22382238
if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
22392239
self.validate_relaxed_bound(trait_ref, *span, rbp);
2240+
} else if let ast::BoundPolarity::Only(_) = modifiers.polarity {
2241+
self.validate_only_bound(trait_ref, *span);
22402242
}
22412243

22422244
hir::PolyTraitRef {
@@ -2247,6 +2249,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
22472249
}
22482250
}
22492251

2252+
fn validate_only_bound(&self, trait_ref: hir::TraitRef<'_>, span: Span) {
2253+
if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res
2254+
&& !(self.tcx.is_lang_item(def_id, hir::LangItem::MetaSized)
2255+
|| self.tcx.is_lang_item(def_id, hir::LangItem::Sized)
2256+
|| self.tcx.is_lang_item(def_id, hir::LangItem::PointeeSized))
2257+
{
2258+
self.dcx()
2259+
.struct_span_err(span, "`only` may only be applied to sizedness traits")
2260+
.emit();
2261+
}
2262+
}
2263+
22502264
fn validate_relaxed_bound(
22512265
&self,
22522266
trait_ref: hir::TraitRef<'_>,
@@ -2812,6 +2826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
28122826
BoundPolarity::Positive => BoundPolarity::Positive,
28132827
BoundPolarity::Negative(span) => BoundPolarity::Negative(self.lower_span(span)),
28142828
BoundPolarity::Maybe(span) => BoundPolarity::Maybe(self.lower_span(span)),
2829+
BoundPolarity::Only(span) => BoundPolarity::Only(self.lower_span(span)),
28152830
};
28162831
hir::TraitBoundModifiers { constness, polarity }
28172832
}

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,9 @@ impl<'a> State<'a> {
14781478
}
14791479
match polarity {
14801480
ast::BoundPolarity::Positive => {}
1481-
ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
1481+
ast::BoundPolarity::Negative(_)
1482+
| ast::BoundPolarity::Maybe(_)
1483+
| ast::BoundPolarity::Only(_) => {
14821484
self.word(polarity.as_str());
14831485
}
14841486
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ struct CollectedBound {
3030
maybe: bool,
3131
/// `!Trait`
3232
negative: bool,
33+
/// `only Trait`
34+
only_modifier: bool,
3335
}
3436

3537
impl CollectedBound {
36-
/// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered.
38+
/// Returns `true` if any of `Trait`, `?Trait`, `only Trait` or `!Trait` were encountered.
3739
fn any(&self) -> bool {
38-
self.positive || self.maybe || self.negative
40+
self.positive || self.maybe || self.negative || self.only_modifier
3941
}
4042
}
4143

@@ -98,6 +100,7 @@ fn collect_bounds<'a, 'tcx>(
98100
match ptr.modifiers.polarity {
99101
hir::BoundPolarity::Maybe(_) => collect_into.maybe = true,
100102
hir::BoundPolarity::Negative(_) => collect_into.negative = true,
103+
hir::BoundPolarity::Only(_) => collect_into.only_modifier = true,
101104
hir::BoundPolarity::Positive => collect_into.positive = true,
102105
}
103106
});

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
973973
// we still need to perform several validation steps (see below). Instead, simply "pour" all
974974
// resulting bounds "down the drain", i.e., into a new `Vec` that just gets dropped at the end.
975975
let transient = match polarity {
976-
hir::BoundPolarity::Positive => {
976+
hir::BoundPolarity::Positive | hir::BoundPolarity::Only(_) => {
977977
// To elaborate on the comment directly above, regarding `PointeeSized` specifically,
978978
// we don't "reify" such bounds to avoid trait system limitations -- namely,
979979
// non-global where-clauses being preferred over item bounds (where `PointeeSized`
@@ -990,9 +990,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
990990
let bounds = if transient { &mut Vec::new() } else { bounds };
991991

992992
let polarity = match polarity {
993-
hir::BoundPolarity::Positive | hir::BoundPolarity::Maybe(_) => {
994-
ty::PredicatePolarity::Positive
995-
}
993+
hir::BoundPolarity::Positive
994+
| hir::BoundPolarity::Maybe(_)
995+
| hir::BoundPolarity::Only(_) => ty::PredicatePolarity::Positive,
996996
hir::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
997997
};
998998

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ impl<'a> State<'a> {
824824
hir::BoundPolarity::Positive => {}
825825
hir::BoundPolarity::Negative(_) => self.word("!"),
826826
hir::BoundPolarity::Maybe(_) => self.word("?"),
827+
hir::BoundPolarity::Only(_) => self.word_space("only"),
827828
}
828829
self.print_formal_generic_params(t.bound_generic_params);
829830
self.print_trait_ref(&t.trait_ref);

compiler/rustc_parse/src/parser/token_type.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub enum TokenType {
106106
KwMod,
107107
KwMove,
108108
KwMut,
109+
KwOnly,
109110
KwPub,
110111
KwRaw,
111112
KwRef,
@@ -247,6 +248,7 @@ impl TokenType {
247248
KwMod,
248249
KwMove,
249250
KwMut,
251+
KwOnly,
250252
KwPub,
251253
KwRaw,
252254
KwRef,
@@ -324,6 +326,7 @@ impl TokenType {
324326
TokenType::KwMod => Some(kw::Mod),
325327
TokenType::KwMove => Some(kw::Move),
326328
TokenType::KwMut => Some(kw::Mut),
329+
TokenType::KwOnly => Some(kw::Only),
327330
TokenType::KwPub => Some(kw::Pub),
328331
TokenType::KwRaw => Some(kw::Raw),
329332
TokenType::KwRef => Some(kw::Ref),
@@ -540,6 +543,7 @@ macro_rules! exp {
540543
(Mod) => { exp!(@kw, Mod, KwMod) };
541544
(Move) => { exp!(@kw, Move, KwMove) };
542545
(Mut) => { exp!(@kw, Mut, KwMut) };
546+
(Only) => { exp!(@kw, Only, KwOnly) };
543547
(Pub) => { exp!(@kw, Pub, KwPub) };
544548
(Raw) => { exp!(@kw, Raw, KwRaw) };
545549
(Ref) => { exp!(@kw, Ref, KwRef) };

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ impl<'a> Parser<'a> {
11201120
|| self.check(exp!(OpenParen))
11211121
|| self.can_begin_maybe_const_bound()
11221122
|| self.check_keyword(exp!(Const))
1123+
|| self.check_keyword(exp!(Only))
11231124
|| self.check_keyword(exp!(Async))
11241125
|| self.check_keyword(exp!(Use))
11251126
}
@@ -1201,7 +1202,9 @@ impl<'a> Parser<'a> {
12011202

12021203
match polarity {
12031204
BoundPolarity::Positive => {}
1204-
BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => {
1205+
BoundPolarity::Negative(span)
1206+
| BoundPolarity::Maybe(span)
1207+
| BoundPolarity::Only(span) => {
12051208
return self
12061209
.dcx()
12071210
.emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() });
@@ -1265,6 +1268,8 @@ impl<'a> Parser<'a> {
12651268
} else if self.eat(exp!(Bang)) {
12661269
self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
12671270
BoundPolarity::Negative(self.prev_token.span)
1271+
} else if self.eat_keyword(exp!(Only)) {
1272+
BoundPolarity::Only(self.prev_token.span)
12681273
} else {
12691274
BoundPolarity::Positive
12701275
};
@@ -1274,7 +1279,9 @@ impl<'a> Parser<'a> {
12741279
BoundPolarity::Positive => {
12751280
// All trait bound modifiers allowed to combine with positive polarity
12761281
}
1277-
BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
1282+
BoundPolarity::Maybe(polarity_span)
1283+
| BoundPolarity::Negative(polarity_span)
1284+
| BoundPolarity::Only(polarity_span) => {
12781285
match (asyncness, constness) {
12791286
(BoundAsyncness::Normal, BoundConstness::Never) => {
12801287
// Ok, no modifiers.
@@ -1346,7 +1353,9 @@ impl<'a> Parser<'a> {
13461353

13471354
if let Some(binder_span) = binder_span {
13481355
match modifiers.polarity {
1349-
BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1356+
BoundPolarity::Negative(polarity_span)
1357+
| BoundPolarity::Maybe(polarity_span)
1358+
| BoundPolarity::Only(polarity_span) => {
13501359
self.dcx().emit_err(errors::BinderAndPolarity {
13511360
binder_span,
13521361
polarity_span,

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ symbols! {
130130
ContractRequires: "contract_requires",
131131
Default: "default",
132132
MacroRules: "macro_rules",
133+
Only: "only",
133134
Raw: "raw",
134135
Reuse: "reuse",
135136
Safe: "safe",

src/librustdoc/html/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ pub(crate) fn print_generic_bound(
267267
hir::BoundPolarity::Positive => "",
268268
hir::BoundPolarity::Maybe(_) => "?",
269269
hir::BoundPolarity::Negative(_) => "!",
270+
hir::BoundPolarity::Only(_) => "only",
270271
})?;
271272
print_poly_trait(ty, cx).fmt(f)
272273
}

0 commit comments

Comments
 (0)