Auto merge of #45575 - michaelwoerister:tweak-inline-trans-items, r=nikomatsakis

Only instantiate inline- and const-fns if they are referenced (again).

It seems that we have regressed on not translating `#[inline]` functions unless they are actually used. This should bring back this optimization. I also added a regression test this time so it doesn't happen again accidentally.

Fixes #40392.

r? @alexcrichton

UPDATE & PSA
---------------------
This patch **makes translation very lazy** -- in general this is a good thing (we don't want the compiler to do unnecessary work) but it has two consequences:
1. Some error messages are only generated when an item is actually translated. Consequently, this patch will lead to more cases where the compiler will only start emitting errors when the erroneous function is actually used. This has always been true to some extend (e.g. when passing generic values to an intrinsic) but since this is something user-facing it's worth mentioning.
2. When writing tests, one has to make sure that the functions in question are actually generated. In other words, it must not be dead code. This can usually  be achieved by either
    1. making sure the function is exported from the resulting binary or
    2. by making sure the function is called from something that is exported (or `main()`).

Note that it depends on the crate type what functions are exported:
   1. For rlibs and dylibs everything that is reachable from the outside is exported.
   2. For executables, cdylibs, and staticlibs, items are only exported if they are additionally `#[no_mangle]` or have an `#[export_name]`.

The commits in this PR contain many examples of how tests can be updated to comply to the new requirements.
This commit is contained in:
bors 2017-11-08 12:23:34 +00:00
commit 4bb96f6519
54 changed files with 518 additions and 405 deletions

View file

@ -328,7 +328,12 @@ impl DepGraph {
}
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
self.fingerprints.borrow()[dep_node]
match self.fingerprints.borrow().get(dep_node) {
Some(&fingerprint) => fingerprint,
None => {
bug!("Could not find current fingerprint for {:?}", dep_node)
}
}
}
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {

View file

@ -211,6 +211,8 @@ use trans_item::{TransItemExt, DefPathBasedNames, InstantiationMode};
use rustc_data_structures::bitvec::BitVector;
use syntax::attr;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum TransItemCollectionMode {
Eager,
@ -324,9 +326,14 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut roots = Vec::new();
{
let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _)| {
tcx.hir.local_def_id(node_id)
});
let mut visitor = RootCollector {
tcx,
mode,
entry_fn,
output: &mut roots,
};
@ -875,6 +882,7 @@ struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mode: TransItemCollectionMode,
output: &'b mut Vec<TransItem<'tcx>>,
entry_fn: Option<DefId>,
}
impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
@ -932,10 +940,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
let tcx = self.tcx;
let def_id = tcx.hir.local_def_id(item.id);
if (self.mode == TransItemCollectionMode::Eager ||
!tcx.is_const_fn(def_id) || tcx.is_exported_symbol(def_id)) &&
!item_has_type_parameters(tcx, def_id) {
if self.is_root(def_id) {
debug!("RootCollector: ItemFn({})",
def_id_to_string(tcx, def_id));
@ -957,10 +962,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
let tcx = self.tcx;
let def_id = tcx.hir.local_def_id(ii.id);
if (self.mode == TransItemCollectionMode::Eager ||
!tcx.is_const_fn(def_id) ||
tcx.is_exported_symbol(def_id)) &&
!item_has_type_parameters(tcx, def_id) {
if self.is_root(def_id) {
debug!("RootCollector: MethodImplItem({})",
def_id_to_string(tcx, def_id));
@ -973,6 +975,22 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
}
}
impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
fn is_root(&self, def_id: DefId) -> bool {
!item_has_type_parameters(self.tcx, def_id) && match self.mode {
TransItemCollectionMode::Eager => {
true
}
TransItemCollectionMode::Lazy => {
self.entry_fn == Some(def_id) ||
self.tcx.is_exported_symbol(def_id) ||
attr::contains_name(&self.tcx.get_attrs(def_id),
"rustc_std_internal_symbol")
}
}
}
}
fn item_has_type_parameters<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
let generics = tcx.generics_of(def_id);
generics.parent_types as usize + generics.types.len() > 0

View file

@ -51,7 +51,8 @@ pub fn requests_inline<'a, 'tcx>(
// available to normal end-users.
return true
}
attr::requests_inline(&instance.def.attrs(tcx)[..])
attr::requests_inline(&instance.def.attrs(tcx)[..]) ||
tcx.is_const_fn(instance.def.def_id())
}
pub fn is_inline_instance<'a, 'tcx>(

View file

@ -40,14 +40,12 @@ extern crate rustc_data_structures;
extern crate syntax;
extern crate syntax_pos;
use rustc::ty::TyCtxt;
use rustc::ty::{TyCtxt, Instance};
use rustc::hir;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir::map as hir_map;
use rustc::util::nodemap::NodeSet;
use syntax::attr;
pub mod common;
pub mod link;
pub mod collector;
@ -77,7 +75,7 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
///
/// 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 find_exported_symbols(tcx: TyCtxt) -> NodeSet {
pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().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
@ -107,11 +105,10 @@ pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet {
node: hir::ImplItemKind::Method(..), .. }) => {
let def_id = tcx.hir.local_def_id(id);
let generics = tcx.generics_of(def_id);
let attributes = tcx.get_attrs(def_id);
(generics.parent_types == 0 && generics.types.is_empty()) &&
// Functions marked with #[inline] are only ever translated
// with "internal" linkage and are never exported.
!attr::requests_inline(&attributes)
!common::requests_inline(tcx, &Instance::mono(tcx, def_id))
}
_ => false

View file

@ -0,0 +1,22 @@
// 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.
// ignore-tidy-linelength
// compile-flags:-Zprint-trans-items=lazy
// NB: We do not expect *any* translation item to be generated here.
#![feature(const_fn)]
#![deny(dead_code)]
#![crate_type = "rlib"]
pub const fn foo(x: u32) -> u32 {
x + 0xf00
}

View file

@ -0,0 +1,23 @@
// 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.
// ignore-tidy-linelength
// compile-flags:-Zprint-trans-items=lazy
// NB: We do not expect *any* translation item to be generated here.
#![deny(dead_code)]
#![crate_type = "rlib"]
#[inline]
pub fn foo() -> bool {
[1, 2] == [3, 4]
}

View file

@ -16,7 +16,7 @@
// compile-flags:-Zinline-in-all-cgus
#![allow(dead_code)]
#![crate_type="lib"]
#![crate_type="rlib"]
// aux-build:cgu_extern_drop_glue.rs
extern crate cgu_extern_drop_glue;
@ -25,20 +25,20 @@ extern crate cgu_extern_drop_glue;
struct LocalStruct(cgu_extern_drop_glue::Struct);
//~ TRANS_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[Internal]
fn user()
//~ TRANS_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
pub fn user()
{
//~ TRANS_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
mod mod1 {
pub mod mod1 {
use cgu_extern_drop_glue;
struct LocalStruct(cgu_extern_drop_glue::Struct);
//~ TRANS_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[Internal]
fn user()
//~ TRANS_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
pub fn user()
{
//~ TRANS_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));

View file

@ -35,10 +35,10 @@ pub fn user()
cgu_explicit_inlining::never_inlined();
}
mod mod1 {
pub mod mod1 {
use cgu_explicit_inlining;
//~ TRANS_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[Internal]
//~ TRANS_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[External]
pub fn user()
{
cgu_explicit_inlining::inlined();
@ -48,10 +48,10 @@ mod mod1 {
}
}
mod mod2 {
pub mod mod2 {
use cgu_explicit_inlining;
//~ TRANS_ITEM fn inlining_from_extern_crate::mod2[0]::user[0] @@ inlining_from_extern_crate-mod2[Internal]
//~ 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();

View file

@ -15,7 +15,7 @@
// compile-flags:-Zinline-in-all-cgus
#![allow(dead_code)]
#![crate_type="lib"]
#![crate_type="rlib"]
//~ TRANS_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
struct Struct {
@ -32,8 +32,8 @@ struct Outer {
_a: Struct
}
//~ TRANS_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[Internal]
fn user()
//~ TRANS_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
pub fn user()
{
let _ = Outer {
_a: Struct {
@ -42,7 +42,7 @@ fn user()
};
}
mod mod1
pub mod mod1
{
use super::Struct;
@ -53,8 +53,8 @@ mod mod1
_b: (u32, Struct),
}
//~ TRANS_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[Internal]
fn user()
//~ TRANS_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
pub fn user()
{
let _ = Struct2 {
_a: Struct { _a: 0 },

View file

@ -27,28 +27,28 @@ mod inline {
}
}
mod user1 {
pub mod user1 {
use super::inline;
//~ TRANS_ITEM fn local_inlining_but_not_all::user1[0]::foo[0] @@ local_inlining_but_not_all-user1[Internal]
fn foo() {
//~ TRANS_ITEM fn local_inlining_but_not_all::user1[0]::foo[0] @@ local_inlining_but_not_all-user1[External]
pub fn foo() {
inline::inlined_function();
}
}
mod user2 {
pub mod user2 {
use super::inline;
//~ TRANS_ITEM fn local_inlining_but_not_all::user2[0]::bar[0] @@ local_inlining_but_not_all-user2[Internal]
fn bar() {
//~ TRANS_ITEM fn local_inlining_but_not_all::user2[0]::bar[0] @@ local_inlining_but_not_all-user2[External]
pub fn bar() {
inline::inlined_function();
}
}
mod non_user {
pub mod non_user {
//~ TRANS_ITEM fn local_inlining_but_not_all::non_user[0]::baz[0] @@ local_inlining_but_not_all-non_user[Internal]
fn baz() {
//~ TRANS_ITEM fn local_inlining_but_not_all::non_user[0]::baz[0] @@ local_inlining_but_not_all-non_user[External]
pub fn baz() {
}
}

View file

@ -28,28 +28,28 @@ mod inline {
}
}
mod user1 {
pub mod user1 {
use super::inline;
//~ TRANS_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[Internal]
fn foo() {
//~ TRANS_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[External]
pub fn foo() {
inline::inlined_function();
}
}
mod user2 {
pub mod user2 {
use super::inline;
//~ TRANS_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[Internal]
fn bar() {
//~ TRANS_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[External]
pub fn bar() {
inline::inlined_function();
}
}
mod non_user {
pub mod non_user {
//~ TRANS_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[Internal]
fn baz() {
//~ TRANS_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[External]
pub fn baz() {
}
}

View file

@ -15,7 +15,7 @@
// compile-flags:-Zinline-in-all-cgus
#![allow(dead_code)]
#![crate_type="lib"]
#![crate_type="rlib"]
mod inline {
@ -37,19 +37,19 @@ mod direct_user {
}
}
mod indirect_user {
pub mod indirect_user {
use super::direct_user;
//~ TRANS_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[Internal]
fn bar() {
//~ TRANS_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[External]
pub fn bar() {
direct_user::foo();
}
}
mod non_user {
pub mod non_user {
//~ TRANS_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[Internal]
fn baz() {
//~ TRANS_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[External]
pub fn baz() {
}
}

View file

@ -13,7 +13,7 @@
// incremental compilation
// compile-flags:-Zprint-trans-items=lazy -Zincremental=tmp/partitioning-tests/statics
#![crate_type="lib"]
#![crate_type="rlib"]
//~ TRANS_ITEM static statics::FOO[0] @@ statics[Internal]
static FOO: u32 = 0;
@ -21,8 +21,8 @@ static FOO: u32 = 0;
//~ TRANS_ITEM static statics::BAR[0] @@ statics[Internal]
static BAR: u32 = 0;
//~ TRANS_ITEM fn statics::function[0] @@ statics[Internal]
fn function() {
//~ TRANS_ITEM fn statics::function[0] @@ statics[External]
pub fn function() {
//~ TRANS_ITEM static statics::function[0]::FOO[0] @@ statics[Internal]
static FOO: u32 = 0;
@ -30,15 +30,15 @@ fn function() {
static BAR: u32 = 0;
}
mod mod1 {
pub mod mod1 {
//~ TRANS_ITEM static statics::mod1[0]::FOO[0] @@ statics-mod1[Internal]
static FOO: u32 = 0;
//~ TRANS_ITEM static statics::mod1[0]::BAR[0] @@ statics-mod1[Internal]
static BAR: u32 = 0;
//~ TRANS_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[Internal]
fn function() {
//~ TRANS_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[External]
pub fn function() {
//~ TRANS_ITEM static statics::mod1[0]::function[0]::FOO[0] @@ statics-mod1[Internal]
static FOO: u32 = 0;

View file

@ -15,7 +15,7 @@
// Hack to get the correct size for the length part in slices
// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
#[no_mangle]
fn helper(_: usize) {
pub fn helper(_: usize) {
}
// CHECK-LABEL: @no_op_slice_adjustment

View file

@ -59,28 +59,28 @@
#![crate_type = "lib"]
mod tests {
pub mod tests {
// CHECK: @f1(i32 inreg %arg0, i32 inreg %arg1, i32 %arg2)
#[no_mangle]
extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
// CHECK: @f2(i32* inreg %arg0, i32* inreg %arg1, i32* %arg2)
#[no_mangle]
extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
pub extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
// CHECK: @f3(float %arg0, i32 inreg %arg1, i32 inreg %arg2, i32 %arg3)
#[no_mangle]
extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}
pub extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}
// CHECK: @f4(i32 inreg %arg0, float %arg1, i32 inreg %arg2, i32 %arg3)
#[no_mangle]
extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}
pub extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}
// CHECK: @f5(i64 %arg0, i32 %arg1)
#[no_mangle]
extern "fastcall" fn f5(_: i64, _: i32) {}
pub extern "fastcall" fn f5(_: i64, _: i32) {}
// CHECK: @f6(i1 inreg zeroext %arg0, i32 inreg %arg1, i32 %arg2)
#[no_mangle]
extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
pub extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
}

View file

@ -93,20 +93,20 @@ pub fn struct_return() -> S {
// Hack to get the correct size for the length part in slices
// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
#[no_mangle]
fn helper(_: usize) {
pub fn helper(_: usize) {
}
// CHECK: @slice(i8* noalias nonnull readonly %arg0.ptr, [[USIZE]] %arg0.meta)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
fn slice(_: &[u8]) {
pub fn slice(_: &[u8]) {
}
// CHECK: @mutable_slice(i8* nonnull %arg0.ptr, [[USIZE]] %arg0.meta)
// FIXME #25759 This should also have `nocapture`
// ... there's this LLVM bug that forces us to not use noalias, see #29485
#[no_mangle]
fn mutable_slice(_: &mut [u8]) {
pub fn mutable_slice(_: &mut [u8]) {
}
// CHECK: @unsafe_slice(%UnsafeInner* nonnull %arg0.ptr, [[USIZE]] %arg0.meta)
@ -118,23 +118,23 @@ pub fn unsafe_slice(_: &[UnsafeInner]) {
// CHECK: @str(i8* noalias nonnull readonly %arg0.ptr, [[USIZE]] %arg0.meta)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
fn str(_: &[u8]) {
pub fn str(_: &[u8]) {
}
// CHECK: @trait_borrow({}* nonnull, {}* noalias nonnull readonly)
// FIXME #25759 This should also have `nocapture`
#[no_mangle]
fn trait_borrow(_: &Drop) {
pub fn trait_borrow(_: &Drop) {
}
// CHECK: @trait_box({}* noalias nonnull, {}* noalias nonnull readonly)
#[no_mangle]
fn trait_box(_: Box<Drop>) {
pub fn trait_box(_: Box<Drop>) {
}
// CHECK: { i16*, [[USIZE]] } @return_slice(i16* noalias nonnull readonly %x.ptr, [[USIZE]] %x.meta)
#[no_mangle]
fn return_slice(x: &[u16]) -> &[u16] {
pub fn return_slice(x: &[u16]) -> &[u16] {
x
}

View file

@ -19,7 +19,7 @@ struct Zst { phantom: PhantomData<Zst> }
// CHECK-LABEL: @mir
// CHECK-NOT: store{{.*}}undef
#[no_mangle]
fn mir() {
pub fn mir() {
let x = Zst { phantom: PhantomData };
let y = (x, 0);
drop(y);

View file

@ -16,10 +16,10 @@
#![feature(naked_functions)]
// CHECK: Function Attrs: naked uwtable
// CHECK-NEXT: define internal void @naked_empty()
// CHECK-NEXT: define void @naked_empty()
#[no_mangle]
#[naked]
fn naked_empty() {
pub fn naked_empty() {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret void
}
@ -27,8 +27,8 @@ fn naked_empty() {
// CHECK: Function Attrs: naked uwtable
#[no_mangle]
#[naked]
// CHECK-NEXT: define internal void @naked_with_args(i{{[0-9]+}})
fn naked_with_args(a: isize) {
// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+}})
pub fn naked_with_args(a: isize) {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: %a = alloca i{{[0-9]+}}
&a; // keep variable in an alloca
@ -36,20 +36,20 @@ fn naked_with_args(a: isize) {
}
// CHECK: Function Attrs: naked uwtable
// CHECK-NEXT: define internal i{{[0-9]+}} @naked_with_return()
// CHECK-NEXT: define i{{[0-9]+}} @naked_with_return()
#[no_mangle]
#[naked]
fn naked_with_return() -> isize {
pub fn naked_with_return() -> isize {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret i{{[0-9]+}} 0
0
}
// CHECK: Function Attrs: naked uwtable
// CHECK-NEXT: define internal i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}})
// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}})
#[no_mangle]
#[naked]
fn naked_with_args_and_return(a: isize) -> isize {
pub fn naked_with_args_and_return(a: isize) -> isize {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: %a = alloca i{{[0-9]+}}
&a; // keep variable in an alloca
@ -58,10 +58,10 @@ fn naked_with_args_and_return(a: isize) -> isize {
}
// CHECK: Function Attrs: naked uwtable
// CHECK-NEXT: define internal void @naked_recursive()
// CHECK-NEXT: define void @naked_recursive()
#[no_mangle]
#[naked]
fn naked_recursive() {
pub fn naked_recursive() {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: call void @naked_empty()

View file

@ -15,7 +15,7 @@
// Hack to get the correct size for the length part in slices
// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
#[no_mangle]
fn helper(_: usize) {
pub fn helper(_: usize) {
}
// CHECK-LABEL: @ref_dst

View file

@ -11,4 +11,6 @@
#[inline()] //~ ERROR E0534
pub fn something() {}
fn main() {}
fn main() {
something();
}

View file

@ -10,6 +10,7 @@
#![feature(repr_simd, platform_intrinsics, core_intrinsics)]
#![allow(warnings)]
#![crate_type = "rlib"]
// Bad monomorphizations could previously cause LLVM asserts even though the
// error was caught in the compiler.
@ -21,21 +22,19 @@ extern "platform-intrinsic" {
use std::intrinsics;
#[derive(Copy, Clone)]
struct Foo(i64);
pub struct Foo(i64);
unsafe fn test_cttz(v: Foo) -> Foo {
pub unsafe fn test_cttz(v: Foo) -> Foo {
intrinsics::cttz(v)
//~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo`
}
unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo {
pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo {
intrinsics::fadd_fast(a, b)
//~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo`
}
unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo {
pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo {
simd_add(a, b)
//~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo`
}
fn main() {}

View file

@ -11,13 +11,13 @@
#![crate_type="rlib"]
#![allow(warnings)]
mod a {
pub mod a {
#[no_mangle]
pub extern fn fail() {
}
}
mod b {
pub mod b {
#[no_mangle]
pub extern fn fail() {
//~^ symbol `fail` is already defined

View file

@ -21,4 +21,8 @@ fn b() {
fn c() {
}
fn main() {}
fn main() {
a();
b();
c();
}

View file

@ -12,6 +12,7 @@
#![recursion_limit = "20"]
#![type_length_limit = "20000000"]
#![crate_type = "rlib"]
#[derive(Clone)]
struct A (B);
@ -66,5 +67,3 @@ impl D {
pub fn matches() {
A(B::Variant1).matches(&(|| ()))
}
fn main() {}

View file

@ -10,92 +10,91 @@
#![feature(core_intrinsics)]
#![allow(warnings)]
#![crate_type = "rlib"]
use std::intrinsics;
#[derive(Copy, Clone)]
struct Foo(i64);
type Bar = &'static Fn();
type Quux = [u8; 100];
pub struct Foo(i64);
pub type Bar = &'static Fn();
pub type Quux = [u8; 100];
unsafe fn test_bool_load(p: &mut bool, v: bool) {
pub unsafe fn test_bool_load(p: &mut bool, v: bool) {
intrinsics::atomic_load(p);
//~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `bool`
}
unsafe fn test_bool_store(p: &mut bool, v: bool) {
pub unsafe fn test_bool_store(p: &mut bool, v: bool) {
intrinsics::atomic_store(p, v);
//~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `bool`
}
unsafe fn test_bool_xchg(p: &mut bool, v: bool) {
pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) {
intrinsics::atomic_xchg(p, v);
//~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `bool`
}
unsafe fn test_bool_cxchg(p: &mut bool, v: bool) {
pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) {
intrinsics::atomic_cxchg(p, v, v);
//~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
}
unsafe fn test_Foo_load(p: &mut Foo, v: Foo) {
pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) {
intrinsics::atomic_load(p);
//~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `Foo`
}
unsafe fn test_Foo_store(p: &mut Foo, v: Foo) {
pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) {
intrinsics::atomic_store(p, v);
//~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `Foo`
}
unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) {
pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) {
intrinsics::atomic_xchg(p, v);
//~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
}
unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
intrinsics::atomic_cxchg(p, v, v);
//~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
}
unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
intrinsics::atomic_load(p);
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
}
unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
intrinsics::atomic_store(p, v);
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
}
unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
intrinsics::atomic_xchg(p, v);
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
}
unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
intrinsics::atomic_cxchg(p, v, v);
//~^ ERROR expected basic integer type, found `&std::ops::Fn()`
}
unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
intrinsics::atomic_load(p);
//~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
}
unsafe fn test_Quux_store(p: &mut Quux, v: Quux) {
pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) {
intrinsics::atomic_store(p, v);
//~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
}
unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) {
pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) {
intrinsics::atomic_xchg(p, v);
//~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
}
unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) {
pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) {
intrinsics::atomic_cxchg(p, v, v);
//~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
}
fn main() {}

View file

@ -12,27 +12,29 @@
// crate. This should not cause anything we use to be invalidated.
// Regression test for #36168.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// aux-build:point.rs
// must-compile-successfully
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![crate_type = "rlib"]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_free_fn", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_free_fn", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
extern crate point;
/// A fn item that calls (public) methods on `Point` from the same impl
mod fn_calls_methods_in_same_impl {
pub mod fn_calls_methods_in_same_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -40,10 +42,10 @@ mod fn_calls_methods_in_same_impl {
}
/// A fn item that calls (public) methods on `Point` from another impl
mod fn_calls_free_fn {
pub mod fn_calls_free_fn {
use point::{self, Point};
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
point::distance_squared(&x);
@ -51,34 +53,31 @@ mod fn_calls_free_fn {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -13,32 +13,34 @@
// Fns with that type used only in their body are also recompiled, but
// their callers are not.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![crate_type = "rlib"]
// These are expected to require translation.
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_with_type_in_sig", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-call_fn_with_type_in_sig", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_with_type_in_body", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-point", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_with_type_in_sig", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-call_fn_with_type_in_sig", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_with_type_in_body", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_write_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-call_fn_with_type_in_body", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-call_fn_with_type_in_body", cfg="cfail2")]
mod point {
#[cfg(rpass1)]
pub mod point {
#[cfg(cfail1)]
pub struct Point {
pub x: f32,
pub y: f32,
}
#[cfg(rpass2)]
#[cfg(cfail2)]
pub struct Point {
pub x: f32,
pub y: f32,
@ -47,18 +49,18 @@ mod point {
impl Point {
pub fn origin() -> Point {
#[cfg(rpass1)]
#[cfg(cfail1)]
return Point { x: 0.0, y: 0.0 };
#[cfg(rpass2)]
#[cfg(cfail2)]
return Point { x: 0.0, y: 0.0, z: 0.0 };
}
pub fn total(&self) -> f32 {
#[cfg(rpass1)]
#[cfg(cfail1)]
return self.x + self.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return self.x + self.y + self.z;
}
@ -75,10 +77,10 @@ mod point {
/// sufficiently "private", we might not need to type-check again.
/// Rebuilding is probably always necessary since the layout may be
/// affected.
mod fn_with_type_in_sig {
pub mod fn_with_type_in_sig {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn boop(p: Option<&Point>) -> f32 {
p.map(|p| p.total()).unwrap_or(0.0)
}
@ -91,10 +93,10 @@ mod fn_with_type_in_sig {
/// sufficiently "private", we might not need to type-check again.
/// Rebuilding is probably always necessary since the layout may be
/// affected.
mod call_fn_with_type_in_sig {
pub mod call_fn_with_type_in_sig {
use fn_with_type_in_sig;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn bip() -> f32 {
fn_with_type_in_sig::boop(None)
}
@ -107,10 +109,10 @@ mod call_fn_with_type_in_sig {
/// sufficiently "private", we might not need to type-check again.
/// Rebuilding is probably always necessary since the layout may be
/// affected.
mod fn_with_type_in_body {
pub mod fn_with_type_in_body {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn boop() -> f32 {
Point::origin().total()
}
@ -120,44 +122,41 @@ mod fn_with_type_in_body {
/// body. In this case, the effects of the change should be contained
/// to Y; X should not have to be rebuilt, nor should it need to be
/// typechecked again.
mod call_fn_with_type_in_body {
pub mod call_fn_with_type_in_body {
use fn_with_type_in_body;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn bip() -> f32 {
fn_with_type_in_body::boop()
}
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn make_origin(p: Point) -> Point {
Point { ..p }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -11,32 +11,34 @@
// Test where we change the body of a private method in an impl.
// We then test what sort of functions must be rebuilt as a result.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![crate_type = "rlib"]
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-point", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
mod point {
pub mod point {
pub struct Point {
pub x: f32,
pub y: f32,
}
fn distance_squared(this: &Point) -> f32 {
#[cfg(rpass1)]
#[cfg(cfail1)]
return this.x + this.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return this.x * this.x + this.y * this.y;
}
@ -56,10 +58,10 @@ mod point {
}
/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_methods_in_same_impl {
pub mod fn_calls_methods_in_same_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -67,10 +69,10 @@ mod fn_calls_methods_in_same_impl {
}
/// A fn item that calls (public) methods on `Point` from another impl
mod fn_calls_methods_in_another_impl {
pub mod fn_calls_methods_in_another_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let mut x = Point { x: 2.0, y: 2.0 };
x.translate(3.0, 3.0);
@ -78,34 +80,31 @@ mod fn_calls_methods_in_another_impl {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -14,10 +14,10 @@ pub struct Point {
}
fn distance_squared(this: &Point) -> f32 {
#[cfg(rpass1)]
#[cfg(cfail1)]
return this.x + this.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return this.x * this.x + this.y * this.y;
}

View file

@ -11,27 +11,29 @@
// Test where we change the body of a private method in an impl.
// We then test what sort of functions must be rebuilt as a result.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// aux-build:point.rs
// must-compile-successfully
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
extern crate point;
/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_methods_in_same_impl {
pub mod fn_calls_methods_in_same_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -39,10 +41,10 @@ mod fn_calls_methods_in_same_impl {
}
/// A fn item that calls (public) methods on `Point` from another impl
mod fn_calls_methods_in_another_impl {
pub mod fn_calls_methods_in_another_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let mut x = Point { x: 2.0, y: 2.0 };
x.translate(3.0, 3.0);
@ -50,34 +52,31 @@ mod fn_calls_methods_in_another_impl {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -11,33 +11,35 @@
// Test where we change the body of a private method in an impl.
// We then test what sort of functions must be rebuilt as a result.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![crate_type = "rlib"]
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-point", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
mod point {
pub mod point {
pub struct Point {
pub x: f32,
pub y: f32,
}
impl Point {
fn distance_squared(&self) -> f32 {
#[cfg(rpass1)]
pub fn distance_squared(&self) -> f32 {
#[cfg(cfail1)]
return self.x + self.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return self.x * self.x + self.y * self.y;
}
@ -56,10 +58,10 @@ mod point {
}
/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_methods_in_same_impl {
pub mod fn_calls_methods_in_same_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -67,10 +69,10 @@ mod fn_calls_methods_in_same_impl {
}
/// A fn item that calls (public) methods on `Point` from another impl
mod fn_calls_methods_in_another_impl {
pub mod fn_calls_methods_in_another_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let mut x = Point { x: 2.0, y: 2.0 };
x.translate(3.0, 3.0);
@ -78,34 +80,31 @@ mod fn_calls_methods_in_another_impl {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -15,10 +15,10 @@ pub struct Point {
impl Point {
fn distance_squared(&self) -> f32 {
#[cfg(rpass1)]
#[cfg(cfail1)]
return self.x + self.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return self.x * self.x + self.y * self.y;
}

View file

@ -11,28 +11,30 @@
// Test where we change the body of a private method in an impl.
// We then test what sort of functions must be rebuilt as a result.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// aux-build:point.rs
// must-compile-successfully
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="cfail2")]
extern crate point;
/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_methods_in_same_impl {
pub mod fn_calls_methods_in_same_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let x = Point { x: 2.0, y: 2.0 };
x.distance_from_origin();
@ -40,10 +42,10 @@ mod fn_calls_methods_in_same_impl {
}
/// A fn item that calls (public) methods on `Point` from another impl
mod fn_calls_methods_in_another_impl {
pub mod fn_calls_methods_in_another_impl {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn dirty() {
let mut x = Point { x: 2.0, y: 2.0 };
x.translate(3.0, 3.0);
@ -51,34 +53,31 @@ mod fn_calls_methods_in_another_impl {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -10,22 +10,24 @@
// Test where we change the body of a public, inherent method.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-point", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_changed_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_changed_method", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
mod point {
pub mod point {
pub struct Point {
pub x: f32,
pub y: f32,
@ -33,10 +35,10 @@ mod point {
impl Point {
pub fn distance_from_origin(&self) -> f32 {
#[cfg(rpass1)]
#[cfg(cfail1)]
return self.x * self.x + self.y * self.y;
#[cfg(rpass2)]
#[cfg(cfail2)]
return (self.x * self.x + self.y * self.y).sqrt();
}
@ -47,10 +49,10 @@ mod point {
}
/// A fn item that calls the method on `Point` which changed
mod fn_calls_changed_method {
pub mod fn_calls_changed_method {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let p = Point { x: 2.0, y: 2.0 };
p.distance_from_origin();
@ -58,10 +60,10 @@ mod fn_calls_changed_method {
}
/// A fn item that calls a method on `Point` which did not change
mod fn_calls_another_method {
pub mod fn_calls_another_method {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let p = Point { x: 2.0, y: 2.0 };
p.x();
@ -69,34 +71,31 @@ mod fn_calls_another_method {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -10,30 +10,32 @@
// Test where we change the *signature* of a public, inherent method.
// revisions:rpass1 rpass2
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]
// These are expected to require translation.
#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-fn_calls_changed_method", cfg="rpass2")]
#![rustc_partition_translated(module="struct_point-point", cfg="cfail2")]
#![rustc_partition_translated(module="struct_point-fn_calls_changed_method", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="cfail2")]
mod point {
pub mod point {
pub struct Point {
pub x: f32,
pub y: f32,
}
impl Point {
#[cfg(rpass1)]
#[cfg(cfail1)]
pub fn distance_from_point(&self, p: Option<Point>) -> f32 {
let p = p.unwrap_or(Point { x: 0.0, y: 0.0 });
let x_diff = self.x - p.x;
@ -41,7 +43,7 @@ mod point {
return x_diff * x_diff + y_diff * y_diff;
}
#[cfg(rpass2)]
#[cfg(cfail2)]
pub fn distance_from_point(&self, p: Option<&Point>) -> f32 {
const ORIGIN: &Point = &Point { x: 0.0, y: 0.0 };
let p = p.unwrap_or(ORIGIN);
@ -57,10 +59,10 @@ mod point {
}
/// A fn item that calls the method that was changed
mod fn_calls_changed_method {
pub mod fn_calls_changed_method {
use point::Point;
#[rustc_dirty(label="TypeckTables", cfg="rpass2")]
#[rustc_dirty(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let p = Point { x: 2.0, y: 2.0 };
p.distance_from_point(None);
@ -68,10 +70,10 @@ mod fn_calls_changed_method {
}
/// A fn item that calls a method that was not changed
mod fn_calls_another_method {
pub mod fn_calls_another_method {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn check() {
let p = Point { x: 2.0, y: 2.0 };
p.x();
@ -79,34 +81,31 @@ mod fn_calls_another_method {
}
/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
pub mod fn_make_struct {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn make_origin() -> Point {
Point { x: 2.0, y: 2.0 }
}
}
/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
pub mod fn_read_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn get_x(p: Point) -> f32 {
p.x
}
}
/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
pub mod fn_write_field {
use point::Point;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
pub fn inc_x(p: &mut Point) {
p.x += 1.0;
}
}
fn main() {
}

View file

@ -190,7 +190,7 @@ impl Struct2 {
}
// Change UFCS Callee Indirectly -----------------------------------------------
mod change_ufcs_callee_indirectly {
pub mod change_ufcs_callee_indirectly {
#[cfg(cfail1)]
use super::Struct as Struct;
#[cfg(not(cfail1))]

View file

@ -25,7 +25,7 @@
#![crate_type="rlib"]
enum Enum {
pub enum Enum {
Struct {
x: i32,
y: i64,
@ -36,7 +36,7 @@ enum Enum {
// Change field value (struct-like) -----------------------------------------
#[cfg(cfail1)]
fn change_field_value_struct_like() -> Enum {
pub fn change_field_value_struct_like() -> Enum {
Enum::Struct {
x: 0,
y: 1,
@ -49,7 +49,7 @@ fn change_field_value_struct_like() -> Enum {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_value_struct_like() -> Enum {
pub fn change_field_value_struct_like() -> Enum {
Enum::Struct {
x: 0,
y: 2,
@ -61,7 +61,7 @@ fn change_field_value_struct_like() -> Enum {
// Change field order (struct-like) -----------------------------------------
#[cfg(cfail1)]
fn change_field_order_struct_like() -> Enum {
pub fn change_field_order_struct_like() -> Enum {
Enum::Struct {
x: 3,
y: 4,
@ -76,7 +76,7 @@ fn change_field_order_struct_like() -> Enum {
#[rustc_metadata_clean(cfg="cfail3")]
// FIXME(michaelwoerister):Interesting. I would have thought that that changes the MIR. And it
// would if it were not all constants
fn change_field_order_struct_like() -> Enum {
pub fn change_field_order_struct_like() -> Enum {
Enum::Struct {
y: 4,
x: 3,
@ -85,7 +85,7 @@ fn change_field_order_struct_like() -> Enum {
}
enum Enum2 {
pub enum Enum2 {
Struct {
x: i8,
y: i8,
@ -102,7 +102,7 @@ enum Enum2 {
// Change constructor path (struct-like) ------------------------------------
#[cfg(cfail1)]
fn change_constructor_path_struct_like() {
pub fn change_constructor_path_struct_like() {
let _ = Enum::Struct {
x: 0,
y: 1,
@ -115,7 +115,7 @@ fn change_constructor_path_struct_like() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_path_struct_like() {
pub fn change_constructor_path_struct_like() {
let _ = Enum2::Struct {
x: 0,
y: 1,
@ -127,7 +127,7 @@ fn change_constructor_path_struct_like() {
// Change variant (regular struct) ------------------------------------
#[cfg(cfail1)]
fn change_constructor_variant_struct_like() {
pub fn change_constructor_variant_struct_like() {
let _ = Enum2::Struct {
x: 0,
y: 1,
@ -140,7 +140,7 @@ fn change_constructor_variant_struct_like() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_variant_struct_like() {
pub fn change_constructor_variant_struct_like() {
let _ = Enum2::Struct2 {
x: 0,
y: 1,
@ -150,7 +150,7 @@ fn change_constructor_variant_struct_like() {
// Change constructor path indirectly (struct-like) -------------------------
mod change_constructor_path_indirectly_struct_like {
pub mod change_constructor_path_indirectly_struct_like {
#[cfg(cfail1)]
use super::Enum as TheEnum;
#[cfg(not(cfail1))]
@ -164,7 +164,7 @@ mod change_constructor_path_indirectly_struct_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> TheEnum {
pub fn function() -> TheEnum {
TheEnum::Struct {
x: 0,
y: 1,
@ -175,7 +175,7 @@ mod change_constructor_path_indirectly_struct_like {
// Change constructor variant indirectly (struct-like) ---------------------------
mod change_constructor_variant_indirectly_struct_like {
pub mod change_constructor_variant_indirectly_struct_like {
use super::Enum2;
#[cfg(cfail1)]
use super::Enum2::Struct as Variant;
@ -186,7 +186,7 @@ mod change_constructor_variant_indirectly_struct_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> Enum2 {
pub fn function() -> Enum2 {
Variant {
x: 0,
y: 1,
@ -198,7 +198,7 @@ mod change_constructor_variant_indirectly_struct_like {
// Change field value (tuple-like) -------------------------------------------
#[cfg(cfail1)]
fn change_field_value_tuple_like() -> Enum {
pub fn change_field_value_tuple_like() -> Enum {
Enum::Tuple(0, 1, 2)
}
@ -207,7 +207,7 @@ fn change_field_value_tuple_like() -> Enum {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_value_tuple_like() -> Enum {
pub fn change_field_value_tuple_like() -> Enum {
Enum::Tuple(0, 1, 3)
}
@ -215,7 +215,7 @@ fn change_field_value_tuple_like() -> Enum {
// Change constructor path (tuple-like) --------------------------------------
#[cfg(cfail1)]
fn change_constructor_path_tuple_like() {
pub fn change_constructor_path_tuple_like() {
let _ = Enum::Tuple(0, 1, 2);
}
@ -227,7 +227,7 @@ fn change_constructor_path_tuple_like() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_path_tuple_like() {
pub fn change_constructor_path_tuple_like() {
let _ = Enum2::Tuple(0, 1, 2);
}
@ -235,7 +235,7 @@ fn change_constructor_path_tuple_like() {
// Change constructor variant (tuple-like) --------------------------------------
#[cfg(cfail1)]
fn change_constructor_variant_tuple_like() {
pub fn change_constructor_variant_tuple_like() {
let _ = Enum2::Tuple(0, 1, 2);
}
@ -247,13 +247,13 @@ fn change_constructor_variant_tuple_like() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_variant_tuple_like() {
pub fn change_constructor_variant_tuple_like() {
let _ = Enum2::Tuple2(0, 1, 2);
}
// Change constructor path indirectly (tuple-like) ---------------------------
mod change_constructor_path_indirectly_tuple_like {
pub mod change_constructor_path_indirectly_tuple_like {
#[cfg(cfail1)]
use super::Enum as TheEnum;
#[cfg(not(cfail1))]
@ -267,7 +267,7 @@ mod change_constructor_path_indirectly_tuple_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> TheEnum {
pub fn function() -> TheEnum {
TheEnum::Tuple(0, 1, 2)
}
}
@ -275,7 +275,7 @@ mod change_constructor_path_indirectly_tuple_like {
// Change constructor variant indirectly (tuple-like) ---------------------------
mod change_constructor_variant_indirectly_tuple_like {
pub mod change_constructor_variant_indirectly_tuple_like {
use super::Enum2;
#[cfg(cfail1)]
use super::Enum2::Tuple as Variant;
@ -286,19 +286,19 @@ mod change_constructor_variant_indirectly_tuple_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> Enum2 {
pub fn function() -> Enum2 {
Variant(0, 1, 2)
}
}
enum Clike {
pub enum Clike {
A,
B,
C
}
enum Clike2 {
pub enum Clike2 {
B,
C,
D
@ -306,7 +306,7 @@ enum Clike2 {
// Change constructor path (C-like) --------------------------------------
#[cfg(cfail1)]
fn change_constructor_path_c_like() {
pub fn change_constructor_path_c_like() {
let _ = Clike::B;
}
@ -314,7 +314,7 @@ fn change_constructor_path_c_like() {
#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirValidated,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_path_c_like() {
pub fn change_constructor_path_c_like() {
let _ = Clike2::B;
}
@ -322,7 +322,7 @@ fn change_constructor_path_c_like() {
// Change constructor variant (C-like) --------------------------------------
#[cfg(cfail1)]
fn change_constructor_variant_c_like() {
pub fn change_constructor_variant_c_like() {
let _ = Clike::A;
}
@ -331,13 +331,13 @@ fn change_constructor_variant_c_like() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_variant_c_like() {
pub fn change_constructor_variant_c_like() {
let _ = Clike::C;
}
// Change constructor path indirectly (C-like) ---------------------------
mod change_constructor_path_indirectly_c_like {
pub mod change_constructor_path_indirectly_c_like {
#[cfg(cfail1)]
use super::Clike as TheEnum;
#[cfg(not(cfail1))]
@ -351,7 +351,7 @@ mod change_constructor_path_indirectly_c_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> TheEnum {
pub fn function() -> TheEnum {
TheEnum::B
}
}
@ -359,7 +359,7 @@ mod change_constructor_path_indirectly_c_like {
// Change constructor variant indirectly (C-like) ---------------------------
mod change_constructor_variant_indirectly_c_like {
pub mod change_constructor_variant_indirectly_c_like {
use super::Clike;
#[cfg(cfail1)]
use super::Clike::A as Variant;
@ -370,7 +370,7 @@ mod change_constructor_variant_indirectly_c_like {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> Clike {
pub fn function() -> Clike {
Variant
}
}

View file

@ -25,7 +25,7 @@
#![feature(rustc_attrs)]
#![crate_type="rlib"]
struct Foo;
pub struct Foo;
// Change Method Name -----------------------------------------------------------
#[cfg(cfail1)]
@ -578,3 +578,19 @@ impl<T: Clone> Bar<T> {
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_trait_bound_to_impl_parameter(&self) { }
}
// Force instantiation of some fns so we can check their hash.
pub fn instantiation_root() {
Foo::method_privacy();
#[cfg(cfail1)]
{
Bar(0u32).change_impl_self_type();
}
#[cfg(not(cfail1))]
{
Bar(0u64).change_impl_self_type();
}
}

View file

@ -25,7 +25,7 @@
#![crate_type="rlib"]
struct RegularStruct {
pub struct RegularStruct {
x: i32,
y: i64,
z: i16,
@ -33,7 +33,7 @@ struct RegularStruct {
// Change field value (regular struct) -----------------------------------------
#[cfg(cfail1)]
fn change_field_value_regular_struct() -> RegularStruct {
pub fn change_field_value_regular_struct() -> RegularStruct {
RegularStruct {
x: 0,
y: 1,
@ -46,7 +46,7 @@ fn change_field_value_regular_struct() -> RegularStruct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_value_regular_struct() -> RegularStruct {
pub fn change_field_value_regular_struct() -> RegularStruct {
RegularStruct {
x: 0,
y: 2,
@ -58,7 +58,7 @@ fn change_field_value_regular_struct() -> RegularStruct {
// Change field order (regular struct) -----------------------------------------
#[cfg(cfail1)]
fn change_field_order_regular_struct() -> RegularStruct {
pub fn change_field_order_regular_struct() -> RegularStruct {
RegularStruct {
x: 3,
y: 4,
@ -71,7 +71,7 @@ fn change_field_order_regular_struct() -> RegularStruct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_order_regular_struct() -> RegularStruct {
pub fn change_field_order_regular_struct() -> RegularStruct {
RegularStruct {
y: 4,
x: 3,
@ -83,7 +83,7 @@ fn change_field_order_regular_struct() -> RegularStruct {
// Add field (regular struct) --------------------------------------------------
#[cfg(cfail1)]
fn add_field_regular_struct() -> RegularStruct {
pub fn add_field_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
x: 3,
y: 4,
@ -101,7 +101,7 @@ fn add_field_regular_struct() -> RegularStruct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn add_field_regular_struct() -> RegularStruct {
pub fn add_field_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
x: 3,
y: 4,
@ -119,7 +119,7 @@ fn add_field_regular_struct() -> RegularStruct {
// Change field label (regular struct) -----------------------------------------
#[cfg(cfail1)]
fn change_field_label_regular_struct() -> RegularStruct {
pub fn change_field_label_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
x: 3,
y: 4,
@ -138,7 +138,7 @@ fn change_field_label_regular_struct() -> RegularStruct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_label_regular_struct() -> RegularStruct {
pub fn change_field_label_regular_struct() -> RegularStruct {
let struct1 = RegularStruct {
x: 3,
y: 4,
@ -154,7 +154,7 @@ fn change_field_label_regular_struct() -> RegularStruct {
struct RegularStruct2 {
pub struct RegularStruct2 {
x: i8,
y: i8,
z: i8,
@ -162,7 +162,7 @@ struct RegularStruct2 {
// Change constructor path (regular struct) ------------------------------------
#[cfg(cfail1)]
fn change_constructor_path_regular_struct() {
pub fn change_constructor_path_regular_struct() {
let _ = RegularStruct {
x: 0,
y: 1,
@ -175,7 +175,7 @@ fn change_constructor_path_regular_struct() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_path_regular_struct() {
pub fn change_constructor_path_regular_struct() {
let _ = RegularStruct2 {
x: 0,
y: 1,
@ -186,7 +186,7 @@ fn change_constructor_path_regular_struct() {
// Change constructor path indirectly (regular struct) -------------------------
mod change_constructor_path_indirectly_regular_struct {
pub mod change_constructor_path_indirectly_regular_struct {
#[cfg(cfail1)]
use super::RegularStruct as Struct;
#[cfg(not(cfail1))]
@ -199,7 +199,7 @@ mod change_constructor_path_indirectly_regular_struct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> Struct {
pub fn function() -> Struct {
Struct {
x: 0,
y: 1,
@ -210,11 +210,11 @@ mod change_constructor_path_indirectly_regular_struct {
struct TupleStruct(i32, i64, i16);
pub struct TupleStruct(i32, i64, i16);
// Change field value (tuple struct) -------------------------------------------
#[cfg(cfail1)]
fn change_field_value_tuple_struct() -> TupleStruct {
pub fn change_field_value_tuple_struct() -> TupleStruct {
TupleStruct(0, 1, 2)
}
@ -223,17 +223,17 @@ fn change_field_value_tuple_struct() -> TupleStruct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_field_value_tuple_struct() -> TupleStruct {
pub fn change_field_value_tuple_struct() -> TupleStruct {
TupleStruct(0, 1, 3)
}
struct TupleStruct2(u16, u16, u16);
pub struct TupleStruct2(u16, u16, u16);
// Change constructor path (tuple struct) --------------------------------------
#[cfg(cfail1)]
fn change_constructor_path_tuple_struct() {
pub fn change_constructor_path_tuple_struct() {
let _ = TupleStruct(0, 1, 2);
}
@ -242,14 +242,14 @@ fn change_constructor_path_tuple_struct() {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn change_constructor_path_tuple_struct() {
pub fn change_constructor_path_tuple_struct() {
let _ = TupleStruct2(0, 1, 2);
}
// Change constructor path indirectly (tuple struct) ---------------------------
mod change_constructor_path_indirectly_tuple_struct {
pub mod change_constructor_path_indirectly_tuple_struct {
#[cfg(cfail1)]
use super::TupleStruct as Struct;
#[cfg(not(cfail1))]
@ -262,7 +262,7 @@ mod change_constructor_path_indirectly_tuple_struct {
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
fn function() -> Struct {
pub fn function() -> Struct {
Struct(0, 1, 2)
}
}

View file

@ -33,10 +33,9 @@ pub fn main() {
mod mod1 {
pub fn some_fn() {
#[cfg(rpass2)]
{}
let _ = 1;
}
#[cfg(rpass2)]
fn _some_other_fn() {
}
}

View file

@ -8,27 +8,27 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: rpass1 rpass2
// revisions: cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![allow(warnings)]
#![feature(rustc_attrs)]
#![rustc_partition_reused(module="krate_inherent-x", cfg="rpass2")]
#![rustc_partition_reused(module="krate_inherent-x", cfg="cfail2")]
#![crate_type = "rlib"]
fn main() { }
mod x {
struct Foo;
pub mod x {
pub struct Foo;
impl Foo {
fn foo(&self) { }
pub fn foo(&self) { }
}
fn method() {
pub fn method() {
let x: Foo = Foo;
x.foo(); // inherent methods used to add an edge from Krate
}
}
#[cfg(rpass1)]
fn bar() { } // remove this unrelated fn in rpass2, which should not affect `x::method`
#[cfg(cfail1)]
pub fn bar() { } // remove this unrelated fn in cfail2, which should not affect `x::method`

View file

@ -20,12 +20,14 @@
#![rustc_partition_reused(module="krate_inlined-x", cfg="rpass2")]
fn main() {
x::method();
#[cfg(rpass2)]
()
}
mod x {
fn method() {
pub fn method() {
// use some methods that require inlining HIR from another crate:
let mut v = vec![];
v.push(1);

View file

@ -8,47 +8,48 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: rpass1 rpass2
// revisions: cfail1 cfail2
// compile-flags: -Z query-dep-graph
// must-compile-successfully
#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type = "rlib"]
// Here the only thing which changes is the string constant in `x`.
// Therefore, the compiler deduces (correctly) that typeck is not
// needed even for callers of `x`.
fn main() { }
mod x {
#[cfg(rpass1)]
pub mod x {
#[cfg(cfail1)]
pub fn x() {
println!("{}", "1");
}
#[cfg(rpass2)]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
#[rustc_dirty(label="MirOptimized", cfg="rpass2")]
#[cfg(cfail2)]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_dirty(label="MirOptimized", cfg="cfail2")]
pub fn x() {
println!("{}", "2");
}
}
mod y {
pub mod y {
use x;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="MirOptimized", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
#[rustc_clean(label="MirOptimized", cfg="cfail2")]
pub fn y() {
x::x();
}
}
mod z {
pub mod z {
use y;
#[rustc_clean(label="TypeckTables", cfg="rpass2")]
#[rustc_clean(label="MirOptimized", cfg="rpass2")]
#[rustc_clean(label="TypeckTables", cfg="cfail2")]
#[rustc_clean(label="MirOptimized", cfg="cfail2")]
pub fn z() {
y::y();
}

View file

@ -13,7 +13,10 @@ fn test(x: u32) -> u32 {
y
}
fn main() { }
fn main() {
// Make sure the function actually gets instantiated.
test(0);
}
// END RUST SOURCE
// START rustc.node4.CopyPropagation.before.mir

View file

@ -18,7 +18,10 @@ fn bar(a: usize) -> Baz {
Baz { x: a, y: 0.0, z: false }
}
fn main() {}
fn main() {
// Make sure the function actually gets instantiated.
bar(0);
}
// END RUST SOURCE
// START rustc.node13.Deaggregator.before.mir

View file

@ -23,7 +23,10 @@ fn test1(x: bool, y: i32) -> Foo {
}
}
fn main() {}
fn main() {
// Make sure the function actually gets instantiated.
test1(false, 0);
}
// END RUST SOURCE
// START rustc.node12.Deaggregator.before.mir

View file

@ -19,7 +19,10 @@ fn test(x: i32) -> [Foo; 2] {
[Foo::A(x), Foo::A(x)]
}
fn main() { }
fn main() {
// Make sure the function actually gets instantiated.
test(0);
}
// END RUST SOURCE
// START rustc.node10.Deaggregator.before.mir

View file

@ -14,6 +14,8 @@ fn main() {
let x = S.other(S.id());
}
// no_mangle to make sure this gets instantiated even in an executable.
#[no_mangle]
pub fn test() {
let u = S;
let mut v = S;

View file

@ -18,7 +18,9 @@ fn guard2(_:i32) -> bool {
true
}
fn full_tested_match() {
// no_mangle to make sure this gets instantiated even in an executable.
#[no_mangle]
pub fn full_tested_match() {
let _ = match Some(42) {
Some(x) if guard() => (1, x),
Some(y) => (2, y),
@ -26,7 +28,9 @@ fn full_tested_match() {
};
}
fn full_tested_match2() {
// no_mangle to make sure this gets instantiated even in an executable.
#[no_mangle]
pub fn full_tested_match2() {
let _ = match Some(42) {
Some(x) if guard() => (1, x),
None => (3, 3),

View file

@ -13,6 +13,7 @@ fn outer<T>() {
fn inner() -> u32 {
8675309
}
inner();
}
extern "C" fn outer_foreign<T>() {
@ -20,6 +21,7 @@ extern "C" fn outer_foreign<T>() {
fn inner() -> u32 {
11235813
}
inner();
}
fn main() {

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn magic_fn() -> usize {
1234
}
@ -24,4 +26,8 @@ mod b {
}
}
fn main() { }
fn main() {
magic_fn();
a::magic_fn();
b::magic_fn();
}

View file

@ -14,7 +14,8 @@ pub static Y: &'static [u8] = include_bytes!("lib.rs");
trait Foo { fn dummy(&self) { } }
impl Foo for usize {}
pub fn dummy() {
#[no_mangle]
pub extern "C" fn dummy() {
// force the vtable to be created
let _x = &1usize as &Foo;
}

View file

@ -17,3 +17,8 @@ impl Def {
Def { id: id }
}
}
#[no_mangle]
pub fn user() {
let _ = Def::new(0);
}

View file

@ -11,4 +11,6 @@
#[inline(unknown)] //~ ERROR E0535
pub fn something() {}
fn main() {}
fn main() {
something();
}