diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-21 19:42:20 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-21 19:42:20 +0100 |
| commit | 3484e2fab4153068e4e5eaebab215e680efe38f1 (patch) | |
| tree | 4955c22b712892f482ee718f954769726fd66baa /src/libsyntax | |
| parent | d532a04a1c6afb34c8b0ac5da3e2bbf76aad5800 (diff) | |
| parent | 6bd69a10921785aa8ab68e58d9c7a7ea1ff6ef96 (diff) | |
| download | rust-3484e2fab4153068e4e5eaebab215e680efe38f1.tar.gz rust-3484e2fab4153068e4e5eaebab215e680efe38f1.zip | |
Rollup merge of #68140 - ecstatic-morse:const-trait-bound-opt-out, r=oli-obk
Implement `?const` opt-out for trait bounds For now, such bounds are treated exactly the same as unprefixed ones in all contexts. [RFC 2632](https://github.com/rust-lang/rfcs/pull/2632) does not specify whether such bounds are forbidden outside of `const` contexts, so they are allowed at the moment. Prior to this PR, the constness of a trait bound/impl was stored in `TraitRef`. Now, the constness of an `impl` is stored in `ast::ItemKind::Impl` and the constness of a bound in `ast::TraitBoundModifer`. Additionally, constness of trait bounds is now stored in an additional field of `ty::Predicate::Trait`, and the combination of the constness of the item along with any `TraitBoundModifier` determines the constness of the bound in accordance with the RFC. Encoding the constness of impls at the `ty` level is left for a later PR. After a discussion in \#wg-grammar on Discord, it was decided that the grammar should not encode the mutual exclusivity of trait bound modifiers. The grammar for trait bound modifiers remains `[?const] [?]`. To encode this, I add a dummy variant to `ast::TraitBoundModifier` that is used when the syntax `?const ?` appears. This variant causes an error in AST validation and disappears during HIR lowering. cc #67794 r? @oli-obk
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/mut_visit.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 1 |
4 files changed, 32 insertions, 22 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a5a4eb1583b..5f38ac4cc0f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -266,12 +266,24 @@ pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0); /// small, positive ids. pub const DUMMY_NODE_ID: NodeId = NodeId::MAX; -/// A modifier on a bound, currently this is only used for `?Sized`, where the -/// modifier is `Maybe`. Negative bounds should also be handled here. +/// A modifier on a bound, e.g., `?Sized` or `?const Trait`. +/// +/// Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] pub enum TraitBoundModifier { + /// No modifiers None, + + /// `?Trait` Maybe, + + /// `?const Trait` + MaybeConst, + + /// `?const ?Trait` + // + // This parses but will be rejected during AST validation. + MaybeConstMaybe, } /// The AST represents all type param bounds as types. @@ -1033,7 +1045,7 @@ impl Expr { pub fn to_bound(&self) -> Option<GenericBound> { match &self.kind { ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(Vec::new(), path.clone(), None, self.span), + PolyTraitRef::new(Vec::new(), path.clone(), self.span), TraitBoundModifier::None, )), _ => None, @@ -2158,7 +2170,8 @@ impl IsAsync { } } -#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(HashStable_Generic)] pub enum Constness { Const, NotConst, @@ -2376,15 +2389,6 @@ pub enum AttrKind { pub struct TraitRef { pub path: Path, pub ref_id: NodeId, - - /// The `const` modifier, if any, that appears before this trait. - /// - /// | | `constness` | - /// |----------------|-----------------------------| - /// | `Trait` | `None` | - /// | `const Trait` | `Some(Constness::Const)` | - /// | `?const Trait` | `Some(Constness::NotConst)` | - pub constness: Option<Constness>, } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2399,15 +2403,10 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new( - generic_params: Vec<GenericParam>, - path: Path, - constness: Option<Constness>, - span: Span, - ) -> Self { + pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self { PolyTraitRef { bound_generic_params: generic_params, - trait_ref: TraitRef { path, constness, ref_id: DUMMY_NODE_ID }, + trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, span, } } @@ -2618,6 +2617,7 @@ pub enum ItemKind { unsafety: Unsafety, polarity: ImplPolarity, defaultness: Defaultness, + constness: Constness, generics: Generics, /// The trait being implemented, if any. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 750d054e8a0..4a460c5d7b2 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -838,8 +838,7 @@ pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut } } -pub fn noop_visit_trait_ref<T: MutVisitor>(tr: &mut TraitRef, vis: &mut T) { - let TraitRef { path, ref_id, constness: _ } = tr; +pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { vis.visit_path(path); vis.visit_id(ref_id); } @@ -922,6 +921,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { unsafety: _, polarity: _, defaultness: _, + constness: _, generics, of_trait, self_ty, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bc67980c454..3927e4f9030 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1230,6 +1230,7 @@ impl<'a> State<'a> { unsafety, polarity, defaultness, + constness, ref generics, ref of_trait, ref self_ty, @@ -1240,6 +1241,7 @@ impl<'a> State<'a> { self.print_defaultness(defaultness); self.print_unsafety(unsafety); self.word_nbsp("impl"); + self.print_constness(constness); if !generics.params.is_empty() { self.print_generic_params(&generics.params); @@ -2773,6 +2775,13 @@ impl<'a> State<'a> { } } + crate fn print_constness(&mut self, s: ast::Constness) { + match s { + ast::Constness::Const => self.word_nbsp("const"), + ast::Constness::NotConst => {} + } + } + crate fn print_is_auto(&mut self, s: ast::IsAuto) { match s { ast::IsAuto::Yes => self.word_nbsp("auto"), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d03a9dfc167..946a0d29cd3 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -312,6 +312,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { unsafety: _, polarity: _, defaultness: _, + constness: _, ref generics, ref of_trait, ref self_ty, |
