about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs57
-rw-r--r--src/libsyntax/ast_util.rs398
-rw-r--r--src/libsyntax/config.rs6
-rw-r--r--src/libsyntax/ext/build.rs8
-rw-r--r--src/libsyntax/fold.rs24
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/parser.rs43
-rw-r--r--src/libsyntax/print/pprust.rs32
-rw-r--r--src/libsyntax/test.rs16
-rw-r--r--src/libsyntax/visit.rs6
10 files changed, 84 insertions, 507 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a441f2990cd..16d4ed53b5b 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -10,7 +10,6 @@
 
 // The Rust abstract syntax tree.
 
-pub use self::StructFieldKind::*;
 pub use self::TyParamBound::*;
 pub use self::UnsafeSource::*;
 pub use self::ViewPath_::*;
@@ -205,6 +204,23 @@ impl fmt::Display for Path {
     }
 }
 
+impl Path {
+    // convert a span and an identifier to the corresponding
+    // 1-segment path
+    pub fn from_ident(s: Span, identifier: Ident) -> Path {
+        Path {
+            span: s,
+            global: false,
+            segments: vec!(
+                PathSegment {
+                    identifier: identifier,
+                    parameters: PathParameters::none()
+                }
+            ),
+        }
+    }
+}
+
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -1877,46 +1893,15 @@ pub enum Visibility {
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct StructField_ {
-    pub kind: StructFieldKind,
+pub struct StructField {
+    pub span: Span,
+    pub ident: Option<Ident>,
+    pub vis: Visibility,
     pub id: NodeId,
     pub ty: P<Ty>,
     pub attrs: Vec<Attribute>,
 }
 
-impl StructField_ {
-    pub fn ident(&self) -> Option<Ident> {
-        match self.kind {
-            NamedField(ref ident, _) => Some(ident.clone()),
-            UnnamedField(_) => None
-        }
-    }
-}
-
-pub type StructField = Spanned<StructField_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum StructFieldKind {
-    NamedField(Ident, Visibility),
-    /// Element of a tuple-like struct
-    UnnamedField(Visibility),
-}
-
-impl StructFieldKind {
-    pub fn is_unnamed(&self) -> bool {
-        match *self {
-            UnnamedField(..) => true,
-            NamedField(..) => false,
-        }
-    }
-
-    pub fn visibility(&self) -> &Visibility {
-        match *self {
-            NamedField(_, ref vis) | UnnamedField(ref vis) => vis
-        }
-    }
-}
-
 /// Fields and Ids of enum variants and structs
 ///
 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
deleted file mode 100644
index 852b153044f..00000000000
--- a/src/libsyntax/ast_util.rs
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ast::*;
-use ast;
-use codemap;
-use codemap::Span;
-use parse::token;
-use print::pprust;
-use ptr::P;
-use visit::{FnKind, Visitor};
-use visit;
-
-use std::cmp;
-use std::u32;
-
-pub fn path_name_i(idents: &[Ident]) -> String {
-    // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
-    idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
-}
-
-pub fn is_path(e: P<Expr>) -> bool {
-    match e.node { ExprKind::Path(..) => true, _ => false }
-}
-
-
-// convert a span and an identifier to the corresponding
-// 1-segment path
-pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
-    ast::Path {
-        span: s,
-        global: false,
-        segments: vec!(
-            ast::PathSegment {
-                identifier: identifier,
-                parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
-                    lifetimes: Vec::new(),
-                    types: P::empty(),
-                    bindings: P::empty(),
-                })
-            }
-        ),
-    }
-}
-
-// If path is a single segment ident path, return that ident. Otherwise, return
-// None.
-pub fn path_to_ident(path: &Path) -> Option<Ident> {
-    if path.segments.len() != 1 {
-        return None;
-    }
-
-    let segment = &path.segments[0];
-    if !segment.parameters.is_empty() {
-        return None;
-    }
-
-    Some(segment.identifier)
-}
-
-pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> P<Pat> {
-    let spanned = codemap::Spanned{ span: s, node: i };
-    P(Pat {
-        id: id,
-        node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), spanned, None),
-        span: s
-    })
-}
-
-/// Generate a "pretty" name for an `impl` from its type and trait.
-/// This is designed so that symbols of `impl`'d methods give some
-/// hint of where they came from, (previously they would all just be
-/// listed as `__extensions__::method_name::hash`, with no indication
-/// of the type).
-pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
-    let mut pretty = match ty {
-        Some(t) => pprust::ty_to_string(t),
-        None => String::from("..")
-    };
-
-    match *trait_ref {
-        Some(ref trait_ref) => {
-            pretty.push('.');
-            pretty.push_str(&pprust::path_to_string(&trait_ref.path));
-        }
-        None => {}
-    }
-    token::gensym_ident(&pretty[..])
-}
-
-pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
-    match field.node.kind {
-        ast::NamedField(_, v) | ast::UnnamedField(v) => v
-    }
-}
-
-// ______________________________________________________________________
-// Enumerating the IDs which appear in an AST
-
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct IdRange {
-    pub min: NodeId,
-    pub max: NodeId,
-}
-
-impl IdRange {
-    pub fn max() -> IdRange {
-        IdRange {
-            min: u32::MAX,
-            max: u32::MIN,
-        }
-    }
-
-    pub fn empty(&self) -> bool {
-        self.min >= self.max
-    }
-
-    pub fn add(&mut self, id: NodeId) {
-        self.min = cmp::min(self.min, id);
-        self.max = cmp::max(self.max, id + 1);
-    }
-}
-
-pub trait IdVisitingOperation {
-    fn visit_id(&mut self, node_id: NodeId);
-}
-
-/// A visitor that applies its operation to all of the node IDs
-/// in a visitable thing.
-
-pub struct IdVisitor<'a, O:'a> {
-    pub operation: &'a mut O,
-    pub visited_outermost: bool,
-}
-
-impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> {
-    fn visit_generics_helper(&mut self, generics: &Generics) {
-        for type_parameter in generics.ty_params.iter() {
-            self.operation.visit_id(type_parameter.id)
-        }
-        for lifetime in &generics.lifetimes {
-            self.operation.visit_id(lifetime.lifetime.id)
-        }
-    }
-}
-
-impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
-    fn visit_mod(&mut self,
-                 module: &Mod,
-                 _: Span,
-                 node_id: NodeId) {
-        self.operation.visit_id(node_id);
-        visit::walk_mod(self, module)
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
-        self.operation.visit_id(foreign_item.id);
-        visit::walk_foreign_item(self, foreign_item)
-    }
-
-    fn visit_item(&mut self, item: &Item) {
-        if self.visited_outermost {
-            return
-        } else {
-            self.visited_outermost = true
-        }
-
-        self.operation.visit_id(item.id);
-        match item.node {
-            ItemKind::Use(ref view_path) => {
-                match view_path.node {
-                    ViewPathSimple(_, _) |
-                    ViewPathGlob(_) => {}
-                    ViewPathList(_, ref paths) => {
-                        for path in paths {
-                            self.operation.visit_id(path.node.id())
-                        }
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        visit::walk_item(self, item);
-
-        self.visited_outermost = false
-    }
-
-    fn visit_local(&mut self, local: &Local) {
-        self.operation.visit_id(local.id);
-        visit::walk_local(self, local)
-    }
-
-    fn visit_block(&mut self, block: &Block) {
-        self.operation.visit_id(block.id);
-        visit::walk_block(self, block)
-    }
-
-    fn visit_stmt(&mut self, statement: &Stmt) {
-        self.operation
-            .visit_id(statement.node.id().expect("attempted to visit unexpanded stmt"));
-        visit::walk_stmt(self, statement)
-    }
-
-    fn visit_pat(&mut self, pattern: &Pat) {
-        self.operation.visit_id(pattern.id);
-        visit::walk_pat(self, pattern)
-    }
-
-    fn visit_expr(&mut self, expression: &Expr) {
-        self.operation.visit_id(expression.id);
-        visit::walk_expr(self, expression)
-    }
-
-    fn visit_ty(&mut self, typ: &Ty) {
-        self.operation.visit_id(typ.id);
-        visit::walk_ty(self, typ)
-    }
-
-    fn visit_generics(&mut self, generics: &Generics) {
-        self.visit_generics_helper(generics);
-        visit::walk_generics(self, generics)
-    }
-
-    fn visit_fn(&mut self,
-                function_kind: visit::FnKind<'v>,
-                function_declaration: &'v FnDecl,
-                block: &'v Block,
-                span: Span,
-                node_id: NodeId) {
-        match function_kind {
-            FnKind::Method(..) if self.visited_outermost => return,
-            FnKind::Method(..) => self.visited_outermost = true,
-            _ => {}
-        }
-
-        self.operation.visit_id(node_id);
-
-        match function_kind {
-            FnKind::ItemFn(_, generics, _, _, _, _) => {
-                self.visit_generics_helper(generics)
-            }
-            FnKind::Method(_, ref sig, _) => {
-                self.visit_generics_helper(&sig.generics)
-            }
-            FnKind::Closure => {}
-        }
-
-        for argument in &function_declaration.inputs {
-            self.operation.visit_id(argument.id)
-        }
-
-        visit::walk_fn(self,
-                       function_kind,
-                       function_declaration,
-                       block,
-                       span);
-
-        if let FnKind::Method(..) = function_kind {
-            self.visited_outermost = false;
-        }
-    }
-
-    fn visit_struct_field(&mut self, struct_field: &StructField) {
-        self.operation.visit_id(struct_field.node.id);
-        visit::walk_struct_field(self, struct_field)
-    }
-
-    fn visit_variant_data(&mut self,
-                        struct_def: &VariantData,
-                        _: ast::Ident,
-                        _: &ast::Generics,
-                        _: NodeId,
-                        _: Span) {
-        self.operation.visit_id(struct_def.id());
-        visit::walk_struct_def(self, struct_def);
-    }
-
-    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
-        self.operation.visit_id(ti.id);
-        visit::walk_trait_item(self, ti);
-    }
-
-    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
-        self.operation.visit_id(ii.id);
-        visit::walk_impl_item(self, ii);
-    }
-
-    fn visit_lifetime(&mut self, lifetime: &Lifetime) {
-        self.operation.visit_id(lifetime.id);
-    }
-
-    fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
-        self.visit_lifetime(&def.lifetime);
-    }
-
-    fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
-        self.operation.visit_id(trait_ref.ref_id);
-        visit::walk_trait_ref(self, trait_ref);
-    }
-}
-
-pub struct IdRangeComputingVisitor {
-    pub result: IdRange,
-}
-
-impl IdRangeComputingVisitor {
-    pub fn new() -> IdRangeComputingVisitor {
-        IdRangeComputingVisitor { result: IdRange::max() }
-    }
-
-    pub fn result(&self) -> IdRange {
-        self.result
-    }
-}
-
-impl IdVisitingOperation for IdRangeComputingVisitor {
-    fn visit_id(&mut self, id: NodeId) {
-        self.result.add(id);
-    }
-}
-
-/// Computes the id range for a single fn body, ignoring nested items.
-pub fn compute_id_range_for_fn_body(fk: FnKind,
-                                    decl: &FnDecl,
-                                    body: &Block,
-                                    sp: Span,
-                                    id: NodeId)
-                                    -> IdRange
-{
-    let mut visitor = IdRangeComputingVisitor::new();
-    let mut id_visitor = IdVisitor {
-        operation: &mut visitor,
-        visited_outermost: false,
-    };
-    id_visitor.visit_fn(fk, decl, body, sp, id);
-    id_visitor.operation.result
-}
-
-/// Returns true if the given pattern consists solely of an identifier
-/// and false otherwise.
-pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
-    match pat.node {
-        PatKind::Ident(..) => true,
-        _ => false,
-    }
-}
-
-// are two paths equal when compared unhygienically?
-// since I'm using this to replace ==, it seems appropriate
-// to compare the span, global, etc. fields as well.
-pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool {
-    (a.span.source_equal(&b.span))
-    && (a.global == b.global)
-    && (segments_name_eq(&a.segments[..], &b.segments[..]))
-}
-
-// are two arrays of segments equal when compared unhygienically?
-pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> bool {
-    a.len() == b.len() &&
-    a.iter().zip(b).all(|(s, t)| {
-        s.identifier.name == t.identifier.name &&
-        // FIXME #7743: ident -> name problems in lifetime comparison?
-        // can types contain idents?
-        s.parameters == t.parameters
-    })
-}
-
-#[cfg(test)]
-mod tests {
-    use ast::*;
-    use super::*;
-
-    fn ident_to_segment(id: Ident) -> PathSegment {
-        PathSegment {identifier: id,
-                     parameters: PathParameters::none()}
-    }
-
-    #[test] fn idents_name_eq_test() {
-        assert!(segments_name_eq(
-            &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
-                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
-            &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(78),SyntaxContext(182))]
-                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
-        assert!(!segments_name_eq(
-            &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
-                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
-            &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(77),SyntaxContext(182))]
-                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
-    }
-}
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 9acb1805cdd..4554a280e5f 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -180,12 +180,12 @@ fn fold_struct<F>(cx: &mut Context<F>, vdata: ast::VariantData) -> ast::VariantD
     match vdata {
         ast::VariantData::Struct(fields, id) => {
             ast::VariantData::Struct(fields.into_iter().filter(|m| {
-                (cx.in_cfg)(&m.node.attrs)
+                (cx.in_cfg)(&m.attrs)
             }).collect(), id)
         }
         ast::VariantData::Tuple(fields, id) => {
             ast::VariantData::Tuple(fields.into_iter().filter(|m| {
-                (cx.in_cfg)(&m.node.attrs)
+                (cx.in_cfg)(&m.attrs)
             }).collect(), id)
         }
         ast::VariantData::Unit(id) => ast::VariantData::Unit(id)
@@ -434,7 +434,7 @@ impl<'v, 'a, 'b> visit::Visitor<'v> for StmtExprAttrFeatureVisitor<'a, 'b> {
     }
 
     fn visit_struct_field(&mut self, s: &'v ast::StructField) {
-        if node_survives_cfg(&s.node.attrs, self.config) {
+        if node_survives_cfg(&s.attrs, self.config) {
             visit::walk_struct_field(self, s);
         }
     }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 0eb42f17f68..a4e5b68277d 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -1007,12 +1007,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
         let fields: Vec<_> = tys.into_iter().map(|ty| {
-            Spanned { span: ty.span, node: ast::StructField_ {
+            ast::StructField {
+                span: ty.span,
                 ty: ty,
-                kind: ast::UnnamedField(ast::Visibility::Inherited),
+                ident: None,
+                vis: ast::Visibility::Inherited,
                 attrs: Vec::new(),
                 id: ast::DUMMY_NODE_ID,
-            }}
+            }
         }).collect();
 
         let vdata = if fields.is_empty() {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 46bcb8067a3..5d378763bef 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -21,7 +21,6 @@
 use ast::*;
 use ast;
 use attr::{ThinAttributes, ThinAttributesExt};
-use ast_util;
 use codemap::{respan, Span, Spanned};
 use parse::token;
 use ptr::P;
@@ -847,15 +846,13 @@ pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> Poly
 }
 
 pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField {
-    let StructField {node: StructField_ {id, kind, ty, attrs}, span} = f;
-    Spanned {
-        node: StructField_ {
-            id: fld.new_id(id),
-            kind: kind,
-            ty: fld.fold_ty(ty),
-            attrs: fold_attrs(attrs, fld),
-        },
-        span: fld.new_span(span)
+    StructField {
+        span: fld.new_span(f.span),
+        id: fld.new_id(f.id),
+        ident: f.ident.map(|ident| fld.fold_ident(ident)),
+        vis: f.vis,
+        ty: fld.fold_ty(f.ty),
+        attrs: fold_attrs(f.attrs, fld),
     }
 }
 
@@ -1073,13 +1070,6 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
                                         folder: &mut T) -> Item {
     let id = folder.new_id(id);
     let node = folder.fold_item_kind(node);
-    let ident = match node {
-        // The node may have changed, recompute the "pretty" impl name.
-        ItemKind::Impl(_, _, _, ref maybe_trait, ref ty, _) => {
-            ast_util::impl_pretty_name(maybe_trait, Some(&ty))
-        }
-        _ => ident
-    };
 
     Item {
         id: id,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 7f8472f8b28..ab14e21e251 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -91,7 +91,6 @@ pub mod syntax {
 
 pub mod abi;
 pub mod ast;
-pub mod ast_util;
 pub mod attr;
 pub mod codemap;
 pub mod config;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 89a504e1ebd..9dc661ed2ea 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -29,7 +29,6 @@ use ast::Local;
 use ast::MacStmtStyle;
 use ast::Mac_;
 use ast::{MutTy, Mutability};
-use ast::NamedField;
 use ast::{Pat, PatKind};
 use ast::{PolyTraitRef, QSelf};
 use ast::{Stmt, StmtKind};
@@ -38,13 +37,11 @@ use ast::StrStyle;
 use ast::SelfKind;
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
-use ast::UnnamedField;
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
 use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
 use ast::{BinOpKind, UnOp};
 use ast;
-use ast_util::{self, ident_to_path};
 use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
 use errors::{self, DiagnosticBuilder};
 use ext::tt::macro_parser;
@@ -1577,9 +1574,14 @@ impl<'a> Parser<'a> {
             pat
         } else {
             debug!("parse_arg_general ident_to_pat");
-            ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
-                                   self.last_span,
-                                   special_idents::invalid)
+            let sp = self.last_span;
+            let spanned = Spanned { span: sp, node: special_idents::invalid };
+            P(Pat {
+                id: ast::DUMMY_NODE_ID,
+                node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable),
+                                     spanned, None),
+                span: sp
+            })
         };
 
         let t = self.parse_ty_sum()?;
@@ -2223,7 +2225,7 @@ impl<'a> Parser<'a> {
                             ctxt: _
                          }, token::Plain) => {
                 self.bump();
-                let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
+                let path = ast::Path::from_ident(mk_sp(lo, hi), id);
                 ex = ExprKind::Path(None, path);
                 hi = self.last_span.hi;
             }
@@ -3679,7 +3681,7 @@ impl<'a> Parser<'a> {
                         // Parse macro invocation
                         let ident = self.parse_ident()?;
                         let ident_span = self.last_span;
-                        let path = ident_to_path(ident_span, ident);
+                        let path = ast::Path::from_ident(ident_span, ident);
                         self.bump();
                         let delim = self.expect_open_delim()?;
                         let tts = self.parse_seq_to_end(
@@ -3847,12 +3849,14 @@ impl<'a> Parser<'a> {
         let name = self.parse_ident()?;
         self.expect(&token::Colon)?;
         let ty = self.parse_ty_sum()?;
-        Ok(spanned(lo, self.last_span.hi, ast::StructField_ {
-            kind: NamedField(name, pr),
+        Ok(StructField {
+            span: mk_sp(lo, self.last_span.hi),
+            ident: Some(name),
+            vis: pr,
             id: ast::DUMMY_NODE_ID,
             ty: ty,
             attrs: attrs,
-        }))
+        })
     }
 
     /// Emit an expected item after attributes error.
@@ -5116,7 +5120,7 @@ impl<'a> Parser<'a> {
 
             self.expect(&token::OpenDelim(token::Brace))?;
             self.expect(&token::CloseDelim(token::Brace))?;
-            Ok((ast_util::impl_pretty_name(&opt_trait, None),
+            Ok((special_idents::invalid,
              ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None))
         } else {
             if opt_trait.is_some() {
@@ -5132,7 +5136,7 @@ impl<'a> Parser<'a> {
                 impl_items.push(self.parse_impl_item()?);
             }
 
-            Ok((ast_util::impl_pretty_name(&opt_trait, Some(&ty)),
+            Ok((special_idents::invalid,
              ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items),
              Some(attrs)))
         }
@@ -5246,13 +5250,16 @@ impl<'a> Parser<'a> {
             |p| {
                 let attrs = p.parse_outer_attributes()?;
                 let lo = p.span.lo;
-                let struct_field_ = ast::StructField_ {
-                    kind: UnnamedField(p.parse_visibility()?),
+                let vis = p.parse_visibility()?;
+                let ty = p.parse_ty_sum()?;
+                Ok(StructField {
+                    span: mk_sp(lo, p.span.hi),
+                    vis: vis,
+                    ident: None,
                     id: ast::DUMMY_NODE_ID,
-                    ty: p.parse_ty_sum()?,
+                    ty: ty,
                     attrs: attrs,
-                };
-                Ok(spanned(lo, p.span.hi, struct_field_))
+                })
             })?;
 
         Ok(fields)
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index a8f28ed3d9e..e2b1d2f5e7a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1407,14 +1407,9 @@ impl<'a> State<'a> {
                 self.commasep(
                     Inconsistent, struct_def.fields(),
                     |s, field| {
-                        match field.node.kind {
-                            ast::NamedField(..) => panic!("unexpected named field"),
-                            ast::UnnamedField(ref vis) => {
-                                s.print_visibility(vis)?;
-                                s.maybe_print_comment(field.span.lo)?;
-                                s.print_type(&field.node.ty)
-                            }
-                        }
+                        s.print_visibility(&field.vis)?;
+                        s.maybe_print_comment(field.span.lo)?;
+                        s.print_type(&field.ty)
                     }
                 )?;
                 self.pclose()?;
@@ -1432,19 +1427,14 @@ impl<'a> State<'a> {
             self.hardbreak_if_not_bol()?;
 
             for field in struct_def.fields() {
-                match field.node.kind {
-                    ast::UnnamedField(..) => panic!("unexpected unnamed field"),
-                    ast::NamedField(ident, ref visibility) => {
-                        self.hardbreak_if_not_bol()?;
-                        self.maybe_print_comment(field.span.lo)?;
-                        self.print_outer_attributes(&field.node.attrs)?;
-                        self.print_visibility(visibility)?;
-                        self.print_ident(ident)?;
-                        self.word_nbsp(":")?;
-                        self.print_type(&field.node.ty)?;
-                        word(&mut self.s, ",")?;
-                    }
-                }
+                self.hardbreak_if_not_bol()?;
+                self.maybe_print_comment(field.span.lo)?;
+                self.print_outer_attributes(&field.attrs)?;
+                self.print_visibility(&field.vis)?;
+                self.print_ident(field.ident.unwrap())?;
+                self.word_nbsp(":")?;
+                self.print_type(&field.ty)?;
+                word(&mut self.s, ",")?;
             }
 
             self.bclose(span)
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 81b702e794d..703b1611540 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -18,7 +18,6 @@ use std::iter;
 use std::slice;
 use std::mem;
 use std::vec;
-use ast_util::*;
 use attr::AttrMetaMethods;
 use attr;
 use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
@@ -35,7 +34,7 @@ use fold;
 use parse::token::{intern, InternedString};
 use parse::{token, ParseSess};
 use print::pprust;
-use {ast, ast_util};
+use ast;
 use ptr::P;
 use util::small_vector::SmallVector;
 
@@ -120,8 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
         if ident.name != token::special_idents::invalid.name {
             self.cx.path.push(ident);
         }
-        debug!("current path: {}",
-               ast_util::path_name_i(&self.cx.path));
+        debug!("current path: {}", path_name_i(&self.cx.path));
 
         let i = if is_test_fn(&self.cx, &i) || is_bench_fn(&self.cx, &i) {
             match i.node {
@@ -349,7 +347,6 @@ enum HasTestSignature {
     NotEvenAFunction,
 }
 
-
 fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     let has_test_attr = attr::contains_name(&i.attrs, "test");
 
@@ -576,6 +573,11 @@ fn path_node(ids: Vec<ast::Ident> ) -> ast::Path {
     }
 }
 
+fn path_name_i(idents: &[ast::Ident]) -> String {
+    // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
+    idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
+}
+
 fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
     // The vector of test_descs for this crate
     let test_descs = mk_test_descs(cx);
@@ -645,10 +647,10 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     // creates $name: $expr
     let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
-    debug!("encoding {}", ast_util::path_name_i(&path[..]));
+    debug!("encoding {}", path_name_i(&path[..]));
 
     // path to the #[test] function: "foo::bar::baz"
-    let path_string = ast_util::path_name_i(&path[..]);
+    let path_string = path_name_i(&path[..]);
     let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..]));
 
     // self::test::StaticTestName($name_expr)
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 1251f9bfe13..839bbf4805d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -619,9 +619,9 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
                                              struct_field: &'v StructField) {
-    walk_opt_ident(visitor, struct_field.span, struct_field.node.ident());
-    visitor.visit_ty(&struct_field.node.ty);
-    walk_list!(visitor, visit_attribute, &struct_field.node.attrs);
+    walk_opt_ident(visitor, struct_field.span, struct_field.ident);
+    visitor.visit_ty(&struct_field.ty);
+    walk_list!(visitor, visit_attribute, &struct_field.attrs);
 }
 
 pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {