diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 67ae92fb42d..4dc7f9710f3 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -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
@@ -1042,125 +1162,6 @@ protected:
   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
 {
@@ -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:
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 8b53bc63a83..2c0e45962ce 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3048,8 +3048,9 @@ public:
 
   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))
   {}
 
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index fd648c53e14..0ae89dc3907 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -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"
@@ -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)
@@ -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);
@@ -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.
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 9e924e0015c..08e6ce000f4 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -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"
@@ -331,7 +332,7 @@ private:
   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 ();
