diff --git a/appveyor.yml b/appveyor.yml index 0735ead8923cc..45e1b4b90d6c7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 diff --git a/src/Cargo.lock b/src/Cargo.lock index 1bf31b2a67c45..b70a01ebb3c18 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -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" diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 925a361f0b22e..c62fa0ede7096 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -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 diff --git a/src/ci/run.sh b/src/ci/run.sh index 3be1c255c164a..79300e08a7d36 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -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 diff --git a/src/etc/ziggurat_tables.py b/src/etc/ziggurat_tables.py deleted file mode 100755 index 762f9565b7802..0000000000000 --- a/src/etc/ziggurat_tables.py +++ /dev/null @@ -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 or the MIT license -# , 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 or the MIT license -// , 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)) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 25f57d8c0f718..570f745f8330c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -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 { self.map(|t| t.clone()) } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 84fdeba4ab3cc..ed46296389da4 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -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> }, diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index a073910fdc83f..d22703452605b 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -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() { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index c4873cb83076a..f4638c23c5f4b 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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>; 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, + pub target_features: Vec, + pub linkage: Option, +} + +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() + } +} + diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 7dca96f94e655..faad3f3563164 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -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> for DefId { #[inline] @@ -1138,6 +1139,43 @@ impl<'gcx> ToStableHashKey> for hir::TraitCandidate { } } +impl<'hir> HashStable> for hir::TransFnAttrs +{ + fn hash_stable(&self, + hcx: &mut StableHashingContext<'hir>, + hasher: &mut StableHasher) { + 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> for hir::TransFnAttrFlags +{ + fn hash_stable(&self, + hcx: &mut StableHashingContext<'hir>, + hasher: &mut StableHasher) { + self.bits().hash_stable(hcx, hasher); + } +} + +impl<'hir> HashStable> for attr::InlineAttr { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'hir>, + hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); + } +} impl_stable_hash_for!(struct hir::Freevar { def, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 7b2cfa0a3ffec..a8ed885e78d55 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -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> @@ -274,9 +273,6 @@ impl<'gcx> HashStable> 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); } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 559b2720076f4..0645bffafe76a 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -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", diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 402cb6a8fef43..5d44b2043e26c 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -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>, diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs index 8a562471ac5d0..abb35d24d7954 100644 --- a/src/librustc/infer/outlives/bounds.rs +++ b/src/librustc/infer/outlives/bounds.rs @@ -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(..) | diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 5dbe2ef516cf7..3c451d7ae46a1 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -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, String>; + -> Result; fn get_dylib_metadata(&self, target: &Target, filename: &Path) - -> Result, String>; + -> Result; } #[derive(Clone)] diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 5658b5b683291..48a62c8c14d69 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -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); } } diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 7f8f2e9b90603..d8eac2b415989 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> { size_estimate: Option, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum Linkage { External, AvailableExternally, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b1d2142060699..ce23cb2349609 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -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 | diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 93e33836818ce..2f3e19d92bcda 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -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())), diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b9ae4599d808e..8ac69c4b5287a 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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 { - 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(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M { match self { VtableImpl(i) => VtableImpl(VtableImplData { diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 4151661b5933c..52a0a897595b2 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -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(..) | diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9e24a4e6afacf..600b4a515f0bf 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -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::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, - inferred_obligations: SnapshotVec>, - intercrate_ambiguity_causes: Option>, /// 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(&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(&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(&mut self, f: F) -> Result where F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result { - 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>, 'tcx:'a + where I : IntoIterator>, '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>, 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 -> Struct. @@ -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: Unsize> 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 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>,()> { - 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>,()> { 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(|_| ()) } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 1eb14a222787d..9dd5aaee7b72f 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -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 | diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 898accb902159..c562f2cd48dde 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -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. diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index f4b5ffbb7dc40..a5f0abb9bc05c 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -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()) } } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index c3cd65230bd86..5069c59562678 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -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 } }; diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index cfc552bdc85c5..d880b022e2f18 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -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); diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2ef97b2673d6e..43a71f1c0d367 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -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, [] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>, + [] fn trans_fn_attrs: trans_fn_attrs(DefId) -> TransFnAttrs, [] fn fn_arg_names: FnArgNames(DefId) -> Vec, [] fn impl_parent: ImplParent(DefId) -> Option, [] fn trait_of_item: TraitOfItem(DefId) -> Option, @@ -362,8 +363,6 @@ define_maps! { <'tcx> [] fn collect_and_partition_translation_items: collect_and_partition_translation_items_node(CrateNum) -> (Arc, Arc>>>), - [] fn export_name: ExportName(DefId) -> Option, - [] 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>, @@ -385,7 +384,6 @@ define_maps! { <'tcx> [] fn target_features_whitelist: target_features_whitelist_node(CrateNum) -> Lrc>, - [] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Lrc>, // 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 } } diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 65f2d476475e9..b18837ff35aa8 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -217,9 +217,9 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; - encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; + encode_query_results::(tcx, enc, qri)?; } // Encode diagnostics diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 13f286d6a2686..fcc69f3b2c39e 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -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, ); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a7c55880e2e17..be27e3d51529b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -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>; - #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct OutlivesPredicate(pub A, pub B); // `A : B` pub type PolyOutlivesPredicate = ty::Binder>; @@ -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(..) | diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 6147b52844fe4..055835ed69c1d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -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> { - 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>(&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>(&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 { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 47ad7cbcb56f7..785035ee5f4f0 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -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, diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index ce44448ef794e..ea99bd39e8792 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -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) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 40c8e8aa4a29a..a2620da4c10ca 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -939,7 +939,6 @@ define_print_multi! { ('tcx) ty::Binder>, ('tcx) ty::Binder>, ('tcx) ty::Binder>, - ('tcx) ty::Binder>, ('tcx) ty::Binder>, ('tcx) ty::Binder>, ('tcx) ty::Binder, 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), diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index 23e0733748b4a..c466b8f8ad1b5 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -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 { pub trait Erased {} impl 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 -> Box`. 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 -> Box`. 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 -> Box`. 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 OwningRef { } } + /// 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 + 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 { } } -unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box { - type Erased = Box; - fn into_erased_send_sync(self) -> Self::Erased { +unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box { + type Erased = Box; + fn into_erased_send(self) -> Self::Erased { self } } +unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box { + type Erased = Box; + fn into_erased_send_sync(self) -> Self::Erased { + let result: Box = 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 { type Erased = Arc; fn into_erased_send_sync(self) -> Self::Erased { diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index b1ab4eaa06924..69fc9ef785eb7 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -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() {} +pub fn assert_send_val(_t: &T) {} pub fn assert_send_sync_val(_t: &T) {} #[macro_export] diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs index 6c3626cd880b2..9d8690072709b 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_llvm/archive_ro.rs @@ -22,6 +22,8 @@ pub struct ArchiveRO { ptr: ArchiveRef, } +unsafe impl Send for ArchiveRO {} + pub struct Iter<'a> { archive: &'a ArchiveRO, ptr: ::ArchiveIteratorRef, diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 8dcf7444dd18f..16bee5b987e2d 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -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 { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 2e95c23b4aed1..202efb9276a81 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -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; -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. diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d19ab89459146..830121b446fca 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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) diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 2d015fa81f925..da0da622d5214 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -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; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index e0fb924f1aa3e..c56674bd6c5a9 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -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); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 3af10c5c25169..bbf4357e5b0f9 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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 diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 08c16fed5dd3f..25f933c5da6e7 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -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( diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 10c2f9f758f14..0f512569adf97 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -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) } } } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 7c86f5a4b1a84..38b8ffc6b9c80 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -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 { - 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 diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 08a9757fb326a..64c702b99cdb3 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -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 { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 6e98604101345..d92025a6787d6 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -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) => { diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index ffa3f7f401164..d5ec8d1b55262 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -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::>() + .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, - target_features: &mut Vec, -) { - 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(); - } - } } diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 739ae768ca29c..fd79ae7435ed1 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -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 { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index beb7a091bdcfe..3708f6f6ec4fc 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -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>, diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 37bd225a7d9cb..7c4e2340d5bdc 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -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 { diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index fd9cb8c5a6bed..0ce3f729305b4 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -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), _ => { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index b93e8c2ad21ca..dc5e788959448 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -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; } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 0b8da10b78e77..74df5127269a7 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -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; diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs index d57624da0c68d..9483420f2f0e7 100644 --- a/src/librustc_trans/metadata.rs +++ b/src/librustc_trans/metadata.rs @@ -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, String> { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { // 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, String> { + -> Result { 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)) } } } diff --git a/src/librustc_trans_utils/diagnostics.rs b/src/librustc_trans_utils/diagnostics.rs deleted file mode 100644 index 13fa15faf4123..0000000000000 --- a/src/librustc_trans_utils/diagnostics.rs +++ /dev/null @@ -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 or the MIT license -// , 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() {} -``` -"##, - -} diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index d636a5f2e64b7..6a3fd21f3a771 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -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; diff --git a/src/librustc_trans_utils/symbol_names.rs b/src/librustc_trans_utils/symbol_names.rs index fb299bf7eea0c..f9f93730255e6 100644 --- a/src/librustc_trans_utils/symbol_names.rs +++ b/src/librustc_trans_utils/symbol_names.rs @@ -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(); } diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 7b2cbe140aebf..0d4811c4b025d 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -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, String> { + ) -> Result { bug!("DummyMetadataLoader::get_rlib_metadata"); } @@ -127,7 +130,7 @@ impl MetadataLoader for DummyMetadataLoader { &self, _target: &Target, _filename: &Path - ) -> Result, String> { + ) -> Result { 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, String> { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { 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, [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, String> { + ) -> Result { // 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); } } _ => {} diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 5e0c47f18bf5a..72e4b726a22b4 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -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, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 841559013a093..4d344eb279903 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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(..) | diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f7158593f0b6e..1a7d8bb56780e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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, + target_features: &mut Vec, +) { + 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 +} diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 6c195a991c24e..96b2ec745f132 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -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. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f9f1c3304949d..d0230a69374d4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1535,7 +1535,6 @@ impl<'a> Clean 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 for ty::TraitPredicate<'a> { } } -impl<'tcx> Clean 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 for ty::SubtypePredicate<'tcx> { fn clean(&self, _cx: &DocContext) -> WherePredicate { panic!("subtype predicates are an internal rustc artifact \ diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index fd14513cac48f..0151a8c3ab715 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -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( @@ -47,12 +48,13 @@ r##" {title} - - + + {themes} - - - + + + {css_extension} {favicon} @@ -76,11 +78,11 @@ r##"
- +