Skip to content

Commit 0ac4ba0

Browse files
Parse ?const ?Trait
1 parent 3b1a9d3 commit 0ac4ba0

File tree

4 files changed

+30
-24
lines changed

4 files changed

+30
-24
lines changed

src/librustc_ast_lowering/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12541254
| GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
12551255
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
12561256
}
1257-
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
1257+
GenericBound::Trait(_, TraitBoundModifier::Maybe)
1258+
| GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
1259+
None
1260+
}
12581261
GenericBound::Outlives(ref lifetime) => {
12591262
if lifetime_bound.is_none() {
12601263
lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2297,8 +2300,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22972300
fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
22982301
match f {
22992302
TraitBoundModifier::None => hir::TraitBoundModifier::None,
2300-
TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
23012303
TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
2304+
TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
2305+
hir::TraitBoundModifier::Maybe
2306+
}
23022307
}
23032308
}
23042309

src/librustc_ast_passes/ast_validation.rs

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

919919
fn visit_param_bound(&mut self, bound: &'a GenericBound) {
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);
920+
match bound {
921+
GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => {
922+
if let Some(ctx) = self.bound_context {
923+
let msg = format!("`?const` is not permitted in {}", ctx.description());
924+
self.err_handler().span_err(bound.span(), &msg);
925+
}
926+
}
927+
928+
GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
929+
self.err_handler()
930+
.span_err(bound.span(), "`?const` and `?` are mutually exclusive");
924931
}
932+
933+
_ => {}
925934
}
926935

927936
visit::walk_param_bound(self, bound)

src/librustc_parse/parser/ty.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,13 @@ struct BoundModifiers {
2727
}
2828

2929
impl BoundModifiers {
30-
fn to_trait_bound_modifier(&self) -> Result<TraitBoundModifier, &'static str> {
31-
let modifier = match (self.maybe, self.maybe_const) {
30+
fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
31+
match (self.maybe, self.maybe_const) {
3232
(None, None) => TraitBoundModifier::None,
3333
(Some(_), None) => TraitBoundModifier::Maybe,
3434
(None, Some(_)) => TraitBoundModifier::MaybeConst,
35-
(Some(_), Some(_)) => {
36-
return Err("`?const` and `?` are mutually exclusive");
37-
}
38-
};
39-
40-
Ok(modifier)
35+
(Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
36+
}
4137
}
4238
}
4339

@@ -563,16 +559,7 @@ impl<'a> Parser<'a> {
563559
self.expect(&token::CloseDelim(token::Paren))?;
564560
}
565561

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-
562+
let modifier = modifiers.to_trait_bound_modifier();
576563
let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
577564
Ok(GenericBound::Trait(poly_trait, modifier))
578565
}

src/libsyntax/ast.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ pub enum TraitBoundModifier {
279279

280280
/// `?const Trait`
281281
MaybeConst,
282+
283+
/// `?const ?Trait`
284+
//
285+
// This parses but will be rejected during AST validation.
286+
MaybeConstMaybe,
282287
}
283288

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

0 commit comments

Comments
 (0)