Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ?const opt-out for trait bounds #68140

Merged
merged 12 commits into from
Jan 21, 2020
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