diff --git a/RELEASES.md b/RELEASES.md index a747d04696821..95307ab788e57 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,30 @@ +Version 1.12.1 (2016-10-20) +=========================== + +Regression Fixes +---------------- + +* [ICE: 'rustc' panicked at 'assertion failed: concrete_substs.is_normalized_for_trans()' #36381][36381] +* [Confusion with double negation and booleans][36856] +* [rustc 1.12.0 fails with SIGSEGV in release mode (syn crate 0.8.0)][36875] +* [Rustc 1.12.0 Windows build of `ethcore` crate fails with LLVM error][36924] +* [1.12.0: High memory usage when linking in release mode with debug info][36926] +* [Corrupted memory after updated to 1.12][36936] +* ["Let NullaryConstructor = something;" causes internal compiler error: "tried to overwrite interned AdtDef"][37026] +* [Fix ICE: inject bitcast if types mismatch for invokes/calls/stores][37112] +* [debuginfo: Handle spread_arg case in MIR-trans in a more stable way.][37153] + +[36381]: https://github.com/rust-lang/rust/issues/36381 +[36856]: https://github.com/rust-lang/rust/issues/36856 +[36875]: https://github.com/rust-lang/rust/issues/36875 +[36924]: https://github.com/rust-lang/rust/issues/36924 +[36926]: https://github.com/rust-lang/rust/issues/36926 +[36936]: https://github.com/rust-lang/rust/issues/36936 +[37026]: https://github.com/rust-lang/rust/issues/37026 +[37112]: https://github.com/rust-lang/rust/issues/37112 +[37153]: https://github.com/rust-lang/rust/issues/37153 + + Version 1.12.0 (2016-09-29) =========================== diff --git a/mk/main.mk b/mk/main.mk index 80f1fdfab96fe..8d95bf6ed8daf 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.13.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.2 +CFG_PRERELEASE_VERSION=.3 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" @@ -53,17 +53,6 @@ endif # versions in the same place CFG_FILENAME_EXTRA=$(shell printf '%s' $(CFG_RELEASE)$(CFG_EXTRA_FILENAME) | $(CFG_HASH_COMMAND)) -# A magic value that allows the compiler to use unstable features during the -# bootstrap even when doing so would normally be an error because of feature -# staging or because the build turns on warnings-as-errors and unstable features -# default to warnings. The build has to match this key in an env var. -# -# This value is keyed off the release to ensure that all compilers for one -# particular release have the same bootstrap key. Note that this is -# intentionally not "secure" by any definition, this is largely just a deterrent -# from users enabling unstable features on the stable compiler. -CFG_BOOTSTRAP_KEY=$(CFG_FILENAME_EXTRA) - # If local-rust is the same as the current version, then force a local-rebuild ifdef CFG_ENABLE_LOCAL_RUST ifeq ($(CFG_RELEASE),\ @@ -73,14 +62,6 @@ ifeq ($(CFG_RELEASE),\ endif endif -# The stage0 compiler needs to use the previous key recorded in src/stage0.txt, -# except for local-rebuild when it just uses the same current key. -ifdef CFG_ENABLE_LOCAL_REBUILD -CFG_BOOTSTRAP_KEY_STAGE0=$(CFG_BOOTSTRAP_KEY) -else -CFG_BOOTSTRAP_KEY_STAGE0=$(shell sed -ne 's/^rustc_key: //p' $(S)src/stage0.txt) -endif - # The name of the package to use for creating tarballs, installers etc. CFG_PACKAGE_NAME=rustc-$(CFG_PACKAGE_VERS) @@ -387,13 +368,16 @@ CFG_INFO := $(info cfg: disabling unstable features (CFG_DISABLE_UNSTABLE_FEATUR # Turn on feature-staging export CFG_DISABLE_UNSTABLE_FEATURES # Subvert unstable feature lints to do the self-build -export RUSTC_BOOTSTRAP_KEY:=$(CFG_BOOTSTRAP_KEY) +export RUSTC_BOOTSTRAP endif -export CFG_BOOTSTRAP_KEY ifdef CFG_MUSL_ROOT export CFG_MUSL_ROOT endif +# FIXME: Transitionary measure to bootstrap using the old bootstrap logic. +# Remove this once the bootstrap compiler uses the new login in Issue #36548. +export RUSTC_BOOTSTRAP_KEY=5c6cf767 + ###################################################################### # Per-stage targets and runner ###################################################################### diff --git a/mk/target.mk b/mk/target.mk index 2a08b7b046534..1b139909ab458 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -42,23 +42,6 @@ $(foreach host,$(CFG_HOST), \ $(foreach crate,$(CRATES), \ $(eval $(call RUST_CRATE_FULLDEPS,$(stage),$(target),$(host),$(crate))))))) -# $(1) stage -# $(2) target -# $(3) host -define DEFINE_BOOTSTRAP_KEY -BOOTSTRAP_KEY$(1)_T_$(2)_H_$(3) := $$(CFG_BOOTSTRAP_KEY) -ifeq ($(1),0) -ifeq ($(3),$$(CFG_BUILD)) -BOOTSTRAP_KEY$(1)_T_$(2)_H_$(3) := $$(CFG_BOOTSTRAP_KEY_STAGE0) -endif -endif -endef - -$(foreach host,$(CFG_TARGET), \ - $(foreach target,$(CFG_TARGET), \ - $(foreach stage,$(STAGES), \ - $(eval $(call DEFINE_BOOTSTRAP_KEY,$(stage),$(target),$(host)))))) - # RUST_TARGET_STAGE_N template: This defines how target artifacts are built # for all stage/target architecture combinations. This is one giant rule which # works as follows: @@ -83,8 +66,6 @@ $(foreach host,$(CFG_TARGET), \ define RUST_TARGET_STAGE_N $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2) -$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ - export RUSTC_BOOTSTRAP_KEY := $$(BOOTSTRAP_KEY$(1)_T_$(2)_H_$(3)) $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ $$(CRATEFILE_$(4)) \ $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \ @@ -132,8 +113,6 @@ endef # $(4) - name of the tool being built define TARGET_TOOL -$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ - export RUSTC_BOOTSTRAP_KEY := $$(BOOTSTRAP_KEY$(1)_T_$(2)_H_$(3)) $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ $$(TOOL_SOURCE_$(4)) \ $$(TOOL_INPUTS_$(4)) \ diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 2b9d717cbd48d..603a5ce752f0a 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -185,7 +185,7 @@ pub fn compiletest(build: &Build, } } } - build.add_bootstrap_key(compiler, &mut cmd); + build.add_bootstrap_key(&mut cmd); cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9de438cfa7d50..239db55ff5b3b 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -133,7 +133,7 @@ fn build_startup_objects(build: &Build, target: &str, into: &Path) { for file in t!(fs::read_dir(build.src.join("src/rtstartup"))) { let file = t!(file); let mut cmd = Command::new(&compiler_path); - build.add_bootstrap_key(&compiler, &mut cmd); + build.add_bootstrap_key(&mut cmd); build.run(cmd.arg("--target").arg(target) .arg("--emit=obj") .arg("--out-dir").arg(into) @@ -199,7 +199,6 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { cargo.env("CFG_RELEASE", &build.release) .env("CFG_RELEASE_CHANNEL", &build.config.channel) .env("CFG_VERSION", &build.version) - .env("CFG_BOOTSTRAP_KEY", &build.bootstrap_key) .env("CFG_PREFIX", build.config.prefix.clone().unwrap_or(String::new())) .env("CFG_LIBDIR_RELATIVE", "lib"); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bcc53129f8d8e..4dea0e3f9e735 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -647,7 +647,7 @@ impl Build { .env("RUSTDOC_REAL", self.rustdoc(compiler)) .env("RUSTC_FLAGS", self.rustc_flags(target).join(" ")); - self.add_bootstrap_key(compiler, &mut cargo); + self.add_bootstrap_key(&mut cargo); // Specify some various options for build scripts used throughout // the build. @@ -862,16 +862,11 @@ impl Build { } /// Adds the compiler's bootstrap key to the environment of `cmd`. - fn add_bootstrap_key(&self, compiler: &Compiler, cmd: &mut Command) { - // In stage0 we're using a previously released stable compiler, so we - // use the stage0 bootstrap key. Otherwise we use our own build's - // bootstrap key. - let bootstrap_key = if compiler.is_snapshot(self) && !self.local_rebuild { - &self.bootstrap_key_stage0 - } else { - &self.bootstrap_key - }; - cmd.env("RUSTC_BOOTSTRAP_KEY", bootstrap_key); + fn add_bootstrap_key(&self, cmd: &mut Command) { + cmd.env("RUSTC_BOOTSTRAP", ""); + // FIXME: Transitionary measure to bootstrap using the old bootstrap logic. + // Remove this once the bootstrap compiler uses the new login in Issue #36548. + cmd.env("RUSTC_BOOTSTRAP_KEY", "5c6cf767"); } /// Returns the compiler's libdir where it stores the dynamic libraries that diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 70b0b810c6c48..c55a319d34eb9 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -1131,8 +1131,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { Adt(adt_def, variant, substs, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, substs, variant_def.did, - ppaux::Ns::Value, &[])?; + ppaux::parameterized(fmt, substs, variant_def.did, &[])?; match variant_def.kind { ty::VariantKind::Unit => Ok(()), @@ -1227,7 +1226,7 @@ impl<'tcx> Debug for Literal<'tcx> { use self::Literal::*; match *self { Item { def_id, substs } => { - ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[]) + ppaux::parameterized(fmt, substs, def_id, &[]) } Value { ref value } => { write!(fmt, "const ")?; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9d7131dc96cc5..05b4c44580e17 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -336,7 +336,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.infcx.tcx } - pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'tcx> { + pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'gcx> { self.infcx.param_env() } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index e37425901c8c8..6a27558b0b77e 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -148,6 +148,8 @@ pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> bool { + debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); + if let Some(r) = tcx.specializes_cache.borrow().check(impl1_def_id, impl2_def_id) { return r; } @@ -177,21 +179,22 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // create a parameter environment corresponding to a (skolemized) instantiation of impl1 - let mut penv = tcx.construct_parameter_environment(DUMMY_SP, - impl1_def_id, - region::DUMMY_CODE_EXTENT); + let penv = tcx.construct_parameter_environment(DUMMY_SP, + impl1_def_id, + region::DUMMY_CODE_EXTENT); let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id) .unwrap() .subst(tcx, &penv.free_substs); - let result = tcx.infer_ctxt(None, None, Reveal::ExactMatch).enter(|mut infcx| { + // Create a infcx, taking the predicates of impl1 as assumptions: + let result = tcx.infer_ctxt(None, Some(penv), Reveal::ExactMatch).enter(|mut infcx| { // Normalize the trait reference, adding any obligations // that arise into the impl1 assumptions. let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = { let selcx = &mut SelectionContext::new(&infcx); traits::normalize(selcx, ObligationCause::dummy(), &impl1_trait_ref) }; - penv.caller_bounds.extend(normalization_obligations.into_iter().map(|o| { + infcx.parameter_environment.caller_bounds.extend(normalization_obligations.into_iter().map(|o| { match tcx.lift_to_global(&o.predicate) { Some(predicate) => predicate, None => { @@ -200,9 +203,6 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } })); - // Install the parameter environment, taking the predicates of impl1 as assumptions: - infcx.parameter_environment = penv; - // Attempt to prove that impl2 applies, given all of the above. fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok() }); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 723af1f0d90a4..d38a30ee631c8 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -34,7 +34,7 @@ use util::nodemap::FnvHashMap; use serialize::{self, Encodable, Encoder}; use std::borrow::Cow; -use std::cell::Cell; +use std::cell::{Cell, RefCell}; use std::hash::{Hash, Hasher}; use std::iter; use std::ops::Deref; @@ -1220,6 +1220,12 @@ pub struct ParameterEnvironment<'tcx> { /// regions don't have this implicit scope and instead introduce /// relationships in the environment. pub free_id_outlive: CodeExtent, + + /// A cache for `moves_by_default`. + pub is_copy_cache: RefCell, bool>>, + + /// A cache for `type_is_sized` + pub is_sized_cache: RefCell, bool>>, } impl<'a, 'tcx> ParameterEnvironment<'tcx> { @@ -1232,6 +1238,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { implicit_region_bound: self.implicit_region_bound, caller_bounds: caller_bounds, free_id_outlive: self.free_id_outlive, + is_copy_cache: RefCell::new(FnvHashMap()), + is_sized_cache: RefCell::new(FnvHashMap()), } } @@ -2782,7 +2790,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { free_substs: Substs::empty(self), caller_bounds: Vec::new(), implicit_region_bound: self.mk_region(ty::ReEmpty), - free_id_outlive: free_id_outlive + free_id_outlive: free_id_outlive, + is_copy_cache: RefCell::new(FnvHashMap()), + is_sized_cache: RefCell::new(FnvHashMap()), } } @@ -2853,6 +2863,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)), caller_bounds: predicates, free_id_outlive: free_id_outlive, + is_copy_cache: RefCell::new(FnvHashMap()), + is_sized_cache: RefCell::new(FnvHashMap()), }; let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps)); diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 5a87ea1473d98..1715185373684 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -908,23 +908,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::ParameterEnvironment { - free_substs: self.free_substs.fold_with(folder), - implicit_region_bound: self.implicit_region_bound.fold_with(folder), - caller_bounds: self.caller_bounds.fold_with(folder), - free_id_outlive: self.free_id_outlive, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.free_substs.visit_with(visitor) || - self.implicit_region_bound.visit_with(visitor) || - self.caller_bounds.visit_with(visitor) - } -} - impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::error::ExpectedFound { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index c9ab577a9921d..5b0f43e3cf1f2 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -20,9 +20,11 @@ use ty::{Disr, ParameterEnvironment}; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; use ty::TypeVariants::*; +use util::nodemap::FnvHashMap; use rustc_const_math::{ConstInt, ConstIsize, ConstUsize}; +use std::cell::RefCell; use std::cmp; use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; @@ -579,11 +581,24 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc impl<'a, 'tcx> ty::TyS<'tcx> { fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: &ParameterEnvironment<'tcx>, - bound: ty::BuiltinBound, span: Span) -> bool + bound: ty::BuiltinBound, + cache: &RefCell, bool>>, + span: Span) -> bool { - tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch).enter(|infcx| { - traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span) - }) + if self.has_param_types() || self.has_self_ty() { + if let Some(result) = cache.borrow().get(self) { + return *result; + } + } + let result = + tcx.infer_ctxt(None, Some(param_env.clone()), Reveal::ExactMatch) + .enter(|infcx| { + traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span) + }); + if self.has_param_types() || self.has_self_ty() { + cache.borrow_mut().insert(self, result); + } + return result; } // FIXME (@jroesch): I made this public to use it, not sure if should be private @@ -610,7 +625,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> { TyArray(..) | TySlice(..) | TyTrait(..) | TyTuple(..) | TyClosure(..) | TyAdt(..) | TyAnon(..) | TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None - }.unwrap_or_else(|| !self.impls_bound(tcx, param_env, ty::BoundCopy, span)); + }.unwrap_or_else(|| { + !self.impls_bound(tcx, param_env, ty::BoundCopy, ¶m_env.is_copy_cache, span) + }); if !self.has_param_types() && !self.has_self_ty() { self.flags.set(self.flags.get() | if result { @@ -650,7 +667,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> { TyAdt(..) | TyProjection(..) | TyParam(..) | TyInfer(..) | TyAnon(..) | TyError => None - }.unwrap_or_else(|| self.impls_bound(tcx, param_env, ty::BoundSized, span)); + }.unwrap_or_else(|| { + self.impls_bound(tcx, param_env, ty::BoundSized, ¶m_env.is_sized_cache, span) + }); if !self.has_param_types() && !self.has_self_ty() { self.flags.set(self.flags.get() | if result { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1df0cf2d5cdf6..312cab245442a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -10,6 +10,7 @@ use hir::def_id::DefId; use ty::subst::{self, Subst, Substs}; +use hir::map::definitions::DefPathData; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use ty::{TyBool, TyChar, TyAdt}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; @@ -56,27 +57,55 @@ fn fn_sig(f: &mut fmt::Formatter, Ok(()) } -/// Namespace of the path given to parameterized to print. -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum Ns { - Type, - Value -} - pub fn parameterized(f: &mut fmt::Formatter, substs: &subst::Substs, - did: DefId, - ns: Ns, + mut did: DefId, projections: &[ty::ProjectionPredicate]) -> fmt::Result { + let key = ty::tls::with(|tcx| tcx.def_key(did)); + let mut item_name = if let Some(name) = key.disambiguated_data.data.get_opt_name() { + Some(name) + } else { + did.index = key.parent.unwrap_or_else( + || bug!("finding type for {:?}, encountered def-id {:?} with no parent", + did, did)); + parameterized(f, substs, did, projections)?; + return write!(f, "::{}", key.disambiguated_data.data.as_interned_str()); + }; + let mut verbose = false; let mut num_supplied_defaults = 0; let mut has_self = false; let mut num_regions = 0; let mut num_types = 0; - let mut item_name = None; + let mut is_value_path = false; let fn_trait_kind = ty::tls::with(|tcx| { - let mut generics = tcx.lookup_generics(did); + // Unfortunately, some kinds of items (e.g., closures) don't have + // generics. So walk back up the find the closest parent that DOES + // have them. + let mut item_def_id = did; + loop { + let key = tcx.def_key(item_def_id); + match key.disambiguated_data.data { + DefPathData::TypeNs(_) => { + break; + } + DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => { + is_value_path = true; + break; + } + _ => { + // if we're making a symbol for something, there ought + // to be a value or type-def or something in there + // *somewhere* + item_def_id.index = key.parent.unwrap_or_else(|| { + bug!("finding type for {:?}, encountered def-id {:?} with no \ + parent", did, item_def_id); + }); + } + } + } + let mut generics = tcx.lookup_generics(item_def_id); let mut path_def_id = did; verbose = tcx.sess.verbose(); has_self = generics.has_self; @@ -84,7 +113,7 @@ pub fn parameterized(f: &mut fmt::Formatter, let mut child_types = 0; if let Some(def_id) = generics.parent { // Methods. - assert_eq!(ns, Ns::Value); + assert!(is_value_path); child_types = generics.types.len(); generics = tcx.lookup_generics(def_id); num_regions = generics.regions.len(); @@ -94,10 +123,11 @@ pub fn parameterized(f: &mut fmt::Formatter, write!(f, "<{} as ", substs.type_at(0))?; } - item_name = Some(tcx.item_name(did)); path_def_id = def_id; } else { - if ns == Ns::Value { + item_name = None; + + if is_value_path { // Functions. assert_eq!(has_self, false); } else { @@ -192,7 +222,7 @@ pub fn parameterized(f: &mut fmt::Formatter, start_or_continue(f, "", ">")?; // For values, also print their name and type parameters. - if ns == Ns::Value { + if is_value_path { empty.set(true); if has_self { @@ -298,7 +328,6 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> { let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self; parameterized(f, trait_ref.substs, trait_ref.def_id, - Ns::Type, projection_bounds) } } @@ -398,7 +427,7 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { let trait_ref = tcx.lift(&ty::Binder(*self)) .expect("could not lift TraitRef for printing") .with_self_ty(tcx, dummy_self).0; - parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[]) + parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) }) } } @@ -798,7 +827,7 @@ impl<'tcx> fmt::Display for ty::Binder fmt::Display for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - parameterized(f, self.substs, self.def_id, Ns::Type, &[]) + parameterized(f, self.substs, self.def_id, &[]) } } @@ -851,7 +880,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { } write!(f, "{} {{", bare_fn.sig.0)?; - parameterized(f, substs, def_id, Ns::Value, &[])?; + parameterized(f, substs, def_id, &[])?; write!(f, "}}") } TyFnPtr(ref bare_fn) => { @@ -874,7 +903,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { !tcx.tcache.borrow().contains_key(&def.did) { write!(f, "{}<..>", tcx.item_path_str(def.did)) } else { - parameterized(f, substs, def.did, Ns::Type, &[]) + parameterized(f, substs, def.did, &[]) } }) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 3e4a2542b270b..ceb6fcb0da8c2 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1106,6 +1106,10 @@ impl<'a, 'tcx> CrateMetadata { } fn are_equal_modulo_startpos(fm1: &syntax_pos::FileMap, fm2: &syntax_pos::FileMap) -> bool { + if fm1.byte_length() != fm2.byte_length() { + return false; + } + if fm1.name != fm2.name { return false; } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 38b31db678143..798614ce58196 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -56,7 +56,7 @@ use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet}; use syntax::ext::base::MultiItemModifier; use syntax::ext::hygiene::Mark; use syntax::ast::{self, FloatTy}; -use syntax::ast::{CRATE_NODE_ID, Name, NodeId, IntTy, UintTy}; +use syntax::ast::{CRATE_NODE_ID, Name, NodeId, SpannedIdent, IntTy, UintTy}; use syntax::parse::token::{self, keywords}; use syntax::util::lev_distance::find_best_match_for_name; @@ -2237,7 +2237,7 @@ impl<'a> Resolver<'a> { } fn fresh_binding(&mut self, - ident: &ast::SpannedIdent, + ident: &SpannedIdent, pat_id: NodeId, outer_pat_id: NodeId, pat_src: PatternSource, @@ -2803,11 +2803,11 @@ impl<'a> Resolver<'a> { } SuggestionType::NotFound } - fn resolve_labeled_block(&mut self, label: Option, id: NodeId, block: &Block) { + fn resolve_labeled_block(&mut self, label: Option, id: NodeId, block: &Block) { if let Some(label) = label { let def = Def::Label(id); self.with_label_rib(|this| { - this.label_ribs.last_mut().unwrap().bindings.insert(label, def); + this.label_ribs.last_mut().unwrap().bindings.insert(label.node, def); this.visit_block(block); }); } else { @@ -3006,19 +3006,6 @@ impl<'a> Resolver<'a> { visit::walk_expr(self, expr); } - ExprKind::Loop(_, Some(label)) | ExprKind::While(.., Some(label)) => { - self.with_label_rib(|this| { - let def = Def::Label(expr.id); - - { - let rib = this.label_ribs.last_mut().unwrap(); - rib.bindings.insert(label.node, def); - } - - visit::walk_expr(this, expr); - }) - } - ExprKind::Break(Some(label)) | ExprKind::Continue(Some(label)) => { match self.search_label(label.node) { None => { @@ -3048,12 +3035,19 @@ impl<'a> Resolver<'a> { optional_else.as_ref().map(|expr| self.visit_expr(expr)); } + ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block), + + ExprKind::While(ref subexpression, ref block, label) => { + self.visit_expr(subexpression); + self.resolve_labeled_block(label, expr.id, &block); + } + ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); self.resolve_pattern(pattern, PatternSource::WhileLet, &mut FnvHashMap()); - self.resolve_labeled_block(label.map(|l| l.node), expr.id, block); + self.resolve_labeled_block(label, expr.id, block); self.value_ribs.pop(); } @@ -3063,7 +3057,7 @@ impl<'a> Resolver<'a> { self.value_ribs.push(Rib::new(NormalRibKind)); self.resolve_pattern(pattern, PatternSource::For, &mut FnvHashMap()); - self.resolve_labeled_block(label.map(|l| l.node), expr.id, block); + self.resolve_labeled_block(label, expr.id, block); self.value_ribs.pop(); } diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index ab2a39864336f..270ce79620f8b 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -26,7 +26,7 @@ pub struct Instance<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[]) + ppaux::parameterized(f, &self.substs, self.def, &[]) } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ee00cb2f5a3e4..81518496132ed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1458,7 +1458,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> { + pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> { &self.parameter_environment } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e37deaa60f219..2f4aa2e58e2f1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1296,15 +1296,12 @@ impl UnstableFeatures { pub fn from_environment() -> UnstableFeatures { // Whether this is a feature-staged build, i.e. on the beta or stable channel let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some(); - // The secret key needed to get through the rustc build itself by - // subverting the unstable features lints - let bootstrap_secret_key = option_env!("CFG_BOOTSTRAP_KEY"); - // The matching key to the above, only known by the build system - let bootstrap_provided_key = env::var("RUSTC_BOOTSTRAP_KEY").ok(); - match (disable_unstable_features, bootstrap_secret_key, bootstrap_provided_key) { - (_, Some(ref s), Some(ref p)) if s == p => UnstableFeatures::Cheat, - (true, _, _) => UnstableFeatures::Disallow, - (false, _, _) => UnstableFeatures::Allow + // Whether we should enable unstable features for bootstrapping + let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok(); + match (disable_unstable_features, bootstrap) { + (_, true) => UnstableFeatures::Cheat, + (true, _) => UnstableFeatures::Disallow, + (false, _) => UnstableFeatures::Allow } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index e3feaee5369d1..d83d3a6c5cfac 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -481,6 +481,9 @@ impl FileMap { self.src.is_none() } + pub fn byte_length(&self) -> u32 { + self.end_pos.0 - self.start_pos.0 + } pub fn count_lines(&self) -> usize { self.lines.borrow().len() } diff --git a/src/stage0.txt b/src/stage0.txt index 0f097ac766fd5..bfab0211b3b00 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -13,5 +13,4 @@ # released on `$date` rustc: 1.12.1-2016-10-20 -rustc_key: 5c6cf767 cargo: nightly-2016-08-21 diff --git a/src/test/compile-fail/resolve-label.rs b/src/test/compile-fail/resolve-label.rs index 398b4f5859e65..ed2c3e0e9b860 100644 --- a/src/test/compile-fail/resolve-label.rs +++ b/src/test/compile-fail/resolve-label.rs @@ -16,6 +16,9 @@ fn f() { } } } + + // issue #37353 + loop { 'w: while break 'w { } } //~ ERROR use of undeclared label } fn main() {} diff --git a/src/test/run-pass/issue-37291/auxiliary/lib.rs b/src/test/run-pass/issue-37291/auxiliary/lib.rs new file mode 100644 index 0000000000000..67cdea807beeb --- /dev/null +++ b/src/test/run-pass/issue-37291/auxiliary/lib.rs @@ -0,0 +1,52 @@ +// Copyright 2016 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. + +#![crate_type = "lib"] + +use std::ops::Mul; + +pub trait A {} +pub trait B { + type AT: A; +} +pub trait C { + type BT: B; +} + +pub struct AV; +impl A for AV {} + +pub struct BV; +impl B for BV { + type AT = AV; +} + +pub struct CV; +impl C for CV { + type BT = BV; +} + +pub struct WrapperB(pub T); +pub struct WrapperC(pub T); + +impl Mul::AT>> for WrapperC + where C1: C +{ + type Output = u8; + fn mul(self, _: WrapperB<::AT>) -> Self::Output { + loop {} + } +} +impl Mul> for WrapperC { + type Output = u8; + fn mul(self, _: WrapperC) -> Self::Output { + loop {} + } +} diff --git a/src/test/run-pass/issue-37291/main.rs b/src/test/run-pass/issue-37291/main.rs new file mode 100644 index 0000000000000..2461f7485f26f --- /dev/null +++ b/src/test/run-pass/issue-37291/main.rs @@ -0,0 +1,29 @@ +// Copyright 2016 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. + +// aux-build:lib.rs + +// Regression test for #37291. The problem was that the starting +// environment for a specialization check was not including the +// where-clauses from the impl when attempting to normalize the impl's +// trait-ref, so things like `::Item` could not resolve, +// since the `C: Foo` trait bound was not included in the environment. + +extern crate lib; + +use lib::{CV, WrapperB, WrapperC}; + +fn main() { + let a = WrapperC(CV); + let b = WrapperC(CV); + if false { + let _ = a * b; + } +}