Skip to content

Commit

Permalink
rustc: Move some attr methods to queries
Browse files Browse the repository at this point in the history
Otherwise we may emit double errors related to the `#[export_name]` attribute,
for example, and using a query should ensure that it's only emitted at most
once.
  • Loading branch information
alexcrichton committed Sep 17, 2017
1 parent 132bde7 commit 8821aff
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 58 deletions.
2 changes: 2 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,8 @@ define_dep_nodes!( <'tcx>
[] AllCrateNums,
[] ExportedSymbols,
[] CollectAndPartitionTranslationItems,
[] ExportName(DefId),
[] ContainsExternIndicator(DefId),
);

trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
} else {
false
};
let is_extern = attr::contains_extern_indicator(&self.tcx.sess.diagnostic(),
&item.attrs);
let def_id = self.tcx.hir.local_def_id(item.id);
let is_extern = self.tcx.contains_extern_indicator(def_id);
if reachable || is_extern {
self.reachable_symbols.insert(search_item);
}
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/middle/trans.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
// Copyright 2017 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 syntax::ast::NodeId;
use syntax::symbol::InternedString;
use ty::Instance;
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,8 @@ define_maps! { <'tcx>
[] fn collect_and_partition_translation_items:
collect_and_partition_translation_items_node(CrateNum)
-> (Arc<FxHashSet<TransItem<'tcx>>>, Vec<Arc<CodegenUnit<'tcx>>>),
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
}

fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
Expand Down
8 changes: 2 additions & 6 deletions src/librustc_trans/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use rustc::ty::TyCtxt;
use rustc_allocator::ALLOCATOR_METHODS;
use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel};
use rustc::middle::exported_symbols::is_below_threshold;
use syntax::attr;

pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ExportedSymbols {
let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow());
Expand Down Expand Up @@ -137,11 +136,8 @@ pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ExportedSymbols {

return ExportedSymbols::new(export_threshold, exports, local_exports);

fn export_level(tcx: TyCtxt,
sym_def_id: DefId)
-> SymbolExportLevel {
let attrs = tcx.get_attrs(sym_def_id);
if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) {
fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel {
if tcx.contains_extern_indicator(sym_def_id) {
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
Expand Down
26 changes: 25 additions & 1 deletion src/librustc_trans/back/symbol_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ pub fn provide(providers: &mut Providers) {
*providers = Providers {
def_symbol_name,
symbol_name,

export_name: |tcx, id| {
tcx.get_attrs(id).iter().fold(None, |ia, attr| {
if attr.check_name("export_name") {
if let s @ Some(_) = attr.value_str() {
s
} else {
struct_span_err!(tcx.sess, attr.span, E0558,
"export_name attribute has invalid format")
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
.emit();
None
}
} else {
ia
}
})
},

contains_extern_indicator: |tcx, id| {
attr::contains_name(&tcx.get_attrs(id), "no_mangle") ||
tcx.export_name(id).is_some()
},

..*providers
};
}
Expand Down Expand Up @@ -245,7 +269,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
return tcx.item_name(def_id).to_string();
}

if let Some(name) = attr::find_export_name_attr(tcx.sess.diagnostic(), &attrs) {
if let Some(name) = tcx.export_name(def_id) {
// Use provided name
return name.to_string();
}
Expand Down
24 changes: 24 additions & 0 deletions src/librustc_trans/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,28 @@ extern "platform-intrinsic" {
unsafe { simd_add(i32x1(0), i32x1(1)); } // ok!
```
"##,

E0558: r##"
The `export_name` attribute was malformed.
Erroneous code example:
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}
fn main() {}
```
The `export_name` attribute expects a string in order to determine the name of
the exported symbol. Example:
```
#[export_name = "some_function"] // ok!
pub fn something() {}
fn main() {}
```
"##,

}
4 changes: 2 additions & 2 deletions src/librustc_trans/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
use rustc::ty::maps::Providers;
use rustc::util::nodemap::{FxHashSet, FxHashMap};

mod diagnostics;

pub mod back {
mod archive;
mod command;
Expand All @@ -88,8 +90,6 @@ pub mod back {
mod rpath;
}

mod diagnostics;

mod abi;
mod adt;
mod allocator;
Expand Down
24 changes: 0 additions & 24 deletions src/libsyntax/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,30 +506,6 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
first_attr_value_str_by_name(attrs, "crate_name")
}

/// Find the value of #[export_name=*] attribute and check its validity.
pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Symbol> {
attrs.iter().fold(None, |ia,attr| {
if attr.check_name("export_name") {
if let s@Some(_) = attr.value_str() {
s
} else {
struct_span_err!(diag, attr.span, E0558,
"export_name attribute has invalid format")
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
.emit();
None
}
} else {
ia
}
})
}

pub fn contains_extern_indicator(diag: &Handler, attrs: &[Attribute]) -> bool {
contains_name(attrs, "no_mangle") ||
find_export_name_attr(diag, attrs).is_some()
}

#[derive(Copy, Clone, PartialEq)]
pub enum InlineAttr {
None,
Expand Down
23 changes: 0 additions & 23 deletions src/libsyntax/diagnostic_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,29 +219,6 @@ Erroneous code example:
Delete the offending feature attribute.
"##,

E0558: r##"
The `export_name` attribute was malformed.
Erroneous code example:
```compile_fail,E0558
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}
fn main() {}
```
The `export_name` attribute expects a string in order to determine the name of
the exported symbol. Example:
```
#[export_name = "some_function"] // ok!
pub fn something() {}
fn main() {}
```
"##,

E0565: r##"
A literal was used in an attribute that doesn't support literals.
Expand Down

0 comments on commit 8821aff

Please sign in to comment.