Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/librustc_ast_lowering/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
}
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
GenericBound::Trait(_, TraitBoundModifier::Maybe)
| GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave a comment here stating that these are ignored here because they have already errored in ast validation.

None
}
GenericBound::Outlives(ref lifetime) => {
if lifetime_bound.is_none() {
lifetime_bound = Some(this.lower_lifetime(lifetime));
Expand Down Expand Up @@ -2297,8 +2300,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
match f {
TraitBoundModifier::None => hir::TraitBoundModifier::None,
TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
hir::TraitBoundModifier::Maybe
}
}
}

Expand Down
17 changes: 13 additions & 4 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,11 +917,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_param_bound(&mut self, bound: &'a GenericBound) {
if let GenericBound::Trait(_, TraitBoundModifier::MaybeConst) = bound {
if let Some(ctx) = self.bound_context {
let msg = format!("`?const` is not permitted in {}", ctx.description());
self.err_handler().span_err(bound.span(), &msg);
match bound {
GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => {
if let Some(ctx) = self.bound_context {
let msg = format!("`?const` is not permitted in {}", ctx.description());
self.err_handler().span_err(bound.span(), &msg);
}
}

GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
self.err_handler()
.span_err(bound.span(), "`?const` and `?` are mutually exclusive");
}

_ => {}
}

visit::walk_param_bound(self, bound)
Expand Down
23 changes: 5 additions & 18 deletions src/librustc_parse/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,13 @@ struct BoundModifiers {
}

impl BoundModifiers {
fn to_trait_bound_modifier(&self) -> Result<TraitBoundModifier, &'static str> {
let modifier = match (self.maybe, self.maybe_const) {
fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
match (self.maybe, self.maybe_const) {
(None, None) => TraitBoundModifier::None,
(Some(_), None) => TraitBoundModifier::Maybe,
(None, Some(_)) => TraitBoundModifier::MaybeConst,
(Some(_), Some(_)) => {
return Err("`?const` and `?` are mutually exclusive");
}
};

Ok(modifier)
(Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
}
}
}

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

let modifier = match modifiers.to_trait_bound_modifier() {
Ok(m) => m,
Err(msg) => {
self.struct_span_err(lo.to(self.prev_span), msg).emit();

// Continue compilation as if the user had written `?Trait`.
TraitBoundModifier::Maybe
}
};

let modifier = modifiers.to_trait_bound_modifier();
let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
Ok(GenericBound::Trait(poly_trait, modifier))
}
Expand Down
5 changes: 5 additions & 0 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ pub enum TraitBoundModifier {

/// `?const Trait`
MaybeConst,

/// `?const ?Trait`
//
// This parses but will be rejected during AST validation.
MaybeConstMaybe,
}

/// The AST represents all type param bounds as types.
Expand Down