Skip to content

Commit eb60346

Browse files
Add MaybeConst variant to {ast,hir}::TraitBoundModifier
1 parent 958b0bc commit eb60346

File tree

6 files changed

+42
-32
lines changed

6 files changed

+42
-32
lines changed

src/librustc_ast_lowering/lib.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12501250
let bounds =
12511251
this.arena.alloc_from_iter(bounds.iter().filter_map(
12521252
|bound| match *bound {
1253-
GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
1253+
GenericBound::Trait(ref ty, TraitBoundModifier::None)
1254+
| GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
12541255
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
12551256
}
12561257
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
@@ -2158,10 +2159,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21582159
p: &PolyTraitRef,
21592160
mut itctx: ImplTraitContext<'_, 'hir>,
21602161
) -> hir::PolyTraitRef<'hir> {
2161-
if p.trait_ref.constness.is_some() {
2162-
self.diagnostic().span_err(p.span, "`?const` on trait bounds is not yet implemented");
2163-
}
2164-
21652162
let bound_generic_params = self.lower_generic_params(
21662163
&p.bound_generic_params,
21672164
&NodeMap::default(),
@@ -2301,6 +2298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23012298
match f {
23022299
TraitBoundModifier::None => hir::TraitBoundModifier::None,
23032300
TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
2301+
TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
23042302
}
23052303
}
23062304

src/librustc_ast_passes/ast_validation.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -917,22 +917,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
917917
}
918918

919919
fn visit_param_bound(&mut self, bound: &'a GenericBound) {
920-
if let GenericBound::Trait(poly, maybe_bound) = bound {
921-
match poly.trait_ref.constness {
922-
Some(Constness::NotConst) => {
923-
if *maybe_bound == TraitBoundModifier::Maybe {
924-
self.err_handler()
925-
.span_err(bound.span(), "`?const` and `?` are mutually exclusive");
926-
}
927-
928-
if let Some(ctx) = self.bound_context {
929-
let msg = format!("`?const` is not permitted in {}", ctx.description());
930-
self.err_handler().span_err(bound.span(), &msg);
931-
}
932-
}
933-
934-
Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"),
935-
None => {}
920+
if let GenericBound::Trait(_, TraitBoundModifier::MaybeConst) = bound {
921+
if let Some(ctx) = self.bound_context {
922+
let msg = format!("`?const` is not permitted in {}", ctx.description());
923+
self.err_handler().span_err(bound.span(), &msg);
936924
}
937925
}
938926

src/librustc_hir/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ impl GenericArgs<'_> {
364364
pub enum TraitBoundModifier {
365365
None,
366366
Maybe,
367+
MaybeConst,
367368
}
368369

369370
/// The AST represents all type param bounds as types.

src/librustc_parse/parser/ty.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ struct BoundModifiers {
2727
}
2828

2929
impl BoundModifiers {
30-
fn trait_bound_modifier(&self) -> TraitBoundModifier {
31-
match self.maybe {
32-
Some(_) => TraitBoundModifier::Maybe,
33-
None => TraitBoundModifier::None,
34-
}
30+
fn to_trait_bound_modifier(&self) -> Result<TraitBoundModifier, &'static str> {
31+
let modifier = match (self.maybe, self.maybe_const) {
32+
(None, None) => TraitBoundModifier::None,
33+
(Some(_), None) => TraitBoundModifier::Maybe,
34+
(None, Some(_)) => TraitBoundModifier::MaybeConst,
35+
(Some(_), Some(_)) => {
36+
return Err("`?const` and `?` are mutually exclusive");
37+
}
38+
};
39+
40+
Ok(modifier)
3541
}
3642
}
3743

@@ -215,7 +221,7 @@ impl<'a> Parser<'a> {
215221
) -> PResult<'a, TyKind> {
216222
assert_ne!(self.token, token::Question);
217223

218-
let poly_trait_ref = PolyTraitRef::new(generic_params, path, None, lo.to(self.prev_span));
224+
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
219225
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
220226
if parse_plus {
221227
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
@@ -557,9 +563,18 @@ impl<'a> Parser<'a> {
557563
self.expect(&token::CloseDelim(token::Paren))?;
558564
}
559565

560-
let constness = modifiers.maybe_const.map(|_| ast::Constness::NotConst);
561-
let poly_trait = PolyTraitRef::new(lifetime_defs, path, constness, lo.to(self.prev_span));
562-
Ok(GenericBound::Trait(poly_trait, modifiers.trait_bound_modifier()))
566+
let modifier = match modifiers.to_trait_bound_modifier() {
567+
Ok(m) => m,
568+
Err(msg) => {
569+
self.struct_span_err(lo.to(self.prev_span), msg).emit();
570+
571+
// Continue compilation as if the user had written `?Trait`.
572+
TraitBoundModifier::Maybe
573+
}
574+
};
575+
576+
let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
577+
Ok(GenericBound::Trait(poly_trait, modifier))
563578
}
564579

565580
/// Optionally parses `for<$generic_params>`.

src/librustdoc/html/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ impl clean::GenericBound {
361361
let modifier_str = match modifier {
362362
hir::TraitBoundModifier::None => "",
363363
hir::TraitBoundModifier::Maybe => "?",
364+
hir::TraitBoundModifier::MaybeConst => "?const",
364365
};
365366
if f.alternate() {
366367
write!(f, "{}{:#}", modifier_str, ty.print())

src/libsyntax/ast.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,19 @@ pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0);
266266
/// small, positive ids.
267267
pub const DUMMY_NODE_ID: NodeId = NodeId::MAX;
268268

269-
/// A modifier on a bound, currently this is only used for `?Sized`, where the
270-
/// modifier is `Maybe`. Negative bounds should also be handled here.
269+
/// A modifier on a bound, e.g., `?Sized` or `?const Trait`.
270+
///
271+
/// Negative bounds should also be handled here.
271272
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
272273
pub enum TraitBoundModifier {
274+
/// No modifiers
273275
None,
276+
277+
/// `?Trait`
274278
Maybe,
279+
280+
/// `?const Trait`
281+
MaybeConst,
275282
}
276283

277284
/// The AST represents all type param bounds as types.

0 commit comments

Comments
 (0)