Improve linkage assignment in trans::partitioning.
This commit is contained in:
parent
65e8a13441
commit
6c8c94b848
@ -2548,8 +2548,8 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
|
||||
///
|
||||
/// This list is later used by linkers to determine the set of symbols needed to
|
||||
/// be exposed from a dynamic library and it's also encoded into the metadata.
|
||||
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
|
||||
scx.reachable().iter().map(|x| *x).filter(|&id| {
|
||||
pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
|
||||
reachable.into_iter().filter(|&id| {
|
||||
// Next, we want to ignore some FFI functions that are not exposed from
|
||||
// this crate. Reachable FFI functions can be lumped into two
|
||||
// categories:
|
||||
@ -2563,9 +2563,9 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
|
||||
//
|
||||
// As a result, if this id is an FFI item (foreign item) then we only
|
||||
// let it through if it's included statically.
|
||||
match scx.tcx().map.get(id) {
|
||||
match tcx.map.get(id) {
|
||||
hir_map::NodeForeignItem(..) => {
|
||||
scx.sess().cstore.is_statically_included_foreign_item(id)
|
||||
tcx.sess.cstore.is_statically_included_foreign_item(id)
|
||||
}
|
||||
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
@ -2575,8 +2575,8 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
|
||||
node: hir::ItemFn(..), .. }) |
|
||||
hir_map::NodeImplItem(&hir::ImplItem {
|
||||
node: hir::ImplItemKind::Method(..), .. }) => {
|
||||
let def_id = scx.tcx().map.local_def_id(id);
|
||||
let scheme = scx.tcx().lookup_item_type(def_id);
|
||||
let def_id = tcx.map.local_def_id(id);
|
||||
let scheme = tcx.lookup_item_type(def_id);
|
||||
scheme.generics.types.is_empty()
|
||||
}
|
||||
|
||||
@ -2598,6 +2598,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let krate = tcx.map.krate();
|
||||
|
||||
let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
|
||||
let reachable = filter_reachable_ids(tcx, reachable);
|
||||
|
||||
let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
|
||||
v
|
||||
@ -2621,12 +2622,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reachable,
|
||||
check_overflow,
|
||||
check_dropflag);
|
||||
|
||||
let reachable_symbol_ids = filter_reachable_ids(&shared_ccx);
|
||||
|
||||
// Translate the metadata.
|
||||
let metadata = time(tcx.sess.time_passes(), "write metadata", || {
|
||||
write_metadata(&shared_ccx, &reachable_symbol_ids)
|
||||
write_metadata(&shared_ccx, shared_ccx.reachable())
|
||||
});
|
||||
|
||||
let metadata_module = ModuleTranslation {
|
||||
@ -2755,7 +2753,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
let sess = shared_ccx.sess();
|
||||
let mut reachable_symbols = reachable_symbol_ids.iter().map(|&id| {
|
||||
let mut reachable_symbols = shared_ccx.reachable().iter().map(|&id| {
|
||||
let def_id = shared_ccx.tcx().map.local_def_id(id);
|
||||
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
|
||||
}).collect::<Vec<_>>();
|
||||
@ -2911,7 +2909,8 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
|
||||
partitioning::partition(scx.tcx(),
|
||||
items.iter().cloned(),
|
||||
strategy,
|
||||
&inlining_map)
|
||||
&inlining_map,
|
||||
scx.reachable())
|
||||
});
|
||||
|
||||
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
|
||||
|
@ -126,7 +126,7 @@ use rustc::ty::TyCtxt;
|
||||
use rustc::ty::item_path::characteristic_def_id_of_type;
|
||||
use syntax::parse::token::{self, InternedString};
|
||||
use trans_item::TransItem;
|
||||
use util::nodemap::{FnvHashMap, FnvHashSet};
|
||||
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
|
||||
|
||||
pub struct CodegenUnit<'tcx> {
|
||||
pub name: InternedString,
|
||||
@ -147,14 +147,23 @@ const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
|
||||
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trans_items: I,
|
||||
strategy: PartitioningStrategy,
|
||||
inlining_map: &InliningMap<'tcx>)
|
||||
inlining_map: &InliningMap<'tcx>,
|
||||
reachable: &NodeSet)
|
||||
-> Vec<CodegenUnit<'tcx>>
|
||||
where I: Iterator<Item = TransItem<'tcx>>
|
||||
{
|
||||
if let PartitioningStrategy::FixedUnitCount(1) = strategy {
|
||||
// If there is only a single codegen-unit, we can use a very simple
|
||||
// scheme and don't have to bother with doing much analysis.
|
||||
return vec![single_codegen_unit(tcx, trans_items, reachable)];
|
||||
}
|
||||
|
||||
// In the first step, we place all regular translation items into their
|
||||
// respective 'home' codegen unit. Regular translation items are all
|
||||
// functions and statics defined in the local crate.
|
||||
let mut initial_partitioning = place_root_translation_items(tcx, trans_items);
|
||||
let mut initial_partitioning = place_root_translation_items(tcx,
|
||||
trans_items,
|
||||
reachable);
|
||||
|
||||
// If the partitioning should produce a fixed count of codegen units, merge
|
||||
// until that count is reached.
|
||||
@ -179,7 +188,8 @@ struct PreInliningPartitioning<'tcx> {
|
||||
struct PostInliningPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);
|
||||
|
||||
fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trans_items: I)
|
||||
trans_items: I,
|
||||
_reachable: &NodeSet)
|
||||
-> PreInliningPartitioning<'tcx>
|
||||
where I: Iterator<Item = TransItem<'tcx>>
|
||||
{
|
||||
@ -219,7 +229,18 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
TransItem::Static(..) => llvm::ExternalLinkage,
|
||||
TransItem::DropGlue(..) => unreachable!(),
|
||||
// Is there any benefit to using ExternalLinkage?:
|
||||
TransItem::Fn(..) => llvm::WeakODRLinkage,
|
||||
TransItem::Fn(ref instance) => {
|
||||
if instance.substs.types.is_empty() {
|
||||
// This is a non-generic functions, we always
|
||||
// make it visible externally on the chance that
|
||||
// it might be used in another codegen unit.
|
||||
llvm::ExternalLinkage
|
||||
} else {
|
||||
// Monomorphizations of generic functions are
|
||||
// always weak-odr
|
||||
llvm::WeakODRLinkage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -282,13 +303,6 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
|
||||
items: FnvHashMap()
|
||||
});
|
||||
}
|
||||
|
||||
fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
|
||||
token::intern_and_get_ident(&format!("{}{}{}",
|
||||
crate_name,
|
||||
NUMBERED_CODEGEN_UNIT_MARKER,
|
||||
index)[..])
|
||||
}
|
||||
}
|
||||
|
||||
fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartitioning<'tcx>,
|
||||
@ -319,6 +333,11 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
|
||||
// so we just add it here with AvailableExternallyLinkage
|
||||
new_codegen_unit.items.insert(trans_item,
|
||||
llvm::AvailableExternallyLinkage);
|
||||
} else if trans_item.is_from_extern_crate() && !trans_item.is_generic_fn() {
|
||||
// An instantiation of this item is always available in the
|
||||
// crate it was imported from.
|
||||
new_codegen_unit.items.insert(trans_item,
|
||||
llvm::AvailableExternallyLinkage);
|
||||
} else {
|
||||
// We can't be sure if this will also be instantiated
|
||||
// somewhere else, so we add an instance here with
|
||||
@ -414,3 +433,54 @@ fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
return token::intern_and_get_ident(&mod_path[..]);
|
||||
}
|
||||
|
||||
fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trans_items: I,
|
||||
reachable: &NodeSet)
|
||||
-> CodegenUnit<'tcx>
|
||||
where I: Iterator<Item = TransItem<'tcx>>
|
||||
{
|
||||
let mut items = FnvHashMap();
|
||||
|
||||
for trans_item in trans_items {
|
||||
let linkage = trans_item.explicit_linkage(tcx).unwrap_or_else(|| {
|
||||
match trans_item {
|
||||
TransItem::Static(node_id) => {
|
||||
if reachable.contains(&node_id) {
|
||||
llvm::ExternalLinkage
|
||||
} else {
|
||||
llvm::InternalLinkage
|
||||
}
|
||||
}
|
||||
TransItem::DropGlue(_) => {
|
||||
llvm::InternalLinkage
|
||||
}
|
||||
TransItem::Fn(instance) => {
|
||||
if trans_item.is_generic_fn() ||
|
||||
trans_item.is_from_extern_crate() ||
|
||||
!reachable.contains(&tcx.map
|
||||
.as_local_node_id(instance.def)
|
||||
.unwrap()) {
|
||||
llvm::InternalLinkage
|
||||
} else {
|
||||
llvm::ExternalLinkage
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
items.insert(trans_item, linkage);
|
||||
}
|
||||
|
||||
CodegenUnit {
|
||||
name: numbered_codegen_unit_name(&tcx.crate_name[..], 0),
|
||||
items: items
|
||||
}
|
||||
}
|
||||
|
||||
fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
|
||||
token::intern_and_get_ident(&format!("{}{}{}",
|
||||
crate_name,
|
||||
NUMBERED_CODEGEN_UNIT_MARKER,
|
||||
index)[..])
|
||||
}
|
||||
|
@ -184,6 +184,14 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_generic_fn(&self) -> bool {
|
||||
match *self {
|
||||
TransItem::Fn(ref instance) => !instance.substs.types.is_empty(),
|
||||
TransItem::DropGlue(..) |
|
||||
TransItem::Static(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<llvm::Linkage> {
|
||||
let def_id = match *self {
|
||||
TransItem::Fn(ref instance) => instance.def,
|
||||
|
@ -25,7 +25,7 @@ extern crate cgu_extern_drop_glue;
|
||||
|
||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||
|
||||
//~ TRANS_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
|
||||
fn user()
|
||||
{
|
||||
//~ TRANS_ITEM drop-glue extern_drop_glue::LocalStruct[0] @@ extern_drop_glue[OnceODR]
|
||||
@ -37,7 +37,7 @@ mod mod1 {
|
||||
|
||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||
|
||||
//~ TRANS_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
|
||||
fn user()
|
||||
{
|
||||
//~ TRANS_ITEM drop-glue extern_drop_glue::mod1[0]::LocalStruct[0] @@ extern_drop_glue-mod1[OnceODR]
|
||||
|
@ -19,7 +19,7 @@
|
||||
// aux-build:cgu_generic_function.rs
|
||||
extern crate cgu_generic_function;
|
||||
|
||||
//~ TRANS_ITEM fn extern_generic::user[0] @@ extern_generic[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_generic::user[0] @@ extern_generic[External]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
@ -27,7 +27,7 @@ fn user() {
|
||||
mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ TRANS_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[External]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
@ -35,7 +35,7 @@ mod mod1 {
|
||||
mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ TRANS_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[External]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
@ -45,14 +45,14 @@ mod mod1 {
|
||||
mod mod2 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ TRANS_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[External]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
}
|
||||
|
||||
mod mod3 {
|
||||
//~ TRANS_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[WeakODR]
|
||||
//~ TRANS_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[External]
|
||||
fn non_user() {}
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,10 @@ extern crate cgu_explicit_inlining;
|
||||
// This test makes sure that items inlined from external crates are privately
|
||||
// instantiated in every codegen unit they are used in.
|
||||
|
||||
//~ TRANS_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[OnceODR] inlining_from_extern_crate-mod1[OnceODR]
|
||||
//~ TRANS_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[OnceODR] inlining_from_extern_crate-mod2[OnceODR]
|
||||
//~ TRANS_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[Available] inlining_from_extern_crate-mod1[Available]
|
||||
//~ TRANS_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[Available] inlining_from_extern_crate-mod2[Available]
|
||||
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::user[0] @@ inlining_from_extern_crate[WeakODR]
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::user[0] @@ inlining_from_extern_crate[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::inlined();
|
||||
@ -37,7 +37,7 @@ pub fn user()
|
||||
mod mod1 {
|
||||
use cgu_explicit_inlining;
|
||||
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::inlined();
|
||||
@ -50,7 +50,7 @@ mod mod1 {
|
||||
mod mod2 {
|
||||
use cgu_explicit_inlining;
|
||||
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::mod2[0]::user[0] @@ inlining_from_extern_crate-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn inlining_from_extern_crate::mod2[0]::user[0] @@ inlining_from_extern_crate-mod2[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::always_inlined();
|
||||
|
@ -23,7 +23,7 @@ struct Struct {
|
||||
}
|
||||
|
||||
impl Drop for Struct {
|
||||
//~ TRANS_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[WeakODR]
|
||||
//~ TRANS_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[External]
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ struct Outer {
|
||||
_a: Struct
|
||||
}
|
||||
|
||||
//~ TRANS_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[WeakODR]
|
||||
//~ TRANS_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
|
||||
fn user()
|
||||
{
|
||||
let _ = Outer {
|
||||
@ -53,7 +53,7 @@ mod mod1
|
||||
_b: (u32, Struct),
|
||||
}
|
||||
|
||||
//~ TRANS_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
|
||||
fn user()
|
||||
{
|
||||
let _ = Struct2 {
|
||||
|
@ -25,7 +25,7 @@
|
||||
//~ TRANS_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[WeakODR]
|
||||
pub fn generic<T>(x: T) -> T { x }
|
||||
|
||||
//~ TRANS_ITEM fn local_generic::user[0] @@ local_generic[WeakODR]
|
||||
//~ TRANS_ITEM fn local_generic::user[0] @@ local_generic[External]
|
||||
fn user() {
|
||||
let _ = generic(0u32);
|
||||
}
|
||||
@ -33,7 +33,7 @@ fn user() {
|
||||
mod mod1 {
|
||||
pub use super::generic;
|
||||
|
||||
//~ TRANS_ITEM fn local_generic::mod1[0]::user[0] @@ local_generic-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn local_generic::mod1[0]::user[0] @@ local_generic-mod1[External]
|
||||
fn user() {
|
||||
let _ = generic(0u64);
|
||||
}
|
||||
@ -41,7 +41,7 @@ mod mod1 {
|
||||
mod mod1 {
|
||||
use super::generic;
|
||||
|
||||
//~ TRANS_ITEM fn local_generic::mod1[0]::mod1[0]::user[0] @@ local_generic-mod1-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn local_generic::mod1[0]::mod1[0]::user[0] @@ local_generic-mod1-mod1[External]
|
||||
fn user() {
|
||||
let _ = generic('c');
|
||||
}
|
||||
@ -51,7 +51,7 @@ mod mod1 {
|
||||
mod mod2 {
|
||||
use super::generic;
|
||||
|
||||
//~ TRANS_ITEM fn local_generic::mod2[0]::user[0] @@ local_generic-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn local_generic::mod2[0]::user[0] @@ local_generic-mod2[External]
|
||||
fn user() {
|
||||
let _ = generic("abc");
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
mod inline {
|
||||
|
||||
// Important: This function should show up in all codegen units where it is inlined
|
||||
//~ TRANS_ITEM fn local_inlining::inline[0]::inlined_function[0] @@ local_inlining-inline[WeakODR] local_inlining-user1[Available] local_inlining-user2[Available]
|
||||
//~ TRANS_ITEM fn local_inlining::inline[0]::inlined_function[0] @@ local_inlining-inline[External] local_inlining-user1[Available] local_inlining-user2[Available]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function()
|
||||
{
|
||||
@ -30,7 +30,7 @@ mod inline {
|
||||
mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ TRANS_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[WeakODR]
|
||||
//~ TRANS_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[External]
|
||||
fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
@ -39,7 +39,7 @@ mod user1 {
|
||||
mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ TRANS_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[WeakODR]
|
||||
//~ TRANS_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[External]
|
||||
fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
@ -47,7 +47,7 @@ mod user2 {
|
||||
|
||||
mod non_user {
|
||||
|
||||
//~ TRANS_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[WeakODR]
|
||||
//~ TRANS_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[External]
|
||||
fn baz() {
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
mod inline {
|
||||
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::inline[0]::inlined_function[0] @@ local_transitive_inlining-inline[WeakODR] local_transitive_inlining-direct_user[Available] local_transitive_inlining-indirect_user[Available]
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::inline[0]::inlined_function[0] @@ local_transitive_inlining-inline[External] local_transitive_inlining-direct_user[Available] local_transitive_inlining-indirect_user[Available]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function()
|
||||
{
|
||||
@ -29,7 +29,7 @@ mod inline {
|
||||
mod direct_user {
|
||||
use super::inline;
|
||||
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::direct_user[0]::foo[0] @@ local_transitive_inlining-direct_user[WeakODR] local_transitive_inlining-indirect_user[Available]
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::direct_user[0]::foo[0] @@ local_transitive_inlining-direct_user[External] local_transitive_inlining-indirect_user[Available]
|
||||
#[inline(always)]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
@ -39,7 +39,7 @@ mod direct_user {
|
||||
mod indirect_user {
|
||||
use super::direct_user;
|
||||
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[WeakODR]
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[External]
|
||||
fn bar() {
|
||||
direct_user::foo();
|
||||
}
|
||||
@ -47,7 +47,7 @@ mod indirect_user {
|
||||
|
||||
mod non_user {
|
||||
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[WeakODR]
|
||||
//~ TRANS_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[External]
|
||||
fn baz() {
|
||||
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ mod mod1 {
|
||||
// Even though the impl is in `mod1`, the methods should end up in the
|
||||
// parent module, since that is where their self-type is.
|
||||
impl SomeType {
|
||||
//~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::method[0] @@ methods_are_with_self_type[WeakODR]
|
||||
//~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::method[0] @@ methods_are_with_self_type[External]
|
||||
fn method(&self) {}
|
||||
|
||||
//~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::associated_fn[0] @@ methods_are_with_self_type[WeakODR]
|
||||
//~ TRANS_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::associated_fn[0] @@ methods_are_with_self_type[External]
|
||||
fn associated_fn() {}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,10 @@
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
//~ TRANS_ITEM fn regular_modules::foo[0] @@ regular_modules[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::foo[0] @@ regular_modules[External]
|
||||
fn foo() {}
|
||||
|
||||
//~ TRANS_ITEM fn regular_modules::bar[0] @@ regular_modules[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::bar[0] @@ regular_modules[External]
|
||||
fn bar() {}
|
||||
|
||||
//~ TRANS_ITEM static regular_modules::BAZ[0] @@ regular_modules[External]
|
||||
@ -27,26 +27,26 @@ static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::foo[0] @@ regular_modules-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::foo[0] @@ regular_modules-mod1[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::bar[0] @@ regular_modules-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::bar[0] @@ regular_modules-mod1[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod1[0]::BAZ[0] @@ regular_modules-mod1[External]
|
||||
static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod1[0]::foo[0] @@ regular_modules-mod1-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod1[0]::foo[0] @@ regular_modules-mod1-mod1[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod1[0]::bar[0] @@ regular_modules-mod1-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod1[0]::bar[0] @@ regular_modules-mod1-mod1[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod1[0]::mod1[0]::BAZ[0] @@ regular_modules-mod1-mod1[External]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod2[0]::foo[0] @@ regular_modules-mod1-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod2[0]::foo[0] @@ regular_modules-mod1-mod2[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod2[0]::bar[0] @@ regular_modules-mod1-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod1[0]::mod2[0]::bar[0] @@ regular_modules-mod1-mod2[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod1[0]::mod2[0]::BAZ[0] @@ regular_modules-mod1-mod2[External]
|
||||
static BAZ: u64 = 0;
|
||||
@ -55,26 +55,26 @@ mod mod1 {
|
||||
|
||||
mod mod2 {
|
||||
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::foo[0] @@ regular_modules-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::foo[0] @@ regular_modules-mod2[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::bar[0] @@ regular_modules-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::bar[0] @@ regular_modules-mod2[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod2[0]::BAZ[0] @@ regular_modules-mod2[External]
|
||||
static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod1[0]::foo[0] @@ regular_modules-mod2-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod1[0]::foo[0] @@ regular_modules-mod2-mod1[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod1[0]::bar[0] @@ regular_modules-mod2-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod1[0]::bar[0] @@ regular_modules-mod2-mod1[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod2[0]::mod1[0]::BAZ[0] @@ regular_modules-mod2-mod1[External]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod2[0]::foo[0] @@ regular_modules-mod2-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod2[0]::foo[0] @@ regular_modules-mod2-mod2[External]
|
||||
fn foo() {}
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod2[0]::bar[0] @@ regular_modules-mod2-mod2[WeakODR]
|
||||
//~ TRANS_ITEM fn regular_modules::mod2[0]::mod2[0]::bar[0] @@ regular_modules-mod2-mod2[External]
|
||||
fn bar() {}
|
||||
//~ TRANS_ITEM static regular_modules::mod2[0]::mod2[0]::BAZ[0] @@ regular_modules-mod2-mod2[External]
|
||||
static BAZ: u64 = 0;
|
||||
|
@ -21,7 +21,7 @@ static FOO: u32 = 0;
|
||||
//~ TRANS_ITEM static statics::BAR[0] @@ statics[External]
|
||||
static BAR: u32 = 0;
|
||||
|
||||
//~ TRANS_ITEM fn statics::function[0] @@ statics[WeakODR]
|
||||
//~ TRANS_ITEM fn statics::function[0] @@ statics[External]
|
||||
fn function() {
|
||||
//~ TRANS_ITEM static statics::function[0]::FOO[0] @@ statics[External]
|
||||
static FOO: u32 = 0;
|
||||
@ -37,7 +37,7 @@ mod mod1 {
|
||||
//~ TRANS_ITEM static statics::mod1[0]::BAR[0] @@ statics-mod1[External]
|
||||
static BAR: u32 = 0;
|
||||
|
||||
//~ TRANS_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[WeakODR]
|
||||
//~ TRANS_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[External]
|
||||
fn function() {
|
||||
//~ TRANS_ITEM static statics::mod1[0]::function[0]::FOO[0] @@ statics-mod1[External]
|
||||
static FOO: u32 = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user