unit-test symbol-names and item-paths

This commit is contained in:
Niko Matsakis 2016-03-16 15:00:20 -04:00
parent 2291abf313
commit 977636156a
6 changed files with 146 additions and 0 deletions

View file

@ -85,6 +85,7 @@ use trans::machine::{llalign_of_min, llsize_of, llsize_of_real};
use trans::meth;
use trans::mir;
use trans::monomorphize::{self, Instance};
use trans::symbol_names_test;
use trans::tvec;
use trans::type_::Type;
use trans::type_of;
@ -2758,6 +2759,8 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
}
collector::print_collection_results(&ccx);
symbol_names_test::report_symbol_names(&ccx);
}
emit_link_guard_if_necessary(&shared_ccx);

View file

@ -60,6 +60,7 @@ mod meth;
mod mir;
mod monomorphize;
mod collector;
mod symbol_names_test;
mod tvec;
mod type_;
mod type_of;

View file

@ -0,0 +1,84 @@
// Copyright 2012-2015 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.
//! Walks the crate looking for items/impl-items/trait-items that have
//! either a `rustc_symbol_name` or `rustc_item_path` attribute and
//! generates an error giving, respectively, the symbol name or
//! item-path. This is used for unit testing the code that generates
//! paths etc in all kinds of annoying scenarios.
use back::symbol_names;
use rustc::middle::ty::TyCtxt;
use rustc_front::hir;
use rustc_front::intravisit::{self, Visitor};
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use trans::common::CrateContext;
const SYMBOL_NAME: &'static str = "rustc_symbol_name";
const ITEM_PATH: &'static str = "rustc_item_path";
pub fn report_symbol_names(ccx: &CrateContext) {
// if the `rustc_attrs` feature is not enabled, then the
// attributes we are interested in cannot be present anyway, so
// skip the walk.
let tcx = ccx.tcx();
if !tcx.sess.features.borrow().rustc_attrs {
return;
}
let _ignore = tcx.dep_graph.in_ignore();
let mut visitor = SymbolNamesTest { ccx: ccx, tcx: tcx };
tcx.map.krate().visit_all_items(&mut visitor);
}
struct SymbolNamesTest<'a, 'tcx:'a> {
ccx: &'a CrateContext<'a, 'tcx>,
tcx: &'a TyCtxt<'tcx>,
}
impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
fn process_attrs(&mut self,
node_id: ast::NodeId) {
let def_id = self.tcx.map.local_def_id(node_id);
for attr in self.tcx.get_attrs(def_id).iter() {
if attr.check_name(SYMBOL_NAME) {
// for now, just monomorphic names
let name = symbol_names::exported_name(self.ccx, def_id, &[]);
self.tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
} else if attr.check_name(ITEM_PATH) {
let path = self.tcx.item_path_str(def_id);
self.tcx.sess.span_err(attr.span, &format!("item-path({})", path));
}
// (*) The formatting of `tag({})` is chosen so that tests can elect
// to test the entirety of the string, if they choose, or else just
// some subset.
}
}
}
impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) {
self.process_attrs(item.id);
intravisit::walk_item(self, item);
}
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
self.process_attrs(ti.id);
intravisit::walk_trait_item(self, ti)
}
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
self.process_attrs(ii.id);
intravisit::walk_impl_item(self, ii)
}
}

View file

@ -349,6 +349,10 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
"the `#[rustc_if_this_changed]` attribute \
is just used for rustc unit tests \
and will never be stable")),
("rustc_symbol_name", Whitelisted, Gated("rustc_attrs",
"internal rustc attributes will never be stable")),
("rustc_item_path", Whitelisted, Gated("rustc_attrs",
"internal rustc attributes will never be stable")),
("rustc_move_fragments", Normal, Gated("rustc_attrs",
"the `#[rustc_move_fragments]` attribute \
is just used for rustc unit tests \
@ -579,6 +583,7 @@ pub struct Features {
pub const_indexing: bool,
pub static_recursion: bool,
pub default_type_parameter_fallback: bool,
pub rustc_attrs: bool,
pub type_macros: bool,
pub cfg_target_feature: bool,
pub cfg_target_vendor: bool,
@ -614,6 +619,7 @@ impl Features {
const_indexing: false,
static_recursion: false,
default_type_parameter_fallback: false,
rustc_attrs: false,
type_macros: false,
cfg_target_feature: false,
cfg_target_vendor: false,
@ -1225,6 +1231,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
const_indexing: cx.has_feature("const_indexing"),
static_recursion: cx.has_feature("static_recursion"),
default_type_parameter_fallback: cx.has_feature("default_type_parameter_fallback"),
rustc_attrs: cx.has_feature("rustc_attrs"),
type_macros: cx.has_feature("type_macros"),
cfg_target_feature: cx.has_feature("cfg_target_feature"),
cfg_target_vendor: cx.has_feature("cfg_target_vendor"),

View file

@ -0,0 +1,16 @@
// Copyright 2012-2015 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.
#![feature(rustc_attrs)]
#[rustc_symbol_name] //~ ERROR _ZN5basic4main
#[rustc_item_path] //~ ERROR item-path(main)
fn main() {
}

View file

@ -0,0 +1,35 @@
// Copyright 2012-2015 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.
#![feature(rustc_attrs)]
#![allow(dead_code)]
mod foo {
pub struct Foo { x: u32 }
impl Foo {
#[rustc_symbol_name] //~ ERROR _ZN5impl13foo3Foo3bar
#[rustc_item_path] //~ ERROR item-path(foo::Foo::bar)
fn bar() { }
}
}
mod bar {
use foo::Foo;
impl Foo {
#[rustc_symbol_name] //~ ERROR _ZN5impl13bar26_$LT$impl$u20$foo..Foo$GT$3baz
#[rustc_item_path] //~ ERROR item-path(bar::<impl foo::Foo>::baz)
fn baz() { }
}
}
fn main() {
}