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

Fix pub type parsing in trait #2720

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
248 changes: 128 additions & 120 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,126 @@ operator!= (const SimplePath &lhs, const std::string &rhs)
// forward decl for Attribute
class AttrInput;

// Visibility of item - if the item has it, then it is some form of public
struct Visibility
{
public:
enum VisType
{
PRIV,
PUB,
PUB_CRATE,
PUB_SELF,
PUB_SUPER,
PUB_IN_PATH
};

private:
VisType vis_type;
// Only assigned if vis_type is IN_PATH
SimplePath in_path;
location_t locus;

// should this store location info?

public:
// Creates a Visibility - TODO make constructor protected or private?
Visibility (VisType vis_type, SimplePath in_path, location_t locus)
: vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
{}

VisType get_vis_type () const { return vis_type; }

// Returns whether visibility is in an error state.
bool is_error () const
{
return vis_type == PUB_IN_PATH && in_path.is_empty ();
}

// Returns whether a visibility has a path
bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }

// Returns whether visibility is public or not.
bool is_public () const { return vis_type != PRIV && !is_error (); }

location_t get_locus () const { return locus; }

// empty?
// Creates an error visibility.
static Visibility create_error ()
{
return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
UNDEF_LOCATION);
}

// Unique pointer custom clone function
/*std::unique_ptr<Visibility> clone_visibility() const {
return std::unique_ptr<Visibility>(clone_visibility_impl());
}*/

/* TODO: think of a way to only allow valid Visibility states - polymorphism
* is one idea but may be too resource-intensive. */

// Creates a public visibility with no further features/arguments.
// empty?
static Visibility create_public (location_t pub_vis_location)
{
return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
}

// Creates a public visibility with crate-relative paths
static Visibility create_crate (location_t crate_tok_location,
location_t crate_vis_location)
{
return Visibility (PUB_CRATE,
SimplePath::from_str ("crate", crate_tok_location),
crate_vis_location);
}

// Creates a public visibility with self-relative paths
static Visibility create_self (location_t self_tok_location,
location_t self_vis_location)
{
return Visibility (PUB_SELF,
SimplePath::from_str ("self", self_tok_location),
self_vis_location);
}

// Creates a public visibility with parent module-relative paths
static Visibility create_super (location_t super_tok_location,
location_t super_vis_location)
{
return Visibility (PUB_SUPER,
SimplePath::from_str ("super", super_tok_location),
super_vis_location);
}

// Creates a private visibility
static Visibility create_private ()
{
return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
}

// Creates a public visibility with a given path or whatever.
static Visibility create_in_path (SimplePath in_path,
location_t in_path_vis_location)
{
return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
}

std::string as_string () const;
const SimplePath &get_path () const { return in_path; }
SimplePath &get_path () { return in_path; }

protected:
// Clone function implementation - not currently virtual but may be if
// polymorphism used
/*virtual*/ Visibility *clone_visibility_impl () const
{
return new Visibility (*this);
}
};

// aka Attr
// Attribute AST representation
struct Attribute
Expand Down Expand Up @@ -1042,125 +1162,6 @@ class Item : public Stmt
Item *clone_stmt_impl () const final override { return clone_item_impl (); }
};

// Visibility of item - if the item has it, then it is some form of public
struct Visibility
{
public:
enum VisType
{
PRIV,
PUB,
PUB_CRATE,
PUB_SELF,
PUB_SUPER,
PUB_IN_PATH
};

private:
VisType vis_type;
// Only assigned if vis_type is IN_PATH
SimplePath in_path;
location_t locus;

// should this store location info?

public:
// Creates a Visibility - TODO make constructor protected or private?
Visibility (VisType vis_type, SimplePath in_path, location_t locus)
: vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
{}

VisType get_vis_type () const { return vis_type; }

// Returns whether visibility is in an error state.
bool is_error () const
{
return vis_type == PUB_IN_PATH && in_path.is_empty ();
}

// Returns whether a visibility has a path
bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }

// Returns whether visibility is public or not.
bool is_public () const { return vis_type != PRIV && !is_error (); }

location_t get_locus () const { return locus; }

// empty?
// Creates an error visibility.
static Visibility create_error ()
{
return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
UNDEF_LOCATION);
}

// Unique pointer custom clone function
/*std::unique_ptr<Visibility> clone_visibility() const {
return std::unique_ptr<Visibility>(clone_visibility_impl());
}*/

/* TODO: think of a way to only allow valid Visibility states - polymorphism
* is one idea but may be too resource-intensive. */

// Creates a public visibility with no further features/arguments.
// empty?
static Visibility create_public (location_t pub_vis_location)
{
return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
}

// Creates a public visibility with crate-relative paths
static Visibility create_crate (location_t crate_tok_location,
location_t crate_vis_location)
{
return Visibility (PUB_CRATE,
SimplePath::from_str ("crate", crate_tok_location),
crate_vis_location);
}

// Creates a public visibility with self-relative paths
static Visibility create_self (location_t self_tok_location,
location_t self_vis_location)
{
return Visibility (PUB_SELF,
SimplePath::from_str ("self", self_tok_location),
self_vis_location);
}

// Creates a public visibility with parent module-relative paths
static Visibility create_super (location_t super_tok_location,
location_t super_vis_location)
{
return Visibility (PUB_SUPER,
SimplePath::from_str ("super", super_tok_location),
super_vis_location);
}

// Creates a private visibility
static Visibility create_private ()
{
return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
}

// Creates a public visibility with a given path or whatever.
static Visibility create_in_path (SimplePath in_path,
location_t in_path_vis_location)
{
return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
}

std::string as_string () const;
const SimplePath &get_path () const { return in_path; }
SimplePath &get_path () { return in_path; }

protected:
// Clone function implementation - not currently virtual but may be if
// polymorphism used
/*virtual*/ Visibility *clone_visibility_impl () const
{
return new Visibility (*this);
}
};
// Item that supports visibility - abstract base class
class VisItem : public Item
{
Expand Down Expand Up @@ -1649,13 +1650,20 @@ class TraitItem : virtual public AssociatedItem
{
protected:
TraitItem (location_t locus)
: node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
: node_id (Analysis::Mappings::get ()->get_next_node_id ()),
vis (Visibility::create_private ()), locus (locus)
{}

TraitItem (Visibility vis, location_t locus)
: node_id (Analysis::Mappings::get ()->get_next_node_id ()), vis (vis),
locus (locus)
{}

// Clone function implementation as pure virtual method
virtual TraitItem *clone_associated_item_impl () const override = 0;

NodeId node_id;
Visibility vis;
location_t locus;

public:
Expand Down
5 changes: 3 additions & 2 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -3048,8 +3048,9 @@ class TraitItemType : public TraitItem

TraitItemType (Identifier name,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
std::vector<Attribute> outer_attrs, location_t locus)
: TraitItem (locus), outer_attrs (std::move (outer_attrs)),
std::vector<Attribute> outer_attrs, Visibility vis,
location_t locus)
: TraitItem (vis, locus), outer_attrs (std::move (outer_attrs)),
name (std::move (name)), type_param_bounds (std::move (type_param_bounds))
{}

Expand Down
10 changes: 7 additions & 3 deletions gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
/* DO NOT INCLUDE ANYWHERE - this is automatically included with rust-parse.h
* This is also the reason why there are no include guards. */

#include "rust-item.h"
#include "rust-token.h"
#define INCLUDE_ALGORITHM
#include "rust-diagnostics.h"
Expand Down Expand Up @@ -5012,12 +5013,14 @@ Parser<ManagedTokenSource>::parse_trait_item ()
// parse outer attributes (if they exist)
AST::AttrVec outer_attrs = parse_outer_attributes ();

AST::Visibility vis = parse_visibility ();

// lookahead to determine what type of trait item to parse
const_TokenPtr tok = lexer.peek_token ();
switch (tok->get_id ())
{
case TYPE:
return parse_trait_type (std::move (outer_attrs));
return parse_trait_type (std::move (outer_attrs), vis);
case CONST:
// disambiguate with function qualifier
if (lexer.peek_token (1)->get_id () == IDENTIFIER)
Expand Down Expand Up @@ -5176,7 +5179,8 @@ Parser<ManagedTokenSource>::parse_trait_item ()
// Parse a typedef trait item.
template <typename ManagedTokenSource>
std::unique_ptr<AST::TraitItemType>
Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs)
Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
AST::Visibility vis)
{
location_t locus = lexer.peek_token ()->get_locus ();
skip_token (TYPE);
Expand Down Expand Up @@ -5208,7 +5212,7 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs)

return std::unique_ptr<AST::TraitItemType> (
new AST::TraitItemType (std::move (ident), std::move (bounds),
std::move (outer_attrs), locus));
std::move (outer_attrs), vis, locus));
}

// Parses a constant trait item.
Expand Down
3 changes: 2 additions & 1 deletion gcc/rust/parse/rust-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef RUST_PARSE_H
#define RUST_PARSE_H

#include "rust-item.h"
#include "rust-lex.h"
#include "rust-ast-full.h"
#include "rust-diagnostics.h"
Expand Down Expand Up @@ -331,7 +332,7 @@ template <typename ManagedTokenSource> class Parser
std::unique_ptr<AST::Trait> parse_trait (AST::Visibility vis,
AST::AttrVec outer_attrs);
std::unique_ptr<AST::TraitItemType>
parse_trait_type (AST::AttrVec outer_attrs);
parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility);
std::unique_ptr<AST::TraitItemConst>
parse_trait_const (AST::AttrVec outer_attrs);
std::unique_ptr<AST::Param> parse_self_param ();
Expand Down
6 changes: 6 additions & 0 deletions gcc/testsuite/rust/compile/trait_pub_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {}

#[cfg(FALSE)]
trait T {
pub type X;
}