Skip to content

Implement ?const opt-out for trait bounds #68140

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

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