Auto merge of #48806 - alexcrichton:rollup, r=alexcrichton

Rollup of 9 pull requests

- Successful merges: #48511, #48549, #48618, #48624, #48651, #48698, #48778, #48787, #48802
- Failed merges: #48669, #48710
This commit is contained in:
bors 2018-03-07 21:59:15 +00:00
commit 5430c0c5c0
88 changed files with 831 additions and 924 deletions

View file

@ -19,12 +19,18 @@ environment:
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
SCRIPT: python x.py test
- MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc --target=i686-pc-windows-msvc
SCRIPT: python x.py test --host i686-pc-windows-msvc --target i686-pc-windows-msvc
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
SCRIPT: python x.py test --exclude src/test/run-pass --exclude src/test/compile-fail
- MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
SCRIPT: python x.py test src/test/run-pass src/test/compile-fail
# MSVC aux tests
- MSYS_BITS: 64
RUST_CHECK_TARGET: check-aux
RUST_CHECK_TARGET: check-aux EXCLUDE_CARGO=1
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
- MSYS_BITS: 64
SCRIPT: python x.py test src/tools/cargotest src/tools/cargo
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
# MSVC tools tests

58
src/Cargo.lock generated
View file

@ -398,10 +398,12 @@ dependencies = [
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -926,12 +928,11 @@ dependencies = [
"clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1185,6 +1186,15 @@ dependencies = [
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miri"
version = "0.1.0"
@ -1511,15 +1521,6 @@ dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "1.0.0"
@ -2225,15 +2226,6 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "same-file"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "same-file"
version = "1.0.2"
@ -2779,16 +2771,6 @@ name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "walkdir"
version = "2.0.1"
@ -2971,6 +2953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
"checksum nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "62e678237a4c70c5f2b917cefd7d080dfbf800421f06e8a59d4e28ef5130fd9e"
"checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487"
@ -3004,7 +2987,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4"
"checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8"
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf"
"checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
@ -3027,7 +3009,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0"
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
@ -3085,7 +3066,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
"checksum walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b6d201f4f8998a837196b6de9c73e35af14c992cbb92c4ab641d2c2dce52de"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"

View file

@ -16,6 +16,12 @@ Q := @
BOOTSTRAP_ARGS :=
endif
ifdef EXCLUDE_CARGO
AUX_ARGS := src/tools/cargo src/tools/cargotest
else
AUX_ARGS :=
endif
BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py
all:
@ -52,14 +58,13 @@ check:
$(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS)
check-aux:
$(Q)$(BOOTSTRAP) test \
src/tools/cargo \
src/tools/cargotest \
src/test/pretty \
src/test/run-pass/pretty \
src/test/run-fail/pretty \
src/test/run-pass-valgrind/pretty \
src/test/run-pass-fulldeps/pretty \
src/test/run-fail-fulldeps/pretty \
$(AUX_ARGS) \
$(BOOTSTRAP_ARGS)
check-bootstrap:
$(Q)$(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap_test.py

View file

@ -104,7 +104,7 @@ else
travis_fold start "make-$1"
travis_time_start
echo "make -j $ncpus $1"
make -j $ncpus "$1"
make -j $ncpus $1
local retval=$?
travis_fold end "make-$1"
travis_time_finish

View file

@ -1,127 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2013 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.
# This creates the tables used for distributions implemented using the
# ziggurat algorithm in `rand::distributions;`. They are
# (basically) the tables as used in the ZIGNOR variant (Doornik 2005).
# They are changed rarely, so the generated file should be checked in
# to git.
#
# It creates 3 tables: X as in the paper, F which is f(x_i), and
# F_DIFF which is f(x_i) - f(x_{i-1}). The latter two are just cached
# values which is not done in that paper (but is done in other
# variants). Note that the adZigR table is unnecessary because of
# algebra.
#
# It is designed to be compatible with Python 2 and 3.
from math import exp, sqrt, log, floor
import random
# The order should match the return value of `tables`
TABLE_NAMES = ['X', 'F']
# The actual length of the table is 1 more, to stop
# index-out-of-bounds errors. This should match the bitwise operation
# to find `i` in `zigurrat` in `libstd/rand/mod.rs`. Also the *_R and
# *_V constants below depend on this value.
TABLE_LEN = 256
# equivalent to `zigNorInit` in Doornik2005, but generalised to any
# distribution. r = dR, v = dV, f = probability density function,
# f_inv = inverse of f
def tables(r, v, f, f_inv):
# compute the x_i
xvec = [0]*(TABLE_LEN+1)
xvec[0] = v / f(r)
xvec[1] = r
for i in range(2, TABLE_LEN):
last = xvec[i-1]
xvec[i] = f_inv(v / last + f(last))
# cache the f's
fvec = [0]*(TABLE_LEN+1)
for i in range(TABLE_LEN+1):
fvec[i] = f(xvec[i])
return xvec, fvec
# Distributions
# N(0, 1)
def norm_f(x):
return exp(-x*x/2.0)
def norm_f_inv(y):
return sqrt(-2.0*log(y))
NORM_R = 3.6541528853610088
NORM_V = 0.00492867323399
NORM = tables(NORM_R, NORM_V,
norm_f, norm_f_inv)
# Exp(1)
def exp_f(x):
return exp(-x)
def exp_f_inv(y):
return -log(y)
EXP_R = 7.69711747013104972
EXP_V = 0.0039496598225815571993
EXP = tables(EXP_R, EXP_V,
exp_f, exp_f_inv)
# Output the tables/constants/types
def render_static(name, type, value):
# no space or
return 'pub static %s: %s =%s;\n' % (name, type, value)
# static `name`: [`type`, .. `len(values)`] =
# [values[0], ..., values[3],
# values[4], ..., values[7],
# ... ];
def render_table(name, values):
rows = []
# 4 values on each row
for i in range(0, len(values), 4):
row = values[i:i+4]
rows.append(', '.join('%.18f' % f for f in row))
rendered = '\n [%s]' % ',\n '.join(rows)
return render_static(name, '[f64, .. %d]' % len(values), rendered)
with open('ziggurat_tables.rs', 'w') as f:
f.write('''// Copyright 2013 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.
// Tables for distributions which are sampled using the ziggurat
// algorithm. Autogenerated by `ziggurat_tables.py`.
pub type ZigTable = &\'static [f64, .. %d];
''' % (TABLE_LEN + 1))
for name, tables, r in [('NORM', NORM, NORM_R),
('EXP', EXP, EXP_R)]:
f.write(render_static('ZIG_%s_R' % name, 'f64', ' %.18f' % r))
for (tabname, table) in zip(TABLE_NAMES, tables):
f.write(render_table('ZIG_%s_%s' % (name, tabname), table))

View file

@ -829,14 +829,13 @@ impl<'a, T: Clone> Option<&'a mut T> {
/// # Examples
///
/// ```
/// #![feature(option_ref_mut_cloned)]
/// let mut x = 12;
/// let opt_x = Some(&mut x);
/// assert_eq!(opt_x, Some(&mut 12));
/// let cloned = opt_x.cloned();
/// assert_eq!(cloned, Some(12));
/// ```
#[unstable(feature = "option_ref_mut_cloned", issue = "43738")]
#[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
pub fn cloned(self) -> Option<T> {
self.map(|t| t.clone())
}

View file

@ -559,6 +559,7 @@ define_dep_nodes!( <'tcx>
[] IsReachableNonGeneric(DefId),
[] IsMirAvailable(DefId),
[] ItemAttrs(DefId),
[] TransFnAttrs(DefId),
[] FnArgNames(DefId),
[] DylibDepFormats(CrateNum),
[] IsPanicRuntime(CrateNum),
@ -626,8 +627,6 @@ define_dep_nodes!( <'tcx>
[input] AllCrateNums,
[] ExportedSymbols(CrateNum),
[eval_always] CollectAndPartitionTranslationItems,
[] ExportName(DefId),
[] ContainsExternIndicator(DefId),
[] IsTranslatedItem(DefId),
[] CodegenUnit(InternedString),
[] CompileCodegenUnit(InternedString),
@ -637,7 +636,6 @@ define_dep_nodes!( <'tcx>
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
[input] TargetFeaturesWhitelist,
[] TargetFeaturesEnabled(DefId),
[] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },

View file

@ -47,7 +47,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
/// Check any attribute.
fn check_attributes(&self, item: &hir::Item, target: Target) {
self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id));
for attr in &item.attrs {
if let Some(name) = attr.name() {

View file

@ -30,12 +30,14 @@ pub use self::Visibility::{Public, Inherited};
use hir::def::Def;
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
use util::nodemap::{NodeMap, FxHashSet};
use mir::mono::Linkage;
use syntax_pos::{Span, DUMMY_SP};
use syntax::codemap::{self, Spanned};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::attr::InlineAttr;
use syntax::ext::hygiene::SyntaxContext;
use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
@ -2210,3 +2212,51 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;
pub fn provide(providers: &mut Providers) {
providers.describe_def = map::describe_def;
}
#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
pub struct TransFnAttrs {
pub flags: TransFnAttrFlags,
pub inline: InlineAttr,
pub export_name: Option<Symbol>,
pub target_features: Vec<Symbol>,
pub linkage: Option<Linkage>,
}
bitflags! {
#[derive(RustcEncodable, RustcDecodable)]
pub struct TransFnAttrFlags: u8 {
const COLD = 0b0000_0001;
const ALLOCATOR = 0b0000_0010;
const UNWIND = 0b0000_0100;
const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000;
const NAKED = 0b0001_0000;
const NO_MANGLE = 0b0010_0000;
const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
}
}
impl TransFnAttrs {
pub fn new() -> TransFnAttrs {
TransFnAttrs {
flags: TransFnAttrFlags::empty(),
inline: InlineAttr::None,
export_name: None,
target_features: vec![],
linkage: None,
}
}
/// True if `#[inline]` or `#[inline(always)]` is present.
pub fn requests_inline(&self) -> bool {
match self.inline {
InlineAttr::Hint | InlineAttr::Always => true,
InlineAttr::None | InlineAttr::Never => false,
}
}
/// True if `#[no_mangle]` or `#[export_name(...)]` is present.
pub fn contains_extern_indicator(&self) -> bool {
self.flags.contains(TransFnAttrFlags::NO_MANGLE) || self.export_name.is_some()
}
}

View file

@ -19,6 +19,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
use std::mem;
use syntax::ast;
use syntax::attr;
impl<'gcx> HashStable<StableHashingContext<'gcx>> for DefId {
#[inline]
@ -1138,6 +1139,43 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::TraitCandidate {
}
}
impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
let hir::TransFnAttrs {
flags,
inline,
export_name,
ref target_features,
linkage,
} = *self;
flags.hash_stable(hcx, hasher);
inline.hash_stable(hcx, hasher);
export_name.hash_stable(hcx, hasher);
target_features.hash_stable(hcx, hasher);
linkage.hash_stable(hcx, hasher);
}
}
impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
self.bits().hash_stable(hcx, hasher);
}
}
impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(struct hir::Freevar {
def,

View file

@ -244,7 +244,6 @@ impl_stable_hash_for!(enum ty::Visibility {
impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
impl<'gcx, A, B> HashStable<StableHashingContext<'gcx>>
@ -274,9 +273,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Predicate<'gcx> {
ty::Predicate::Trait(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::Equate(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::Subtype(ref pred) => {
pred.hash_stable(hcx, hasher);
}

View file

@ -1280,7 +1280,6 @@ impl<'tcx> ObligationCause<'tcx> {
}),
IfExpression => Error0308("if and else have incompatible types"),
IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
EquatePredicate => Error0308("equality predicate not satisfied"),
MainFunctionType => Error0580("main function has wrong type"),
StartFunctionType => Error0308("start function has wrong type"),
IntrinsicType => Error0308("intrinsic has wrong type"),
@ -1309,7 +1308,6 @@ impl<'tcx> ObligationCause<'tcx> {
},
IfExpression => "if and else have compatible types",
IfExpressionWithNoElse => "if missing an else returns ()",
EquatePredicate => "equality where clause is satisfied",
MainFunctionType => "`main` function has the correct type",
StartFunctionType => "`start` function has the correct type",
IntrinsicType => "intrinsic has the correct type",

View file

@ -943,23 +943,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.borrow_region_constraints().make_subregion(origin, a, b);
}
pub fn equality_predicate(&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: &ty::PolyEquatePredicate<'tcx>)
-> InferResult<'tcx, ()>
{
self.commit_if_ok(|snapshot| {
let (ty::EquatePredicate(a, b), skol_map) =
self.skolemize_late_bound_regions(predicate, snapshot);
let cause_span = cause.span;
let eqty_ok = self.at(cause, param_env).eq(b, a)?;
self.leak_check(false, cause_span, &skol_map, snapshot)?;
self.pop_skolemized(skol_map, snapshot);
Ok(eqty_ok.unit())
})
}
pub fn subtype_predicate(&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,

View file

@ -117,7 +117,6 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
assert!(!obligation.has_escaping_regions());
match obligation.predicate {
ty::Predicate::Trait(..) |
ty::Predicate::Equate(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::Projection(..) |
ty::Predicate::ClosureKind(..) |
@ -204,7 +203,6 @@ pub fn explicit_outlives_bounds<'tcx>(
.filter_map(move |predicate| match predicate {
ty::Predicate::Projection(..) |
ty::Predicate::Trait(..) |
ty::Predicate::Equate(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::WellFormed(..) |
ty::Predicate::ObjectSafe(..) |

View file

@ -36,13 +36,12 @@ use session::search_paths::PathKind;
use std::any::Any;
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use rustc_data_structures::owning_ref::ErasedBoxRef;
use syntax::ast;
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_back::target::Target;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::sync::{MetadataRef, Lrc};
pub use self::NativeLibraryKind::*;
@ -186,11 +185,11 @@ pub trait MetadataLoader {
fn get_rlib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String>;
-> Result<MetadataRef, String>;
fn get_dylib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String>;
-> Result<MetadataRef, String>;
}
#[derive(Clone)]

View file

@ -15,6 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.
use hir::TransFnAttrs;
use hir::map as hir_map;
use hir::def::Def;
use hir::def_id::{DefId, CrateNum};
@ -43,8 +44,8 @@ fn generics_require_inlining(generics: &hir::Generics) -> bool {
// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
fn item_might_be_inlined(item: &hir::Item) -> bool {
if attr::requests_inline(&item.attrs) {
fn item_might_be_inlined(item: &hir::Item, attrs: TransFnAttrs) -> bool {
if attrs.requests_inline() {
return true
}
@ -60,14 +61,15 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_item: &hir::ImplItem,
impl_src: DefId) -> bool {
if attr::requests_inline(&impl_item.attrs) ||
let trans_fn_attrs = tcx.trans_fn_attrs(impl_item.hir_id.owner_def_id());
if trans_fn_attrs.requests_inline() ||
generics_require_inlining(&impl_item.generics) {
return true
}
if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
match tcx.hir.find(impl_node_id) {
Some(hir_map::NodeItem(item)) =>
item_might_be_inlined(&item),
item_might_be_inlined(&item, trans_fn_attrs),
Some(..) | None =>
span_bug!(impl_item.span, "impl did is not an item")
}
@ -160,7 +162,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match self.tcx.hir.find(node_id) {
Some(hir_map::NodeItem(item)) => {
match item.node {
hir::ItemFn(..) => item_might_be_inlined(&item),
hir::ItemFn(..) =>
item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)),
_ => false,
}
}
@ -176,8 +179,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match impl_item.node {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Method(..) => {
let attrs = self.tcx.trans_fn_attrs(def_id);
if generics_require_inlining(&impl_item.generics) ||
attr::requests_inline(&impl_item.attrs) {
attrs.requests_inline() {
true
} else {
let impl_did = self.tcx
@ -229,7 +233,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
false
};
let def_id = self.tcx.hir.local_def_id(item.id);
let is_extern = self.tcx.contains_extern_indicator(def_id);
let is_extern = self.tcx.trans_fn_attrs(def_id).contains_extern_indicator();
if reachable || is_extern {
self.reachable_symbols.insert(search_item);
}
@ -246,7 +250,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir_map::NodeItem(item) => {
match item.node {
hir::ItemFn(.., body) => {
if item_might_be_inlined(&item) {
let def_id = self.tcx.hir.local_def_id(item.id);
if item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)) {
self.visit_nested_body(body);
}
}

View file

@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> {
size_estimate: Option<usize>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum Linkage {
External,
AvailableExternally,

View file

@ -631,16 +631,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
}
ty::Predicate::Equate(ref predicate) => {
let predicate = self.resolve_type_vars_if_possible(predicate);
let err = self.equality_predicate(&obligation.cause,
obligation.param_env,
&predicate).err().unwrap();
struct_span_err!(self.tcx.sess, span, E0278,
"the requirement `{}` is not satisfied (`{}`)",
predicate, err)
}
ty::Predicate::RegionOutlives(ref predicate) => {
let predicate = self.resolve_type_vars_if_possible(predicate);
let err = self.region_outlives_predicate(&obligation.cause,
@ -1270,7 +1260,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ObligationCauseCode::MatchExpressionArm { .. } |
ObligationCauseCode::IfExpression |
ObligationCauseCode::IfExpressionWithNoElse |
ObligationCauseCode::EquatePredicate |
ObligationCauseCode::MainFunctionType |
ObligationCauseCode::StartFunctionType |
ObligationCauseCode::IntrinsicType |

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use infer::{RegionObligation, InferCtxt, InferOk};
use infer::{RegionObligation, InferCtxt};
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
use ty::error::ExpectedFound;
use rustc_data_structures::obligation_forest::{ObligationForest, Error};
@ -380,17 +380,6 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}
ty::Predicate::Equate(ref binder) => {
match selcx.infcx().equality_predicate(&obligation.cause,
obligation.param_env,
binder) {
Ok(InferOk { obligations, value: () }) => {
Ok(Some(obligations))
},
Err(_) => Err(CodeSelectionError(Unimplemented)),
}
}
ty::Predicate::RegionOutlives(ref binder) => {
match selcx.infcx().region_outlives_predicate(&obligation.cause, binder) {
Ok(()) => Ok(Some(Vec::new())),

View file

@ -204,9 +204,6 @@ pub enum ObligationCauseCode<'tcx> {
/// Computing common supertype of an if expression with no else counter-part
IfExpressionWithNoElse,
/// `where a == b`
EquatePredicate,
/// `main` has wrong type
MainFunctionType,
@ -854,19 +851,6 @@ impl<'tcx, N> Vtable<'tcx, N> {
}
}
fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
match self {
&mut VtableImpl(ref mut i) => &mut i.nested,
&mut VtableParam(ref mut n) => n,
&mut VtableBuiltin(ref mut i) => &mut i.nested,
&mut VtableAutoImpl(ref mut d) => &mut d.nested,
&mut VtableGenerator(ref mut c) => &mut c.nested,
&mut VtableClosure(ref mut c) => &mut c.nested,
&mut VtableObject(ref mut d) => &mut d.nested,
&mut VtableFnPointer(ref mut d) => &mut d.nested,
}
}
pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
match self {
VtableImpl(i) => VtableImpl(VtableImplData {

View file

@ -175,7 +175,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
ty::Predicate::RegionOutlives(..) |
ty::Predicate::ClosureKind(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::Equate(..) |
ty::Predicate::ConstEvaluatable(..) => {
false
}
@ -204,7 +203,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
ty::Predicate::Projection(..) |
ty::Predicate::Trait(..) |
ty::Predicate::Equate(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::RegionOutlives(..) |
ty::Predicate::WellFormed(..) |

View file

@ -44,12 +44,10 @@ use ty::relate::TypeRelation;
use middle::lang_items;
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
use std::iter;
use std::cell::RefCell;
use std::cmp;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;
use syntax::abi::Abi;
@ -57,14 +55,6 @@ use hir;
use lint;
use util::nodemap::{FxHashMap, FxHashSet};
struct InferredObligationsSnapshotVecDelegate<'tcx> {
phantom: PhantomData<&'tcx i32>,
}
impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
type Value = PredicateObligation<'tcx>;
type Undo = ();
fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
}
pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
/// would satisfy it. This avoids crippling inference, basically.
intercrate: Option<IntercrateMode>,
inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
/// Controls whether or not to filter out negative impls when selecting.
@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: None,
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
}
@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: Some(mode),
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
}
@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: None,
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls,
}
@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn in_snapshot<R, F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
{
// The irrefutable nature of the operation means we don't need to snapshot the
// inferred_obligations vector.
self.infcx.in_snapshot(|snapshot| f(self, snapshot))
}
@ -508,10 +491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn probe<R, F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
{
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
let result = self.infcx.probe(|snapshot| f(self, snapshot));
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
result
self.infcx.probe(|snapshot| f(self, snapshot))
}
/// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
@ -519,17 +499,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
{
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) {
Ok(ok) => {
self.inferred_obligations.commit(inferred_obligations_snapshot);
Ok(ok)
},
Err(err) => {
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
Err(err)
}
}
self.infcx.commit_if_ok(|snapshot| f(self, snapshot))
}
@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
let ret = match self.candidate_from_obligation(&stack)? {
None => None,
Some(candidate) => {
let mut candidate = self.confirm_candidate(obligation, candidate)?;
let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
candidate.nested_obligations_mut().extend(inferred_obligations);
Some(candidate)
},
Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?)
};
// Test whether this is a `()` which was produced by defaulting a
@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
stack: TraitObligationStackList<'o, 'tcx>,
predicates: I)
-> EvaluationResult
where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
{
let mut result = EvaluatedToOk;
for obligation in predicates {
@ -691,22 +656,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
}
ty::Predicate::Equate(ref p) => {
// does this code ever run?
match self.infcx.equality_predicate(&obligation.cause, obligation.param_env, p) {
Ok(InferOk { obligations, .. }) => {
self.inferred_obligations.extend(obligations);
EvaluatedToOk
},
Err(_) => EvaluatedToErr
}
}
ty::Predicate::Subtype(ref p) => {
// does this code ever run?
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
Some(Ok(InferOk { obligations, .. })) => {
self.inferred_obligations.extend(obligations);
self.evaluate_predicates_recursively(previous_stack, &obligations);
EvaluatedToOk
},
Some(Err(_)) => EvaluatedToErr,
@ -1553,12 +1507,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
-> bool
{
assert!(!skol_trait_ref.has_escaping_regions());
match self.infcx.at(&obligation.cause, obligation.param_env)
.sup(ty::Binder(skol_trait_ref), trait_bound) {
Ok(InferOk { obligations, .. }) => {
self.inferred_obligations.extend(obligations);
}
Err(_) => { return false; }
if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env)
.sup(ty::Binder(skol_trait_ref), trait_bound) {
return false;
}
self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok()
@ -2644,6 +2595,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
};
let mut upcast_trait_ref = None;
let mut nested = vec![];
let vtable_base;
{
@ -2662,7 +2614,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.commit_if_ok(
|this, _| this.match_poly_trait_ref(obligation, t))
{
Ok(_) => { upcast_trait_ref = Some(t); false }
Ok(obligations) => {
upcast_trait_ref = Some(t);
nested.extend(obligations);
false
}
Err(_) => { true }
}
});
@ -2680,7 +2636,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
VtableObjectData {
upcast_trait_ref: upcast_trait_ref.unwrap(),
vtable_base,
nested: vec![]
nested,
}
}
@ -2737,7 +2693,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
let Normalized {
value: trait_ref,
obligations
mut obligations
} = normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
@ -2749,10 +2705,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
trait_ref,
obligations);
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?;
obligations.extend(
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?);
Ok(VtableGeneratorData {
closure_def_id: closure_def_id,
@ -2798,10 +2755,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
trait_ref,
obligations);
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?;
obligations.extend(
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?);
obligations.push(Obligation::new(
obligation.cause.clone(),
@ -2845,13 +2803,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
obligation_param_env: ty::ParamEnv<'tcx>,
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
expected_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<(), SelectionError<'tcx>>
-> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
{
let obligation_trait_ref = obligation_trait_ref.clone();
self.infcx
.at(&obligation_cause, obligation_param_env)
.sup(obligation_trait_ref, expected_trait_ref)
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
.map(|InferOk { obligations, .. }| obligations)
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
}
@ -2888,7 +2846,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_trait)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Register one obligation for 'a: 'b.
let cause = ObligationCause::new(obligation.cause.span,
@ -2950,7 +2908,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(b, a)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
}
// Struct<T> -> Struct<U>.
@ -3014,7 +2972,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_struct)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
nested.push(tcx.predicate_for_trait_def(
@ -3045,7 +3003,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_tuple)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Construct the nested T: Unsize<U> predicate.
nested.push(tcx.predicate_for_trait_def(
@ -3118,7 +3076,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
impl_substs);
let impl_trait_ref =
let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
project::normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
@ -3134,12 +3092,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let InferOk { obligations, .. } =
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(skol_obligation_trait_ref, impl_trait_ref.value)
.eq(skol_obligation_trait_ref, impl_trait_ref)
.map_err(|e| {
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
()
})?;
self.inferred_obligations.extend(obligations);
nested_obligations.extend(obligations);
if let Err(e) = self.infcx.leak_check(false,
obligation.cause.span,
@ -3152,7 +3110,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
debug!("match_impl: success impl_substs={:?}", impl_substs);
Ok((Normalized {
value: impl_substs,
obligations: impl_trait_ref.obligations
obligations: nested_obligations
}, skol_map))
}
@ -3189,8 +3147,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<Vec<PredicateObligation<'tcx>>,()>
{
self.match_poly_trait_ref(obligation, where_clause_trait_ref)?;
Ok(Vec::new())
self.match_poly_trait_ref(obligation, where_clause_trait_ref)
}
/// Returns `Ok` if `poly_trait_ref` being true implies that the
@ -3198,7 +3155,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn match_poly_trait_ref(&mut self,
obligation: &TraitObligation<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<(),()>
-> Result<Vec<PredicateObligation<'tcx>>,()>
{
debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
obligation,
@ -3206,7 +3163,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| ())
}

View file

@ -236,7 +236,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
}
super::IfExpression => Some(super::IfExpression),
super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
super::EquatePredicate => Some(super::EquatePredicate),
super::MainFunctionType => Some(super::MainFunctionType),
super::StartFunctionType => Some(super::StartFunctionType),
super::IntrinsicType => Some(super::IntrinsicType),
@ -512,7 +511,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
super::MatchExpressionArm { arm_span: _, source: _ } |
super::IfExpression |
super::IfExpressionWithNoElse |
super::EquatePredicate |
super::MainFunctionType |
super::StartFunctionType |
super::IntrinsicType |
@ -561,7 +559,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
super::MatchExpressionArm { arm_span: _, source: _ } |
super::IfExpression |
super::IfExpressionWithNoElse |
super::EquatePredicate |
super::MainFunctionType |
super::StartFunctionType |
super::IntrinsicType |

View file

@ -25,9 +25,6 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::Predicate::Trait(ref data) =>
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)),
ty::Predicate::Equate(ref data) =>
ty::Predicate::Equate(tcx.anonymize_late_bound_regions(data)),
ty::Predicate::RegionOutlives(ref data) =>
ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)),
@ -163,11 +160,6 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
// Currently, we do not elaborate object-safe
// predicates.
}
ty::Predicate::Equate(..) => {
// Currently, we do not "elaborate" predicates like
// `X == Y`, though conceivably we might. For example,
// `&X == &Y` implies that `X == Y`.
}
ty::Predicate::Subtype(..) => {
// Currently, we do not "elaborate" predicates like `X
// <: Y`, though conceivably we might.

View file

@ -96,7 +96,6 @@ impl<'tcx> InstanceDef<'tcx> {
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>
) -> bool {
use syntax::attr::requests_inline;
if self.is_inline(tcx) {
return true
}
@ -106,8 +105,8 @@ impl<'tcx> InstanceDef<'tcx> {
// available to normal end-users.
return true
}
requests_inline(&self.attrs(tcx)[..]) ||
tcx.is_const_fn(self.def_id())
let trans_fn_attrs = tcx.trans_fn_attrs(self.def_id());
trans_fn_attrs.requests_inline() || tcx.is_const_fn(self.def_id())
}
}

View file

@ -1203,7 +1203,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
}
let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
if pointee.is_sized(tcx, param_env, DUMMY_SP) {
if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
}
@ -1428,7 +1428,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
let param_env = tcx.param_env(def.did);
let last_field = def.variants[v].fields.last().unwrap();
let always_sized = tcx.type_of(last_field.did)
.is_sized(tcx, param_env, DUMMY_SP);
.is_sized(tcx.at(DUMMY_SP), param_env);
if !always_sized { StructKind::MaybeUnsized }
else { StructKind::AlwaysSized }
};

View file

@ -687,8 +687,8 @@ impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
impl_disk_cacheable_query!(contains_extern_indicator, |_| true);
impl_disk_cacheable_query!(def_symbol_name, |_| true);
impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
impl_disk_cacheable_query!(trans_fn_attrs, |_| true);

View file

@ -12,7 +12,7 @@ use dep_graph::{DepConstructor, DepNode};
use errors::DiagnosticBuilder;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::def::{Def, Export};
use hir::{self, TraitCandidate, ItemLocalId};
use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs};
use hir::svh::Svh;
use lint;
use middle::borrowck::BorrowCheckResult;
@ -235,6 +235,7 @@ define_maps! { <'tcx>
[] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
[] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
[] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
[] fn trans_fn_attrs: trans_fn_attrs(DefId) -> TransFnAttrs,
[] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
[] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
@ -362,8 +363,6 @@ define_maps! { <'tcx>
[] fn collect_and_partition_translation_items:
collect_and_partition_translation_items_node(CrateNum)
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
[] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
[] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
@ -385,7 +384,6 @@ define_maps! { <'tcx>
[] fn target_features_whitelist:
target_features_whitelist_node(CrateNum) -> Lrc<FxHashSet<String>>,
[] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Lrc<Vec<String>>,
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
@ -403,6 +401,10 @@ fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::Features
}
fn trans_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
DepConstructor::TransFnAttrs { 0: id }
}
fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
DepConstructor::EraseRegionsTy { ty }
}

View file

@ -217,9 +217,9 @@ impl<'sess> OnDiskCache<'sess> {
encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
encode_query_results::<check_match, _>(tcx, enc, qri)?;
encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
}
// Encode diagnostics

View file

@ -854,6 +854,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
DepKind::TransFnAttrs => { force!(trans_fn_attrs, def_id!()); }
DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
@ -925,15 +926,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::CollectAndPartitionTranslationItems => {
force!(collect_and_partition_translation_items, LOCAL_CRATE);
}
DepKind::ExportName => { force!(export_name, def_id!()); }
DepKind::ContainsExternIndicator => {
force!(contains_extern_indicator, def_id!());
}
DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); }
DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }
DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
DepKind::Features => { force!(features_query, LOCAL_CRATE); }
@ -997,10 +993,10 @@ impl_load_from_cache!(
MirConstQualif => mir_const_qualif,
SymbolName => def_symbol_name,
ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
ContainsExternIndicator => contains_extern_indicator,
CheckMatch => check_match,
TypeOfItem => type_of,
GenericsOfItem => generics_of,
PredicatesOfItem => predicates_of,
UsedTraitImports => used_trait_imports,
TransFnAttrs => trans_fn_attrs,
);

View file

@ -912,9 +912,6 @@ pub enum Predicate<'tcx> {
/// would be the type parameters.
Trait(PolyTraitPredicate<'tcx>),
/// where `T1 == T2`.
Equate(PolyEquatePredicate<'tcx>),
/// where 'a : 'b
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
@ -1023,8 +1020,6 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
match *self {
Predicate::Trait(ty::Binder(ref data)) =>
Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
Predicate::Equate(ty::Binder(ref data)) =>
Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
Predicate::Subtype(ty::Binder(ref data)) =>
Predicate::Subtype(ty::Binder(data.subst(tcx, substs))),
Predicate::RegionOutlives(ty::Binder(ref data)) =>
@ -1072,10 +1067,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
@ -1166,12 +1157,6 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
}
}
impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
fn to_predicate(&self) -> Predicate<'tcx> {
Predicate::Equate(self.clone())
}
}
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
fn to_predicate(&self) -> Predicate<'tcx> {
Predicate::RegionOutlives(self.clone())
@ -1199,9 +1184,6 @@ impl<'tcx> Predicate<'tcx> {
ty::Predicate::Trait(ref data) => {
data.skip_binder().input_types().collect()
}
ty::Predicate::Equate(ty::Binder(ref data)) => {
vec![data.0, data.1]
}
ty::Predicate::Subtype(ty::Binder(SubtypePredicate { a, b, a_is_expected: _ })) => {
vec![a, b]
}
@ -1242,7 +1224,6 @@ impl<'tcx> Predicate<'tcx> {
Some(t.to_poly_trait_ref())
}
Predicate::Projection(..) |
Predicate::Equate(..) |
Predicate::Subtype(..) |
Predicate::RegionOutlives(..) |
Predicate::WellFormed(..) |
@ -1262,7 +1243,6 @@ impl<'tcx> Predicate<'tcx> {
}
Predicate::Trait(..) |
Predicate::Projection(..) |
Predicate::Equate(..) |
Predicate::Subtype(..) |
Predicate::RegionOutlives(..) |
Predicate::WellFormed(..) |

View file

@ -282,14 +282,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
type Lifted = ty::EquatePredicate<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
-> Option<ty::EquatePredicate<'tcx>> {
tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
type Lifted = ty::SubtypePredicate<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
@ -355,9 +347,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
ty::Predicate::Trait(ref binder) => {
tcx.lift(binder).map(ty::Predicate::Trait)
}
ty::Predicate::Equate(ref binder) => {
tcx.lift(binder).map(ty::Predicate::Equate)
}
ty::Predicate::Subtype(ref binder) => {
tcx.lift(binder).map(ty::Predicate::Subtype)
}
@ -1049,8 +1038,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
match *self {
ty::Predicate::Trait(ref a) =>
ty::Predicate::Trait(a.fold_with(folder)),
ty::Predicate::Equate(ref binder) =>
ty::Predicate::Equate(binder.fold_with(folder)),
ty::Predicate::Subtype(ref binder) =>
ty::Predicate::Subtype(binder.fold_with(folder)),
ty::Predicate::RegionOutlives(ref binder) =>
@ -1073,7 +1060,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ty::Predicate::Trait(ref a) => a.visit_with(visitor),
ty::Predicate::Equate(ref binder) => binder.visit_with(visitor),
ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor),
ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
@ -1111,16 +1097,6 @@ BraceStructTypeFoldableImpl! {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::EquatePredicate(self.0.fold_with(folder), self.1.fold_with(folder))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.0.visit_with(visitor) || self.1.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::SubtypePredicate {

View file

@ -20,6 +20,7 @@ use traits::{self, Reveal};
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::fold::TypeVisitor;
use ty::subst::{Subst, UnpackedKind};
use ty::maps::TyCtxtAt;
use ty::TypeVariants::*;
use util::common::ErrorReported;
use middle::lang_items;
@ -385,7 +386,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
match predicate {
ty::Predicate::Projection(..) |
ty::Predicate::Trait(..) |
ty::Predicate::Equate(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::WellFormed(..) |
ty::Predicate::ObjectSafe(..) |
@ -864,11 +864,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
}
pub fn is_sized(&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
span: Span)-> bool
tcx_at: TyCtxtAt<'a, 'tcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>)-> bool
{
tcx.at(span).is_sized_raw(param_env.and(self))
tcx_at.is_sized_raw(param_env.and(self))
}
pub fn is_freeze(&'tcx self,

View file

@ -77,10 +77,6 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
ty::Predicate::Trait(ref t) => {
wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
}
ty::Predicate::Equate(ref t) => {
wf.compute(t.skip_binder().0);
wf.compute(t.skip_binder().1);
}
ty::Predicate::RegionOutlives(..) => {
}
ty::Predicate::TypeOutlives(ref t) => {

View file

@ -939,7 +939,6 @@ define_print_multi! {
('tcx) ty::Binder<ty::TraitRef<'tcx>>,
('tcx) ty::Binder<ty::FnSig<'tcx>>,
('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
('tcx) ty::Binder<ty::EquatePredicate<'tcx>>,
('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
@ -1217,14 +1216,6 @@ define_print! {
}
}
define_print! {
('tcx) ty::EquatePredicate<'tcx>, (self, f, cx) {
display {
print!(f, cx, print(self.0), write(" == "), print(self.1))
}
}
}
define_print! {
('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) {
display {
@ -1292,7 +1283,6 @@ define_print! {
display {
match *self {
ty::Predicate::Trait(ref data) => data.print(f, cx),
ty::Predicate::Equate(ref predicate) => predicate.print(f, cx),
ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx),
ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx),
ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx),
@ -1317,7 +1307,6 @@ define_print! {
debug {
match *self {
ty::Predicate::Trait(ref a) => a.print(f, cx),
ty::Predicate::Equate(ref pair) => pair.print(f, cx),
ty::Predicate::Subtype(ref pair) => pair.print(f, cx),
ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx),
ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx),

View file

@ -243,6 +243,7 @@ fn main() {
```
*/
use std::mem;
pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress};
/// An owning reference.
@ -279,7 +280,7 @@ pub struct OwningRefMut<O, T: ?Sized> {
pub trait Erased {}
impl<T> Erased for T {}
/// Helper trait for erasing the concrete type of what an owner derferences to,
/// Helper trait for erasing the concrete type of what an owner dereferences to,
/// for example `Box<T> -> Box<Erased>`. This would be unneeded with
/// higher kinded types support in the language.
pub unsafe trait IntoErased<'a> {
@ -289,10 +290,20 @@ pub unsafe trait IntoErased<'a> {
fn into_erased(self) -> Self::Erased;
}
/// Helper trait for erasing the concrete type of what an owner derferences to,
/// Helper trait for erasing the concrete type of what an owner dereferences to,
/// for example `Box<T> -> Box<Erased + Send>`. This would be unneeded with
/// higher kinded types support in the language.
pub unsafe trait IntoErasedSend<'a> {
/// Owner with the dereference type substituted to `Erased + Send`.
type Erased: Send;
/// Perform the type erasure.
fn into_erased_send(self) -> Self::Erased;
}
/// Helper trait for erasing the concrete type of what an owner dereferences to,
/// for example `Box<T> -> Box<Erased + Send + Sync>`. This would be unneeded with
/// higher kinded types support in the language.
pub unsafe trait IntoErasedSendSync<'a>: Send + Sync {
pub unsafe trait IntoErasedSendSync<'a> {
/// Owner with the dereference type substituted to `Erased + Send + Sync`.
type Erased: Send + Sync;
/// Perform the type erasure.
@ -472,6 +483,18 @@ impl<O, T: ?Sized> OwningRef<O, T> {
}
}
/// Erases the concrete base type of the owner with a trait object which implements `Send`.
///
/// This allows mixing of owned references with different owner base types.
pub fn erase_send_owner<'a>(self) -> OwningRef<O::Erased, T>
where O: IntoErasedSend<'a>,
{
OwningRef {
reference: self.reference,
owner: self.owner.into_erased_send(),
}
}
/// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`.
///
/// This allows mixing of owned references with different owner base types.
@ -1161,13 +1184,25 @@ unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
}
}
unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box<T> {
type Erased = Box<Erased + Send + Sync + 'a>;
fn into_erased_send_sync(self) -> Self::Erased {
unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
type Erased = Box<Erased + Send + 'a>;
fn into_erased_send(self) -> Self::Erased {
self
}
}
unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
type Erased = Box<Erased + Sync + Send + 'a>;
fn into_erased_send_sync(self) -> Self::Erased {
let result: Box<Erased + Send + 'a> = self;
// This is safe since Erased can always implement Sync
// Only the destructor is available and it takes &mut self
unsafe {
mem::transmute(result)
}
}
}
unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
type Erased = Arc<Erased + Send + Sync + 'a>;
fn into_erased_send_sync(self) -> Self::Erased {

View file

@ -177,7 +177,7 @@ cfg_if! {
macro_rules! rustc_erase_owner {
($v:expr) => {{
let v = $v;
::rustc_data_structures::sync::assert_send_sync_val(&v);
::rustc_data_structures::sync::assert_send_val(&v);
v.erase_send_sync_owner()
}}
}
@ -262,6 +262,7 @@ cfg_if! {
}
pub fn assert_sync<T: ?Sized + Sync>() {}
pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
#[macro_export]

View file

@ -22,6 +22,8 @@ pub struct ArchiveRO {
ptr: ArchiveRef,
}
unsafe impl Send for ArchiveRO {}
pub struct Iter<'a> {
archive: &'a ArchiveRO,
ptr: ::ArchiveIteratorRef,

View file

@ -221,6 +221,8 @@ pub struct ObjectFile {
pub llof: ObjectFileRef,
}
unsafe impl Send for ObjectFile {}
impl ObjectFile {
// This will take ownership of llmb
pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {

View file

@ -24,7 +24,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
use std::cell::{RefCell, Cell};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::owning_ref::ErasedBoxRef;
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
@ -42,7 +41,9 @@ pub use cstore_impl::{provide, provide_extern};
// own crate numbers.
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
pub use rustc_data_structures::sync::MetadataRef;
pub struct MetadataBlob(pub MetadataRef);
/// Holds information about a syntax_pos::FileMap imported from another crate.
/// See `imported_filemaps()` for more information.

View file

@ -832,7 +832,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} else if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
let generics = self.tcx.generics_of(def_id);
let types = generics.parent_types as usize + generics.types.len();
let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs);
let needs_inline = types > 0 || tcx.trans_fn_attrs(def_id).requests_inline();
let is_const_fn = sig.constness == hir::Constness::Const;
let ast = if is_const_fn { Some(body) } else { None };
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
@ -1123,7 +1123,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
hir::ItemFn(_, _, constness, _, ref generics, _) => {
let has_tps = generics.ty_params().next().is_some();
let needs_inline = has_tps || attr::requests_inline(&item.attrs);
let needs_inline = has_tps || tcx.trans_fn_attrs(def_id).requests_inline();
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
if needs_inline || constness == hir::Constness::Const || always_encode_mir {
self.encode_optimized_mir(def_id)

View file

@ -39,6 +39,7 @@ extern crate proc_macro;
#[macro_use]
extern crate rustc;
extern crate rustc_back;
#[macro_use]
extern crate rustc_data_structures;
mod diagnostics;

View file

@ -219,7 +219,7 @@
//! no means all of the necessary details. Take a look at the rest of
//! metadata::locator or metadata::creader for all the juicy details!
use cstore::MetadataBlob;
use cstore::{MetadataRef, MetadataBlob};
use creader::Library;
use schema::{METADATA_HEADER, rustc_version};
@ -243,8 +243,8 @@ use std::path::{Path, PathBuf};
use std::time::Instant;
use flate2::read::DeflateDecoder;
use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
use rustc_data_structures::owning_ref::OwningRef;
pub struct CrateMismatch {
path: PathBuf,
got: String,
@ -842,7 +842,7 @@ fn get_metadata_section_imp(target: &Target,
if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display()));
}
let raw_bytes: ErasedBoxRef<[u8]> = match flavor {
let raw_bytes: MetadataRef = match flavor {
CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
CrateFlavor::Dylib => {
let buf = loader.get_dylib_metadata(target, filename)?;
@ -862,7 +862,7 @@ fn get_metadata_section_imp(target: &Target,
match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
Ok(_) => {
let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
buf.map_owner_box().erase_owner()
rustc_erase_owner!(buf.map_owner_box())
}
Err(_) => {
return Err(format!("failed to decompress metadata: {}", filename.display()));
@ -872,7 +872,7 @@ fn get_metadata_section_imp(target: &Target,
CrateFlavor::Rmeta => {
let buf = fs::read(filename).map_err(|_|
format!("failed to read rmeta metadata: '{}'", filename.display()))?;
OwningRef::new(buf).map_owner_box().erase_owner()
rustc_erase_owner!(OwningRef::new(buf).map_owner_box())
}
};
let blob = MetadataBlob(raw_bytes);

View file

@ -1208,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
// shouldn't affect `is_sized`.
let gcx = self.tcx().global_tcx();
let erased_ty = gcx.lift(&self.tcx().erase_regions(&ty)).unwrap();
if !erased_ty.is_sized(gcx, self.param_env, span) {
if !erased_ty.is_sized(gcx.at(span), self.param_env) {
// in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough

View file

@ -286,7 +286,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
}
pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
ty.is_sized(self.tcx, self.param_env, DUMMY_SP)
ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env)
}
pub fn load_mir(

View file

@ -188,7 +188,7 @@
//! this is not implemented however: a mono item will be produced
//! regardless of whether it is actually needed or not.
use rustc::hir;
use rustc::hir::{self, TransFnAttrFlags};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::map as hir_map;
@ -211,8 +211,6 @@ use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode};
use rustc_data_structures::bitvec::BitVector;
use syntax::attr;
use std::iter;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
@ -796,7 +794,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
if ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) {
return false;
}
let tail = tcx.struct_tail(ty);
@ -985,8 +983,8 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
MonoItemCollectionMode::Lazy => {
self.entry_fn == Some(def_id) ||
self.tcx.is_reachable_non_generic(def_id) ||
attr::contains_name(&self.tcx.get_attrs(def_id),
"rustc_std_internal_symbol")
self.tcx.trans_fn_attrs(def_id).flags.contains(
TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
}
}
}

View file

@ -21,7 +21,7 @@ use rustc::session::config::OptLevel;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use syntax::ast;
use syntax::attr::{self, InlineAttr};
use syntax::attr::InlineAttr;
use std::fmt::{self, Write};
use std::iter;
use rustc::mir::mono::Linkage;
@ -29,33 +29,6 @@ use syntax_pos::symbol::Symbol;
use syntax::codemap::Span;
pub use rustc::mir::mono::MonoItem;
pub fn linkage_by_name(name: &str) -> Option<Linkage> {
use rustc::mir::mono::Linkage::*;
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
// applicable to variable declarations and may not really make sense for
// Rust code in the first place but whitelist them anyway and trust that
// the user knows what s/he's doing. Who knows, unanticipated use cases
// may pop up in the future.
//
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
// and don't have to be, LLVM treats them as no-ops.
match name {
"appending" => Some(Appending),
"available_externally" => Some(AvailableExternally),
"common" => Some(Common),
"extern_weak" => Some(ExternalWeak),
"external" => Some(External),
"internal" => Some(Internal),
"linkonce" => Some(LinkOnceAny),
"linkonce_odr" => Some(LinkOnceODR),
"private" => Some(Private),
"weak" => Some(WeakAny),
"weak_odr" => Some(WeakODR),
_ => None,
}
}
/// Describes how a translation item will be instantiated in object files.
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum InstantiationMode {
@ -141,8 +114,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
// creating one copy of this `#[inline]` function which may
// conflict with upstream crates as it could be an exported
// symbol.
let attrs = instance.def.attrs(tcx);
match attr::find_inline_attr(Some(tcx.sess.diagnostic()), &attrs) {
match tcx.trans_fn_attrs(instance.def_id()).inline {
InlineAttr::Always => InstantiationMode::LocalCopy,
_ => {
InstantiationMode::GloballyShared { may_conflict: true }
@ -165,21 +137,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
MonoItem::GlobalAsm(..) => return None,
};
let attributes = tcx.get_attrs(def_id);
if let Some(name) = attr::first_attr_value_str_by_name(&attributes, "linkage") {
if let Some(linkage) = linkage_by_name(&name.as_str()) {
Some(linkage)
} else {
let span = tcx.hir.span_if_local(def_id);
if let Some(span) = span {
tcx.sess.span_fatal(span, "invalid linkage specified")
} else {
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
}
}
} else {
None
}
let trans_fn_attrs = tcx.trans_fn_attrs(def_id);
trans_fn_attrs.linkage
}
/// Returns whether this instance is instantiable - whether it has no unsatisfied

View file

@ -11,6 +11,7 @@
//! Inlining pass for MIR functions
use rustc::hir;
use rustc::hir::TransFnAttrFlags;
use rustc::hir::def_id::DefId;
use rustc_data_structures::bitvec::BitVector;
@ -206,10 +207,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
return false;
}
let attrs = tcx.get_attrs(callsite.callee);
let hint = attr::find_inline_attr(None, &attrs[..]);
let trans_fn_attrs = tcx.trans_fn_attrs(callsite.callee);
let hinted = match hint {
let hinted = match trans_fn_attrs.inline {
// Just treat inline(always) as a hint for now,
// there are cases that prevent inlining that we
// need to check for first.
@ -239,7 +239,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
};
// Significantly lower the threshold for inlining cold functions
if attr::contains_name(&attrs[..], "cold") {
if trans_fn_attrs.flags.contains(TransFnAttrFlags::COLD) {
threshold /= 5;
}
@ -344,7 +344,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
}
}
if let attr::InlineAttr::Always = hint {
if let attr::InlineAttr::Always = trans_fn_attrs.inline {
debug!("INLINING {:?} because inline(always) [cost={}]", callsite, cost);
true
} else {

View file

@ -1665,17 +1665,23 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
if !self.span.filter_generated(sub_span, ex.span) {
let span =
self.span_from_span(sub_span.expect("No span found for var ref"));
let ref_id =
::id_from_def_id(def.non_enum_variant().fields[idx.node].did);
self.dumper.dump_ref(Ref {
kind: RefKind::Variable,
span,
ref_id,
});
if let Some(field) = def.non_enum_variant().fields.get(idx.node) {
let ref_id = ::id_from_def_id(field.did);
self.dumper.dump_ref(Ref {
kind: RefKind::Variable,
span,
ref_id,
});
} else {
return;
}
}
}
ty::TyTuple(..) => {}
_ => span_bug!(ex.span, "Expected struct or tuple type, found {:?}", ty),
_ => {
debug!("Expected struct or tuple type, found {:?}", ty);
return;
}
}
}
ast::ExprKind::Closure(_, _, ref decl, ref body, _fn_decl_span) => {

View file

@ -11,19 +11,16 @@
use std::ffi::{CStr, CString};
use rustc::hir::Unsafety;
use rustc::hir::TransFnAttrFlags;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::session::config::Sanitizer;
use rustc::ty::TyCtxt;
use rustc::ty::maps::Providers;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use llvm::{self, Attribute, ValueRef};
use llvm::AttributePlace::Function;
use llvm_util;
pub use syntax::attr::{self, InlineAttr};
use syntax::ast;
use context::CodegenCx;
/// Mark LLVM function to use provided inline heuristic.
@ -102,31 +99,42 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
use syntax::attr::*;
let attrs = cx.tcx.get_attrs(id);
inline(llfn, find_inline_attr(Some(cx.sess().diagnostic()), &attrs));
let trans_fn_attrs = cx.tcx.trans_fn_attrs(id);
inline(llfn, trans_fn_attrs.inline);
set_frame_pointer_elimination(cx, llfn);
set_probestack(cx, llfn);
for attr in attrs.iter() {
if attr.check_name("cold") {
Attribute::Cold.apply_llfn(Function, llfn);
} else if attr.check_name("naked") {
naked(llfn, true);
} else if attr.check_name("allocator") {
Attribute::NoAlias.apply_llfn(
llvm::AttributePlace::ReturnValue, llfn);
} else if attr.check_name("unwind") {
unwind(llfn, true);
} else if attr.check_name("rustc_allocator_nounwind") {
unwind(llfn, false);
}
if trans_fn_attrs.flags.contains(TransFnAttrFlags::COLD) {
Attribute::Cold.apply_llfn(Function, llfn);
}
if trans_fn_attrs.flags.contains(TransFnAttrFlags::NAKED) {
naked(llfn, true);
}
if trans_fn_attrs.flags.contains(TransFnAttrFlags::ALLOCATOR) {
Attribute::NoAlias.apply_llfn(
llvm::AttributePlace::ReturnValue, llfn);
}
if trans_fn_attrs.flags.contains(TransFnAttrFlags::UNWIND) {
unwind(llfn, true);
}
if trans_fn_attrs.flags.contains(TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
unwind(llfn, false);
}
let target_features = cx.tcx.target_features_enabled(id);
if !target_features.is_empty() {
let val = CString::new(target_features.join(",")).unwrap();
let features =
trans_fn_attrs.target_features
.iter()
.map(|f| {
let feature = &*f.as_str();
format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
})
.collect::<Vec<String>>()
.join(",");
if !features.is_empty() {
let val = CString::new(features).unwrap();
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
cstr("target-features\0"), &val);
@ -145,89 +153,4 @@ pub fn provide(providers: &mut Providers) {
.map(|c| c.to_string())
.collect())
};
providers.target_features_enabled = |tcx, id| {
let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
let mut target_features = Vec::new();
for attr in tcx.get_attrs(id).iter() {
if !attr.check_name("target_feature") {
continue
}
if let Some(val) = attr.value_str() {
for feat in val.as_str().split(",").map(|f| f.trim()) {
if !feat.is_empty() && !feat.contains('\0') {
target_features.push(feat.to_string());
}
}
let msg = "#[target_feature = \"..\"] is deprecated and will \
eventually be removed, use \
#[target_feature(enable = \"..\")] instead";
tcx.sess.span_warn(attr.span, &msg);
continue
}
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
let msg = "#[target_feature(..)] can only be applied to \
`unsafe` function";
tcx.sess.span_err(attr.span, msg);
}
from_target_feature(tcx, attr, &whitelist, &mut target_features);
}
Lrc::new(target_features)
};
}
fn from_target_feature(
tcx: TyCtxt,
attr: &ast::Attribute,
whitelist: &FxHashSet<String>,
target_features: &mut Vec<String>,
) {
let list = match attr.meta_item_list() {
Some(list) => list,
None => {
let msg = "#[target_feature] attribute must be of the form \
#[target_feature(..)]";
tcx.sess.span_err(attr.span, &msg);
return
}
};
for item in list {
if !item.check_name("enable") {
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
currently";
tcx.sess.span_err(item.span, &msg);
continue
}
let value = match item.value_str() {
Some(list) => list,
None => {
let msg = "#[target_feature] attribute must be of the form \
#[target_feature(enable = \"..\")]";
tcx.sess.span_err(item.span, &msg);
continue
}
};
let value = value.as_str();
for feature in value.split(',') {
if whitelist.contains(feature) {
let llvm_feature = llvm_util::to_llvm_feature(&tcx.sess, feature);
target_features.push(format!("+{}", llvm_feature));
continue
}
let msg = format!("the feature named `{}` is not valid for \
this target", feature);
let mut err = tcx.sess.struct_span_err(item.span, &msg);
if feature.starts_with("+") {
let valid = whitelist.contains(&feature[1..]);
if valid {
err.help("consider removing the leading `+` in the feature name");
}
}
err.emit();
}
}
}

View file

@ -13,6 +13,7 @@ use std::sync::Arc;
use monomorphize::Instance;
use rustc::hir;
use rustc::hir::TransFnAttrFlags;
use rustc::hir::def_id::CrateNum;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name};
@ -21,7 +22,6 @@ use rustc::ty::{TyCtxt, SymbolName};
use rustc::ty::maps::Providers;
use rustc::util::nodemap::{FxHashMap, DefIdSet};
use rustc_allocator::ALLOCATOR_METHODS;
use syntax::attr;
pub type ExportedSymbols = FxHashMap<
CrateNum,
@ -256,9 +256,10 @@ fn symbol_export_level_provider(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportL
// special symbols in the standard library for various plumbing between
// core/std/allocators/etc. For example symbols used to hook up allocation
// are not considered for export
let is_extern = tcx.contains_extern_indicator(sym_def_id);
let std_internal = attr::contains_name(&tcx.get_attrs(sym_def_id),
"rustc_std_internal_symbol");
let trans_fn_attrs = tcx.trans_fn_attrs(sym_def_id);
let is_extern = trans_fn_attrs.contains_extern_indicator();
let std_internal = trans_fn_attrs.flags.contains(TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
if is_extern && !std_internal {
SymbolExportLevel::C
} else {

View file

@ -90,7 +90,6 @@ use syntax::ast;
use mir::operand::OperandValue;
pub use rustc_trans_utils::check_for_rustc_errors_attr;
pub use rustc_mir::monomorphize::item::linkage_by_name;
pub struct StatRecorder<'a, 'tcx: 'a> {
cx: &'a CodegenCx<'a, 'tcx>,

View file

@ -44,7 +44,7 @@ pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> b
}
pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All))
}
pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {

View file

@ -146,20 +146,12 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
hir_map::NodeForeignItem(&hir::ForeignItem {
ref attrs, span, node: hir::ForeignItemStatic(..), ..
}) => {
let g = if let Some(name) =
attr::first_attr_value_str_by_name(&attrs, "linkage") {
let g = if let Some(linkage) = cx.tcx.trans_fn_attrs(def_id).linkage {
// If this is a static with a linkage specified, then we need to handle
// it a little specially. The typesystem prevents things like &T and
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
let linkage = match base::linkage_by_name(&name.as_str()) {
Some(linkage) => linkage,
None => {
cx.sess().span_fatal(span, "invalid linkage specified");
}
};
let llty2 = match ty.sty {
ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
_ => {

View file

@ -435,7 +435,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) {
return false;
}

View file

@ -50,7 +50,7 @@ extern crate rustc_allocator;
extern crate rustc_apfloat;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_data_structures;
#[macro_use] extern crate rustc_data_structures;
extern crate rustc_demangle;
extern crate rustc_incremental;
extern crate rustc_llvm as llvm;

View file

@ -15,17 +15,19 @@ use llvm;
use llvm::{False, ObjectFile, mk_section_iter};
use llvm::archive_ro::ArchiveRO;
use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
use rustc_data_structures::owning_ref::OwningRef;
use std::path::Path;
use std::ptr;
use std::slice;
pub use rustc_data_structures::sync::MetadataRef;
pub const METADATA_FILENAME: &str = "rust.metadata.bin";
pub struct LlvmMetadataLoader;
impl MetadataLoader for LlvmMetadataLoader {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
// internally to read the file. We also avoid even using a memcpy by
// just keeping the archive along while the metadata is in use.
@ -47,13 +49,13 @@ impl MetadataLoader for LlvmMetadataLoader {
filename.display())
})
})?;
Ok(buf.erase_owner())
Ok(rustc_erase_owner!(buf))
}
fn get_dylib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String> {
-> Result<MetadataRef, String> {
unsafe {
let buf = common::path2cstr(filename);
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
@ -65,7 +67,7 @@ impl MetadataLoader for LlvmMetadataLoader {
.ok_or_else(|| format!("provided path not an object file: '{}'",
filename.display()))?;
let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
Ok(buf.erase_owner())
Ok(rustc_erase_owner!(buf))
}
}
}

View file

@ -1,38 +0,0 @@
// 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.
#![allow(non_snake_case)]
register_long_diagnostics! {
E0558: r##"
The `export_name` attribute was malformed.
Erroneous code example:
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}
fn main() {}
```
The `export_name` attribute expects a string in order to determine the name of
the exported symbol. Example:
```
#[export_name = "some_function"] // ok!
pub fn something() {}
fn main() {}
```
"##,
}

View file

@ -37,16 +37,14 @@ extern crate rustc;
extern crate rustc_back;
extern crate rustc_mir;
extern crate rustc_incremental;
#[macro_use]
extern crate syntax;
extern crate syntax_pos;
extern crate rustc_data_structures;
#[macro_use] extern crate rustc_data_structures;
pub extern crate rustc as __rustc;
use rustc::ty::TyCtxt;
pub mod diagnostics;
pub mod link;
pub mod trans_crate;
pub mod symbol_names;

View file

@ -120,29 +120,6 @@ pub fn provide(providers: &mut Providers) {
def_symbol_name,
symbol_name,
export_name: |tcx, id| {
tcx.get_attrs(id).iter().fold(None, |ia, attr| {
if attr.check_name("export_name") {
if let s @ Some(_) = attr.value_str() {
s
} else {
struct_span_err!(tcx.sess, attr.span, E0558,
"export_name attribute has invalid format")
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
.emit();
None
}
} else {
ia
}
})
},
contains_extern_indicator: |tcx, id| {
attr::contains_name(&tcx.get_attrs(id), "no_mangle") ||
tcx.export_name(id).is_some()
},
..*providers
};
}
@ -287,7 +264,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
return tcx.item_name(def_id).to_string();
}
if let Some(name) = tcx.export_name(def_id) {
if let Some(name) = tcx.trans_fn_attrs(def_id).export_name {
// Use provided name
return name.to_string();
}

View file

@ -28,7 +28,7 @@ use std::fs::File;
use std::path::Path;
use std::sync::mpsc;
use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::sync::Lrc;
use ar::{Archive, Builder, Header};
use flate2::Compression;
@ -44,9 +44,12 @@ use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc_back::target::Target;
use rustc_data_structures::fx::FxHashSet;
use rustc_mir::monomorphize::collector;
use link::{build_link_meta, out_filename};
pub use rustc_data_structures::sync::MetadataRef;
pub trait TransCrate {
fn init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {}
@ -119,7 +122,7 @@ impl MetadataLoader for DummyMetadataLoader {
&self,
_target: &Target,
_filename: &Path
) -> Result<ErasedBoxRef<[u8]>, String> {
) -> Result<MetadataRef, String> {
bug!("DummyMetadataLoader::get_rlib_metadata");
}
@ -127,7 +130,7 @@ impl MetadataLoader for DummyMetadataLoader {
&self,
_target: &Target,
_filename: &Path
) -> Result<ErasedBoxRef<[u8]>, String> {
) -> Result<MetadataRef, String> {
bug!("DummyMetadataLoader::get_dylib_metadata");
}
}
@ -135,7 +138,7 @@ impl MetadataLoader for DummyMetadataLoader {
pub struct NoLlvmMetadataLoader;
impl MetadataLoader for NoLlvmMetadataLoader {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
let file = File::open(filename)
.map_err(|e| format!("metadata file open err: {:?}", e))?;
let mut archive = Archive::new(file);
@ -147,7 +150,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
let mut buf = Vec::new();
io::copy(&mut entry, &mut buf).unwrap();
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
return Ok(buf.map_owner_box().erase_owner());
return Ok(rustc_erase_owner!(buf.map_owner_box()));
}
}
@ -158,7 +161,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
&self,
_target: &Target,
_filename: &Path,
) -> Result<ErasedBoxRef<[u8]>, String> {
) -> Result<MetadataRef, String> {
// FIXME: Support reading dylibs from llvm enabled rustc
self.get_rlib_metadata(_target, _filename)
}
@ -198,8 +201,9 @@ impl TransCrate for MetadataOnlyTransCrate {
fn provide(&self, providers: &mut Providers) {
::symbol_names::provide(providers);
providers.target_features_enabled = |_tcx, _id| {
Lrc::new(Vec::new()) // Just a dummy
providers.target_features_whitelist = |_tcx, _cnum| {
Lrc::new(FxHashSet()) // Just a dummy
};
}
fn provide_extern(&self, _providers: &mut Providers) {}
@ -233,12 +237,8 @@ impl TransCrate for MetadataOnlyTransCrate {
MonoItem::Fn(inst) => {
let def_id = inst.def_id();
if def_id.is_local() {
let _ = tcx.export_name(def_id);
let _ = tcx.contains_extern_indicator(def_id);
let _ = inst.def.is_inline(tcx);
let attrs = inst.def.attrs(tcx);
let _ =
::syntax::attr::find_inline_attr(Some(tcx.sess.diagnostic()), &attrs);
let _ = tcx.trans_fn_attrs(def_id);
}
}
_ => {}

View file

@ -255,7 +255,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let opt_trait_ref = match obligation.predicate {
ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)),
ty::Predicate::Trait(ref data) => Some(data.to_poly_trait_ref()),
ty::Predicate::Equate(..) => None,
ty::Predicate::Subtype(..) => None,
ty::Predicate::RegionOutlives(..) => None,
ty::Predicate::TypeOutlives(..) => None,

View file

@ -635,7 +635,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
_ => None,
}
}
ty::Predicate::Equate(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::Projection(..) |
ty::Predicate::RegionOutlives(..) |

View file

@ -30,25 +30,29 @@ use constrained_type_params as ctp;
use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use middle::resolve_lifetime as rl;
use rustc::mir::mono::Linkage;
use rustc::traits::Reveal;
use rustc::ty::subst::Substs;
use rustc::ty::{ToPredicate, ReprOptions};
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::ty::util::IntTypeExt;
use rustc::util::nodemap::FxHashSet;
use util::nodemap::FxHashMap;
use rustc_const_math::ConstInt;
use syntax::{abi, ast};
use syntax::ast::MetaItemKind;
use syntax::attr::{InlineAttr, list_contains_name, mark_used};
use syntax::codemap::Spanned;
use syntax::symbol::{Symbol, keywords};
use syntax_pos::{Span, DUMMY_SP};
use rustc::hir::{self, map as hir_map};
use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags, Unsafety};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
///////////////////////////////////////////////////////////////////////////
// Main entry point
@ -71,6 +75,7 @@ pub fn provide(providers: &mut Providers) {
impl_trait_ref,
impl_polarity,
is_foreign_item,
trans_fn_attrs,
..*providers
};
}
@ -1723,3 +1728,186 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
}
}
fn from_target_feature(
tcx: TyCtxt,
attr: &ast::Attribute,
whitelist: &FxHashSet<String>,
target_features: &mut Vec<Symbol>,
) {
let list = match attr.meta_item_list() {
Some(list) => list,
None => {
let msg = "#[target_feature] attribute must be of the form \
#[target_feature(..)]";
tcx.sess.span_err(attr.span, &msg);
return
}
};
for item in list {
if !item.check_name("enable") {
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
currently";
tcx.sess.span_err(item.span, &msg);
continue
}
let value = match item.value_str() {
Some(list) => list,
None => {
let msg = "#[target_feature] attribute must be of the form \
#[target_feature(enable = \"..\")]";
tcx.sess.span_err(item.span, &msg);
continue
}
};
let value = value.as_str();
for feature in value.split(',') {
if whitelist.contains(feature) {
target_features.push(Symbol::intern(feature));
continue
}
let msg = format!("the feature named `{}` is not valid for \
this target", feature);
let mut err = tcx.sess.struct_span_err(item.span, &msg);
if feature.starts_with("+") {
let valid = whitelist.contains(&feature[1..]);
if valid {
err.help("consider removing the leading `+` in the feature name");
}
}
err.emit();
}
}
}
fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &str) -> Linkage {
use rustc::mir::mono::Linkage::*;
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
// applicable to variable declarations and may not really make sense for
// Rust code in the first place but whitelist them anyway and trust that
// the user knows what s/he's doing. Who knows, unanticipated use cases
// may pop up in the future.
//
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
// and don't have to be, LLVM treats them as no-ops.
match name {
"appending" => Appending,
"available_externally" => AvailableExternally,
"common" => Common,
"extern_weak" => ExternalWeak,
"external" => External,
"internal" => Internal,
"linkonce" => LinkOnceAny,
"linkonce_odr" => LinkOnceODR,
"private" => Private,
"weak" => WeakAny,
"weak_odr" => WeakODR,
_ => {
let span = tcx.hir.span_if_local(def_id);
if let Some(span) = span {
tcx.sess.span_fatal(span, "invalid linkage specified")
} else {
tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
}
}
}
}
fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
let attrs = tcx.get_attrs(id);
let mut trans_fn_attrs = TransFnAttrs::new();
let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
for attr in attrs.iter() {
if attr.check_name("cold") {
trans_fn_attrs.flags |= TransFnAttrFlags::COLD;
} else if attr.check_name("allocator") {
trans_fn_attrs.flags |= TransFnAttrFlags::ALLOCATOR;
} else if attr.check_name("unwind") {
trans_fn_attrs.flags |= TransFnAttrFlags::UNWIND;
} else if attr.check_name("rustc_allocator_nounwind") {
trans_fn_attrs.flags |= TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
} else if attr.check_name("naked") {
trans_fn_attrs.flags |= TransFnAttrFlags::NAKED;
} else if attr.check_name("no_mangle") {
trans_fn_attrs.flags |= TransFnAttrFlags::NO_MANGLE;
} else if attr.check_name("rustc_std_internal_symbol") {
trans_fn_attrs.flags |= TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
} else if attr.check_name("inline") {
trans_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
if attr.path != "inline" {
return ia;
}
let meta = match attr.meta() {
Some(meta) => meta.node,
None => return ia,
};
match meta {
MetaItemKind::Word => {
mark_used(attr);
InlineAttr::Hint
}
MetaItemKind::List(ref items) => {
mark_used(attr);
if items.len() != 1 {
span_err!(tcx.sess.diagnostic(), attr.span, E0534,
"expected one argument");
InlineAttr::None
} else if list_contains_name(&items[..], "always") {
InlineAttr::Always
} else if list_contains_name(&items[..], "never") {
InlineAttr::Never
} else {
span_err!(tcx.sess.diagnostic(), items[0].span, E0535,
"invalid argument");
InlineAttr::None
}
}
_ => ia,
}
});
} else if attr.check_name("export_name") {
if let s @ Some(_) = attr.value_str() {
trans_fn_attrs.export_name = s;
} else {
struct_span_err!(tcx.sess, attr.span, E0558,
"export_name attribute has invalid format")
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
.emit();
}
} else if attr.check_name("target_feature") {
if let Some(val) = attr.value_str() {
for feat in val.as_str().split(",").map(|f| f.trim()) {
if !feat.is_empty() && !feat.contains('\0') {
trans_fn_attrs.target_features.push(Symbol::intern(feat));
}
}
let msg = "#[target_feature = \"..\"] is deprecated and will \
eventually be removed, use \
#[target_feature(enable = \"..\")] instead";
tcx.sess.span_warn(attr.span, &msg);
continue
}
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
let msg = "#[target_feature(..)] can only be applied to \
`unsafe` function";
tcx.sess.span_err(attr.span, msg);
}
from_target_feature(tcx, attr, &whitelist, &mut trans_fn_attrs.target_features);
} else if attr.check_name("linkage") {
if let Some(val) = attr.value_str() {
trans_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
}
}
}
trans_fn_attrs
}

View file

@ -3705,6 +3705,98 @@ match r {
```
"##,
E0534: r##"
The `inline` attribute was malformed.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline()] // error: expected one argument
pub fn something() {}
fn main() {}
```
The parenthesized `inline` attribute requires the parameter to be specified:
```
#[inline(always)]
fn something() {}
```
or:
```
#[inline(never)]
fn something() {}
```
Alternatively, a paren-less version of the attribute may be used to hint the
compiler about inlining opportunity:
```
#[inline]
fn something() {}
```
For more information about the inline attribute, read:
https://doc.rust-lang.org/reference.html#inline-attributes
"##,
E0535: r##"
An unknown argument was given to the `inline` attribute.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline(unknown)] // error: invalid argument
pub fn something() {}
fn main() {}
```
The `inline` attribute only supports two arguments:
* always
* never
All other arguments given to the `inline` attribute will return this error.
Example:
```
#[inline(never)] // ok!
pub fn something() {}
fn main() {}
```
For more information about the inline attribute, https:
read://doc.rust-lang.org/reference.html#inline-attributes
"##,
E0558: r##"
The `export_name` attribute was malformed.
Erroneous code example:
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
#[export_name] // error: export_name attribute has invalid format
pub fn something() {}
fn main() {}
```
The `export_name` attribute expects a string in order to determine the name of
the exported symbol. Example:
```
#[export_name = "some_function"] // ok!
pub fn something() {}
fn main() {}
```
"##,
E0559: r##"
An unknown field was specified into an enum's structure variant.

View file

@ -1535,7 +1535,6 @@ impl<'a> Clean<WherePredicate> for ty::Predicate<'a> {
match *self {
Predicate::Trait(ref pred) => pred.clean(cx),
Predicate::Equate(ref pred) => pred.clean(cx),
Predicate::Subtype(ref pred) => pred.clean(cx),
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
@ -1557,16 +1556,6 @@ impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
}
}
impl<'tcx> Clean<WherePredicate> for ty::EquatePredicate<'tcx> {
fn clean(&self, cx: &DocContext) -> WherePredicate {
let ty::EquatePredicate(ref lhs, ref rhs) = *self;
WherePredicate::EqPredicate {
lhs: lhs.clean(cx),
rhs: rhs.clean(cx)
}
}
}
impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
fn clean(&self, _cx: &DocContext) -> WherePredicate {
panic!("subtype predicates are an internal rustc artifact \

View file

@ -28,6 +28,7 @@ pub struct Page<'a> {
pub root_path: &'a str,
pub description: &'a str,
pub keywords: &'a str,
pub resource_suffix: &'a str,
}
pub fn render<T: fmt::Display, S: fmt::Display>(
@ -47,12 +48,13 @@ r##"<!DOCTYPE html>
<title>{title}</title>
<link rel="stylesheet" type="text/css" href="{root_path}normalize.css">
<link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css" id="mainThemeStyle">
<link rel="stylesheet" type="text/css" href="{root_path}normalize{suffix}.css">
<link rel="stylesheet" type="text/css" href="{root_path}rustdoc{suffix}.css"
id="mainThemeStyle">
{themes}
<link rel="stylesheet" type="text/css" href="{root_path}dark.css">
<link rel="stylesheet" type="text/css" href="{root_path}main.css" id="themeStyle">
<script src="{root_path}storage.js"></script>
<link rel="stylesheet" type="text/css" href="{root_path}dark{suffix}.css">
<link rel="stylesheet" type="text/css" href="{root_path}main{suffix}.css" id="themeStyle">
<script src="{root_path}storage{suffix}.js"></script>
{css_extension}
{favicon}
@ -76,11 +78,11 @@ r##"<!DOCTYPE html>
<div class="theme-picker">
<button id="theme-picker" aria-label="Pick another theme!">
<img src="{root_path}brush.svg" width="18" alt="Pick another theme!">
<img src="{root_path}brush{suffix}.svg" width="18" alt="Pick another theme!">
</button>
<div id="theme-choices"></div>
</div>
<script src="{root_path}theme.js"></script>
<script src="{root_path}theme{suffix}.js"></script>
<nav class="sub">
<form class="search-form js-only">
<div class="search-container">
@ -153,13 +155,14 @@ r##"<!DOCTYPE html>
window.rootPath = "{root_path}";
window.currentCrate = "{krate}";
</script>
<script src="{root_path}main.js"></script>
<script src="{root_path}main{suffix}.js"></script>
<script defer src="{root_path}search-index.js"></script>
</body>
</html>"##,
css_extension = if css_file_extension {
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme.css\">",
root_path = page.root_path)
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
root_path = page.root_path,
suffix=page.resource_suffix)
} else {
"".to_owned()
},
@ -191,8 +194,10 @@ r##"<!DOCTYPE html>
.filter_map(|t| t.file_stem())
.filter_map(|t| t.to_str())
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#,
page.root_path, t))
page.root_path,
t.replace(".css", &format!("{}.css", page.resource_suffix))))
.collect::<String>(),
suffix=page.resource_suffix,
)
}

View file

@ -32,6 +32,7 @@
//! for creating the corresponding search index and source file renderings.
//! These threads are not parallelized (they haven't been a bottleneck yet), and
//! both occur before the crate is rendered.
pub use self::ExternalLocation::*;
use std::borrow::Cow;
@ -128,6 +129,9 @@ pub struct SharedContext {
pub sort_modules_alphabetically: bool,
/// Additional themes to be added to the generated docs.
pub themes: Vec<PathBuf>,
/// Suffix to be added on resource files (if suffix is "-v2" then "main.css" becomes
/// "main-v2.css").
pub resource_suffix: String,
}
impl SharedContext {
@ -492,6 +496,7 @@ pub fn run(mut krate: clean::Crate,
external_html: &ExternalHtml,
playground_url: Option<String>,
dst: PathBuf,
resource_suffix: String,
passes: FxHashSet<String>,
css_file_extension: Option<PathBuf>,
renderinfo: RenderInfo,
@ -520,6 +525,7 @@ pub fn run(mut krate: clean::Crate,
created_dirs: RefCell::new(FxHashSet()),
sort_modules_alphabetically,
themes,
resource_suffix,
};
// If user passed in `--playground-url` arg, we fill in crate name here
@ -734,7 +740,7 @@ fn write_shared(cx: &Context,
// Add all the static files. These may already exist, but we just
// overwrite them anyway to make sure that they're fresh and up-to-date.
write(cx.dst.join("rustdoc.css"),
write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
include_bytes!("static/rustdoc.css"))?;
// To avoid "main.css" to be overwritten, we'll first run over the received themes and only
@ -746,16 +752,19 @@ fn write_shared(cx: &Context,
let mut f = try_err!(File::open(&entry), &entry);
try_err!(f.read_to_end(&mut content), &entry);
write(cx.dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?;
themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned());
let theme = try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry);
let extension = try_none!(try_none!(entry.extension(), &entry).to_str(), &entry);
write(cx.dst.join(format!("{}{}.{}", theme, cx.shared.resource_suffix, extension)),
content.as_slice())?;
themes.insert(theme.to_owned());
}
write(cx.dst.join("brush.svg"),
write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)),
include_bytes!("static/brush.svg"))?;
write(cx.dst.join("main.css"),
write(cx.dst.join(&format!("main{}.css", cx.shared.resource_suffix)),
include_bytes!("static/themes/main.css"))?;
themes.insert("main".to_owned());
write(cx.dst.join("dark.css"),
write(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
include_bytes!("static/themes/dark.css"))?;
themes.insert("dark".to_owned());
@ -763,7 +772,8 @@ fn write_shared(cx: &Context,
themes.sort();
// To avoid theme switch latencies as much as possible, we put everything theme related
// at the beginning of the html files into another js file.
write(cx.dst.join("theme.js"), format!(
write(cx.dst.join(&format!("theme{}.js", cx.shared.resource_suffix)),
format!(
r#"var themes = document.getElementById("theme-choices");
var themePicker = document.getElementById("theme-picker");
themePicker.onclick = function() {{
@ -785,19 +795,28 @@ themePicker.onclick = function() {{
}};
themes.appendChild(but);
}});
"#, themes.iter()
.map(|s| format!("\"{}\"", s))
.collect::<Vec<String>>()
.join(",")).as_bytes())?;
"#,
themes.iter()
.map(|s| format!("\"{}\"", s))
.collect::<Vec<String>>()
.join(",")).as_bytes(),
)?;
write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?;
write(cx.dst.join("storage.js"), include_bytes!("static/storage.js"))?;
write(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
include_bytes!("static/main.js"))?;
{
let mut data = format!("var resourcesSuffix = \"{}\";\n",
cx.shared.resource_suffix).into_bytes();
data.extend_from_slice(include_bytes!("static/storage.js"));
write(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)), &data)?;
}
if let Some(ref css) = cx.shared.css_file_extension {
let out = cx.dst.join("theme.css");
let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
try_err!(fs::copy(css, out), css);
}
write(cx.dst.join("normalize.css"),
write(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
include_bytes!("static/normalize.css"))?;
write(cx.dst.join("FiraSans-Regular.woff"),
include_bytes!("static/FiraSans-Regular.woff"))?;
@ -1084,6 +1103,7 @@ impl<'a> SourceCollector<'a> {
root_path: &root_path,
description: &desc,
keywords: BASIC_KEYWORDS,
resource_suffix: &self.scx.resource_suffix,
};
layout::render(&mut w, &self.scx.layout,
&page, &(""), &Source(contents),
@ -1446,6 +1466,7 @@ impl Context {
title: &title,
description: &desc,
keywords: &keywords,
resource_suffix: &self.shared.resource_suffix,
};
reset_ids(true);

View file

@ -41,7 +41,9 @@ function getCurrentValue(name) {
}
function switchTheme(styleElem, mainStyleElem, newTheme) {
var newHref = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css");
var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
var fullNewTheme = newTheme + resourcesSuffix + ".css";
var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
var found = false;
if (savedHref.length === 0) {

View file

@ -261,6 +261,13 @@ pub fn opts() -> Vec<RustcOptGroup> {
"check if given theme is valid",
"FILES")
}),
unstable("resource-suffix", |o| {
o.optopt("",
"resource-suffix",
"suffix to add to CSS and JavaScript files, e.g. \"main.css\" will become \
\"main-suffix.css\"",
"PATH")
}),
]
}
@ -417,6 +424,7 @@ pub fn main_args(args: &[String]) -> isize {
let display_warnings = matches.opt_present("display-warnings");
let linker = matches.opt_str("linker").map(PathBuf::from);
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
let resource_suffix = matches.opt_str("resource-suffix");
match (should_test, markdown_input) {
(true, true) => {
@ -442,6 +450,7 @@ pub fn main_args(args: &[String]) -> isize {
Some("html") | None => {
html::render::run(krate, &external_html, playground_url,
output.unwrap_or(PathBuf::from("doc")),
resource_suffix.unwrap_or(String::new()),
passes.into_iter().collect(),
css_file_extension,
renderinfo,

View file

@ -1080,14 +1080,45 @@ impl fmt::Display for ExitStatus {
}
}
/// This is ridiculously unstable, as it's a completely-punted-upon part
/// of the `?`-in-`main` RFC. It's here only to allow experimenting with
/// returning a code directly from main. It will definitely change
/// drastically before being stabilized, if it doesn't just get deleted.
#[doc(hidden)]
/// This type represents the status code a process can return to its
/// parent under normal termination.
///
/// Numeric values used in this type don't have portable meanings, and
/// different platforms may mask different amounts of them.
///
/// For the platform's canonical successful and unsuccessful codes, see
/// the [`SUCCESS`] and [`FAILURE`] associated items.
///
/// [`SUCCESS`]: #associatedconstant.SUCCESS
/// [`FAILURE`]: #associatedconstant.FAILURE
///
/// **Warning**: While various forms of this were discussed in [RFC #1937],
/// it was ultimately cut from that RFC, and thus this type is more subject
/// to change even than the usual unstable item churn.
///
/// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937
#[derive(Clone, Copy, Debug)]
#[unstable(feature = "process_exitcode_placeholder", issue = "43301")]
pub struct ExitCode(pub i32);
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
pub struct ExitCode(imp::ExitCode);
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
impl ExitCode {
/// The canonical ExitCode for successful termination on this platform.
///
/// Note that a `()`-returning `main` implicitly results in a successful
/// termination, so there's no need to return this from `main` unless
/// you're also returning other possible codes.
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS);
/// The canonical ExitCode for unsuccessful termination on this platform.
///
/// If you're only returning this and `SUCCESS` from `main`, consider
/// instead returning `Err(_)` and `Ok(())` respectively, which will
/// return the same codes (but will also `eprintln!` the error).
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
}
impl Child {
/// Forces the child to exit. This is equivalent to sending a
@ -1401,18 +1432,6 @@ pub fn id() -> u32 {
::sys::os::getpid()
}
#[cfg(target_arch = "wasm32")]
mod exit {
pub const SUCCESS: i32 = 0;
pub const FAILURE: i32 = 1;
}
#[cfg(not(target_arch = "wasm32"))]
mod exit {
use libc;
pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
pub const FAILURE: i32 = libc::EXIT_FAILURE;
}
/// A trait for implementing arbitrary return types in the `main` function.
///
/// The c-main function only supports to return integers as return type.
@ -1433,18 +1452,15 @@ pub trait Termination {
#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for () {
fn report(self) -> i32 { exit::SUCCESS }
fn report(self) -> i32 { ExitCode::SUCCESS.report() }
}
#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl<E: fmt::Debug> Termination for Result<(), E> {
fn report(self) -> i32 {
match self {
Ok(val) => val.report(),
Err(err) => {
eprintln!("Error: {:?}", err);
exit::FAILURE
}
Ok(()) => ().report(),
Err(err) => Err::<!, _>(err).report(),
}
}
}
@ -1459,15 +1475,14 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
fn report(self) -> i32 {
let Err(err) = self;
eprintln!("Error: {:?}", err);
exit::FAILURE
ExitCode::FAILURE.report()
}
}
#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for ExitCode {
fn report(self) -> i32 {
let ExitCode(code) = self;
code
self.0.as_i32()
}
}

View file

@ -126,6 +126,18 @@ impl fmt::Display for ExitStatus {
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(bool);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(false);
pub const FAILURE: ExitCode = ExitCode(true);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
pub struct Process(Void);
impl Process {

View file

@ -13,6 +13,7 @@ use ffi::OsStr;
use os::unix::ffi::OsStrExt;
use fmt;
use io::{self, Error, ErrorKind};
use libc::{EXIT_SUCCESS, EXIT_FAILURE};
use path::{Path, PathBuf};
use sys::fd::FileDesc;
use sys::fs::{File, OpenOptions};
@ -480,6 +481,18 @@ impl fmt::Display for ExitStatus {
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(u8);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
/// The unique id of the process (this should never be negative).
pub struct Process {
pid: usize,

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::process_common::{Command, ExitStatus, Stdio, StdioPipes};
pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
pub use self::process_inner::Process;
mod process_common;

View file

@ -13,7 +13,7 @@ use os::unix::prelude::*;
use ffi::{OsString, OsStr, CString, CStr};
use fmt;
use io;
use libc::{self, c_int, gid_t, uid_t, c_char};
use libc::{self, c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
use ptr;
use sys::fd::FileDesc;
use sys::fs::{File, OpenOptions};
@ -393,6 +393,18 @@ impl fmt::Display for ExitStatus {
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(u8);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests {
use super::*;

View file

@ -129,6 +129,18 @@ impl fmt::Display for ExitStatus {
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(bool);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(false);
pub const FAILURE: ExitCode = ExitCode(true);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
pub struct Process(Void);
impl Process {

View file

@ -18,7 +18,7 @@ use ffi::{OsString, OsStr};
use fmt;
use fs;
use io::{self, Error, ErrorKind};
use libc::c_void;
use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE};
use mem;
use os::windows::ffi::OsStrExt;
use path::Path;
@ -408,6 +408,18 @@ impl fmt::Display for ExitStatus {
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(c::DWORD);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
fn zeroed_startupinfo() -> c::STARTUPINFO {
c::STARTUPINFO {
cb: 0,

View file

@ -520,7 +520,7 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
first_attr_value_str_by_name(attrs, "crate_name")
}
#[derive(Copy, Clone, PartialEq)]
#[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)]
pub enum InlineAttr {
None,
Hint,
@ -528,43 +528,6 @@ pub enum InlineAttr {
Never,
}
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> InlineAttr {
attrs.iter().fold(InlineAttr::None, |ia, attr| {
if attr.path != "inline" {
return ia;
}
let meta = match attr.meta() {
Some(meta) => meta.node,
None => return ia,
};
match meta {
MetaItemKind::Word => {
mark_used(attr);
InlineAttr::Hint
}
MetaItemKind::List(ref items) => {
mark_used(attr);
if items.len() != 1 {
diagnostic.map(|d|{ span_err!(d, attr.span, E0534, "expected one argument"); });
InlineAttr::None
} else if list_contains_name(&items[..], "always") {
InlineAttr::Always
} else if list_contains_name(&items[..], "never") {
InlineAttr::Never
} else {
diagnostic.map(|d| {
span_err!(d, items[0].span, E0535, "invalid argument");
});
InlineAttr::None
}
}
_ => ia,
}
})
}
#[derive(Copy, Clone, PartialEq)]
pub enum UnwindAttr {
Allowed,
@ -610,13 +573,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
})
}
/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
pub fn requests_inline(attrs: &[Attribute]) -> bool {
match find_inline_attr(None, attrs) {
InlineAttr::Hint | InlineAttr::Always => true,
InlineAttr::None | InlineAttr::Never => false,
}
}
/// Tests if a cfg-pattern matches the cfg set
pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {

View file

@ -37,75 +37,6 @@ More details can be found in [RFC 438].
[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
"##,
E0534: r##"
The `inline` attribute was malformed.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline()] // error: expected one argument
pub fn something() {}
fn main() {}
```
The parenthesized `inline` attribute requires the parameter to be specified:
```
#[inline(always)]
fn something() {}
```
or:
```
#[inline(never)]
fn something() {}
```
Alternatively, a paren-less version of the attribute may be used to hint the
compiler about inlining opportunity:
```
#[inline]
fn something() {}
```
For more information about the inline attribute, read:
https://doc.rust-lang.org/reference.html#inline-attributes
"##,
E0535: r##"
An unknown argument was given to the `inline` attribute.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline(unknown)] // error: invalid argument
pub fn something() {}
fn main() {}
```
The `inline` attribute only supports two arguments:
* always
* never
All other arguments given to the `inline` attribute will return this error.
Example:
```
#[inline(never)] // ok!
pub fn something() {}
fn main() {}
```
For more information about the inline attribute, https:
read://doc.rust-lang.org/reference.html#inline-attributes
"##,
E0536: r##"
The `not` cfg-predicate was malformed.

@ -1 +1 @@
Subproject commit ba2edd794c7def715007931fcd1b4ce62aa711c8
Subproject commit 0903c72cbbc3dafcb5c88820e4a8a98c3a764cf3

View file

@ -1,4 +1,4 @@
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
2018-02-09
2018-03-06

View file

@ -459,3 +459,10 @@ struct Rls699 {
fn new(f: u32) -> Rls699 {
Rls699 { fs }
}
fn invalid_tuple_struct_access() {
bar.0;
struct S;
S.0;
}

View file

@ -14,5 +14,5 @@
use std::process::ExitCode;
fn main() -> ExitCode {
ExitCode(0)
ExitCode::SUCCESS
}

View file

@ -10,11 +10,13 @@ filetime = "0.1"
getopts = "0.2"
log = "0.4"
regex = "0.2"
rustc-serialize = "0.3"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
miow = "0.2"
winapi = "0.2"
miow = "0.3"
winapi = { version = "0.3", features = ["winerror"] }

View file

@ -9,7 +9,7 @@
// except according to those terms.
use errors::{Error, ErrorKind};
use rustc_serialize::json;
use serde_json;
use std::str::FromStr;
use std::path::Path;
use runtest::ProcRes;
@ -17,17 +17,16 @@ use runtest::ProcRes;
// These structs are a subset of the ones found in
// `syntax::json`.
#[derive(RustcEncodable, RustcDecodable)]
#[derive(Deserialize)]
struct Diagnostic {
message: String,
code: Option<DiagnosticCode>,
level: String,
spans: Vec<DiagnosticSpan>,
children: Vec<Diagnostic>,
rendered: Option<String>,
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Deserialize, Clone)]
struct DiagnosticSpan {
file_name: String,
line_start: usize,
@ -40,7 +39,7 @@ struct DiagnosticSpan {
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Deserialize, Clone)]
struct DiagnosticSpanMacroExpansion {
/// span where macro was applied to generate this code
span: DiagnosticSpan,
@ -49,7 +48,7 @@ struct DiagnosticSpanMacroExpansion {
macro_decl_name: String,
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Deserialize, Clone)]
struct DiagnosticCode {
/// The code itself.
code: String,
@ -67,7 +66,7 @@ fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) ->
// The compiler sometimes intermingles non-JSON stuff into the
// output. This hack just skips over such lines. Yuck.
if line.starts_with('{') {
match json::decode::<Diagnostic>(line) {
match serde_json::from_str::<Diagnostic>(line) {
Ok(diagnostic) => {
let mut expected_errors = vec![];
push_expected_errors(&mut expected_errors, &diagnostic, &[], file_name);

View file

@ -21,8 +21,10 @@ extern crate getopts;
extern crate libc;
#[macro_use]
extern crate log;
extern crate rustc_serialize;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate test;
use std::env;

View file

@ -119,7 +119,7 @@ mod imp {
use self::miow::iocp::{CompletionPort, CompletionStatus};
use self::miow::pipe::NamedPipe;
use self::miow::Overlapped;
use self::winapi::ERROR_BROKEN_PIPE;
use self::winapi::shared::winerror::ERROR_BROKEN_PIPE;
struct Pipe<'a> {
dst: &'a mut Vec<u8>,

@ -1 +1 @@
Subproject commit b55e0fc77590cf5d23a01dedeb2104d8cbb48efc
Subproject commit 118e078c5badd520d18b92813fd88789c8d341ab