From 2a5f3ee0c5b51c4d3aa4c6ab1cb7f3ffe1687c41 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 22 Mar 2018 23:58:36 +0000 Subject: [PATCH 01/19] Make --emit=metadata output metadata regardless of link --- src/librustc_trans/back/link.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index bdda7741221f5..168570df464e4 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -146,9 +146,7 @@ pub(crate) fn link_binary(sess: &Session, let mut out_filenames = Vec::new(); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-trans, as they will error. - if (sess.opts.debugging_opts.no_trans || - !sess.opts.output_types.should_trans()) && - crate_type == config::CrateTypeExecutable { + if sess.opts.debugging_opts.no_trans && crate_type == config::CrateTypeExecutable { continue; } From 8056506b1b8aef3dc1af1d6256e0665fbfc79ae9 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 31 Mar 2018 22:12:52 +0100 Subject: [PATCH 02/19] Special-case OutputType::Metadata --- src/librustc_trans/back/link.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 168570df464e4..60ce0517cfabb 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -146,7 +146,10 @@ pub(crate) fn link_binary(sess: &Session, let mut out_filenames = Vec::new(); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-trans, as they will error. - if sess.opts.debugging_opts.no_trans && crate_type == config::CrateTypeExecutable { + let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); + let ignore_executable = sess.opts.debugging_opts.no_trans || + !(sess.opts.output_types.should_trans() || output_metadata); + if crate_type == config::CrateTypeExecutable && ignore_executable { continue; } From 7575d96a98dfb5d46accf6d2744529f09c83cd6c Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 10 Apr 2018 11:12:21 +0100 Subject: [PATCH 03/19] Reformat trans skip condition --- src/librustc_trans/back/link.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 60ce0517cfabb..514d76a4129ec 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -147,9 +147,9 @@ pub(crate) fn link_binary(sess: &Session, for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-trans, as they will error. let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); - let ignore_executable = sess.opts.debugging_opts.no_trans || - !(sess.opts.output_types.should_trans() || output_metadata); - if crate_type == config::CrateTypeExecutable && ignore_executable { + if (sess.opts.debugging_opts.no_trans || !sess.opts.output_types.should_trans()) && + !output_metadata && + crate_type == config::CrateTypeExecutable { continue; } From 7d939200db5d31a666547f2e1998ef9ea53537c7 Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Tue, 3 Apr 2018 17:53:13 +0200 Subject: [PATCH 04/19] Implement Chalk lowering rule Normalize-From-Impl --- src/librustc/ich/impls_ty.rs | 1 + src/librustc/traits/mod.rs | 1 + src/librustc/traits/structural_impls.rs | 2 + src/librustc_traits/lowering.rs | 65 +++++++++++++++++++++++-- src/test/ui/chalkify/lower_impl.rs | 9 ++++ src/test/ui/chalkify/lower_impl.stderr | 8 ++- 6 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index af4d3429bb1d5..cdaf79fe84cdd 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1373,6 +1373,7 @@ impl<'a, 'tcx> HashStable> for traits::DomainGoal<'tcx> FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher), WellFormedTy(ty) => ty.hash_stable(hcx, hasher), + Normalize(projection) => projection.hash_stable(hcx, hasher), FromEnvTy(ty) => ty.hash_stable(hcx, hasher), RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher), TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher), diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b30fb2ce016df..bf81cd197bf01 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -267,6 +267,7 @@ pub enum DomainGoal<'tcx> { WellFormed(WhereClauseAtom<'tcx>), FromEnv(WhereClauseAtom<'tcx>), WellFormedTy(Ty<'tcx>), + Normalize(ty::ProjectionPredicate<'tcx>), FromEnvTy(Ty<'tcx>), RegionOutlives(ty::RegionOutlivesPredicate<'tcx>), TypeOutlives(ty::TypeOutlivesPredicate<'tcx>), diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 865a9a34aaa25..e8d31d401847e 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -449,6 +449,7 @@ impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { FromEnv(Implemented(trait_ref)) => write!(fmt, "FromEnv({})", trait_ref), FromEnv(ProjectionEq(projection)) => write!(fmt, "FromEnv({})", projection), WellFormedTy(ty) => write!(fmt, "WellFormed({})", ty), + Normalize(projection) => write!(fmt, "Normalize({})", projection), FromEnvTy(ty) => write!(fmt, "FromEnv({})", ty), RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate), TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate), @@ -537,6 +538,7 @@ EnumTypeFoldableImpl! { (traits::DomainGoal::WellFormed)(wc), (traits::DomainGoal::FromEnv)(wc), (traits::DomainGoal::WellFormedTy)(ty), + (traits::DomainGoal::Normalize)(projection), (traits::DomainGoal::FromEnvTy)(ty), (traits::DomainGoal::RegionOutlives)(predicate), (traits::DomainGoal::TypeOutlives)(predicate), diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index 3d24b087c5958..b735cc1417eba 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -116,10 +116,20 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI -> Lrc>> { let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let item = tcx.hir.expect_item(node_id); - match item.node { - hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id), - hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), + let node = tcx.hir.find(node_id).unwrap(); + match node { + hir::map::Node::NodeItem(item) => match item.node { + hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id), + hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), + _ => Lrc::new(vec![]), + } + hir::map::Node::NodeImplItem(item) => { + if let hir::ImplItemKind::Type(..) = item.node { + program_clauses_for_associated_type(tcx, def_id) + } else { + Lrc::new(vec![]) + } + }, // FIXME: other constructions e.g. traits, associated types... _ => Lrc::new(vec![]), @@ -229,6 +239,53 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId Lrc::new(vec![Clause::ForAll(ty::Binder::dummy(clause))]) } +pub fn program_clauses_for_associated_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: DefId) + -> Lrc>> { + // Rule Normalize-From-Impl (see rustc guide) + // + // ```impl Trait for A0 + // where WC + // { + // type AssocType where WC1 = T; + // }``` + // + // ``` + // forall { + // forall { + // Normalize(>::AssocType -> T) :- + // WC && WC1 + // } + // } + // ``` + + let item = tcx.associated_item(item_id); + debug_assert_eq!(item.kind, ty::AssociatedKind::Type); + let impl_id = if let ty::AssociatedItemContainer::ImplContainer(impl_id) = item.container { + impl_id + } else { + bug!() + }; + // `A0 as Trait` + let trait_ref = tcx.impl_trait_ref(impl_id).unwrap(); + // `T` + let ty = tcx.type_of(item_id); + // `WC` + let impl_where_clauses = tcx.predicates_of(impl_id).predicates.lower(); + // `WC1` + let item_where_clauses = tcx.predicates_of(item_id).predicates.lower(); + // `WC && WC1` + let mut where_clauses = vec![]; + where_clauses.extend(impl_where_clauses); + where_clauses.extend(item_where_clauses); + // `>::AssocType` + let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name); + // `Normalize(>::AssocType -> T)` + let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty }); + // `Normalize(... -> T) :- WC && WC1` + let clause = Clause::Implies(where_clauses, normalize_goal); + Lrc::new(vec![clause]) +} + pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { if !tcx.features().rustc_attrs { return; diff --git a/src/test/ui/chalkify/lower_impl.rs b/src/test/ui/chalkify/lower_impl.rs index 2083ada6d2de5..671d77efbea3a 100644 --- a/src/test/ui/chalkify/lower_impl.rs +++ b/src/test/ui/chalkify/lower_impl.rs @@ -15,6 +15,15 @@ trait Foo { } #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- impl Foo for T where T: Iterator { } +trait Bar { + type Assoc; +} + +impl Bar for T where T: Iterator { + #[rustc_dump_program_clauses] //~ ERROR Normalize(::Assoc == std::vec::Vec) :- + type Assoc = Vec; +} + fn main() { println!("hello"); } diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr index b5d791d640ada..5a32b8567b99f 100644 --- a/src/test/ui/chalkify/lower_impl.stderr +++ b/src/test/ui/chalkify/lower_impl.stderr @@ -4,5 +4,11 @@ error: Implemented(T: Foo) :- ProjectionEq(::Item == i LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: Normalize(::Assoc == std::vec::Vec) :- ProjectionEq(::Item == i32), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized). + --> $DIR/lower_impl.rs:23:5 + | +LL | #[rustc_dump_program_clauses] //~ ERROR Normalize(::Assoc == std::vec::Vec) :- + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors From 0bf3eb6013210a957c7d6929338e5f4bb24d704e Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Sat, 7 Apr 2018 02:04:28 +0200 Subject: [PATCH 05/19] Improve function name. --- src/librustc_traits/lowering.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index b735cc1417eba..5c5ca42f468da 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -125,7 +125,7 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI } hir::map::Node::NodeImplItem(item) => { if let hir::ImplItemKind::Type(..) = item.node { - program_clauses_for_associated_type(tcx, def_id) + program_clauses_for_associated_type_value(tcx, def_id) } else { Lrc::new(vec![]) } @@ -239,8 +239,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId Lrc::new(vec![Clause::ForAll(ty::Binder::dummy(clause))]) } -pub fn program_clauses_for_associated_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: DefId) - -> Lrc>> { +pub fn program_clauses_for_associated_type_value<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: DefId, +) -> Lrc>> { // Rule Normalize-From-Impl (see rustc guide) // // ```impl Trait for A0 From 7e5003907990f0ca33b490936dcc01c982dbf52c Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Wed, 11 Apr 2018 14:27:00 +0200 Subject: [PATCH 06/19] Rebase and update code. --- src/librustc_traits/lowering.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index 5c5ca42f468da..1cc5715f12354 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -106,6 +106,7 @@ impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> { FromEnv(..) | WellFormedTy(..) | FromEnvTy(..) | + Normalize(..) | RegionOutlives(..) | TypeOutlives(..) => self, } @@ -284,8 +285,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>( // `Normalize(>::AssocType -> T)` let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty }); // `Normalize(... -> T) :- WC && WC1` - let clause = Clause::Implies(where_clauses, normalize_goal); - Lrc::new(vec![clause]) + let clause = ProgramClause { + goal: normalize_goal, + hypotheses: where_clauses.into_iter().map(|wc| wc.into()).collect(), + }; + Lrc::new(vec![Clause::ForAll(ty::Binder::dummy(clause))]) } pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { From 34956c8e8e9c5cda3020de052d0c6e76895d4472 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 11 Apr 2018 14:56:59 +0200 Subject: [PATCH 07/19] Don't inject clippy into rls on stable/beta --- src/bootstrap/tool.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 5fc92611e6529..97507bc08698a 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -564,7 +564,8 @@ tool_extended!((self, builder), target: self.target, extra_features: Vec::new(), }); - if clippy.is_some() { + let channel = &builder.config.channel; + if clippy.is_some() && channel != "stable" && channel != "beta" { self.extra_features.push("clippy".to_owned()); } builder.ensure(native::Openssl { From 0b393e053895055f86975cf40169701006dbe54b Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 11 Apr 2018 19:54:48 +0100 Subject: [PATCH 08/19] Ignore copyright year when generating deriving span tests Previously, generate-deriving-span-tests.py would regenerate all the tests anew, even if they hadn't changed. This creates unnecessary diffs that only change the copyright year. Now we check to see if any of the content of the test has changed before generating the new one. --- src/etc/generate-deriving-span-tests.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index 15c9fc2e504a1..5b106275ac9d2 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -18,7 +18,7 @@ sample usage: src/etc/generate-deriving-span-tests.py """ -import sys, os, datetime, stat +import sys, os, datetime, stat, re TEST_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '../test/compile-fail')) @@ -87,16 +87,25 @@ def create_test_case(type, trait, super_traits, error_count): def write_file(name, string): test_file = os.path.join(TEST_DIR, 'derives-span-%s.rs' % name) + with open(test_file) as f: + old_str = f.read() + old_str_ignoring_date = re.sub(r'^// Copyright \d+', + '// Copyright {year}'.format(year = YEAR), old_str) + if old_str_ignoring_date == string: + # if all we're doing is updating the copyright year, ignore it + return 0 + # set write permission if file exists, so it can be changed if os.path.exists(test_file): os.chmod(test_file, stat.S_IWUSR) - with open(test_file, 'wt') as f: + with open(test_file, 'w') as f: f.write(string) # mark file read-only os.chmod(test_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) + return 1 ENUM = 1 @@ -120,11 +129,15 @@ def write_file(name, string): ('Hash', [], 1)]: traits[trait] = (ALL, supers, errs) +files = 0 + for (trait, (types, super_traits, error_count)) in traits.items(): mk = lambda ty: create_test_case(ty, trait, super_traits, error_count) if types & ENUM: - write_file(trait + '-enum', mk(ENUM_TUPLE)) - write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) + files += write_file(trait + '-enum', mk(ENUM_TUPLE)) + files += write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT)) if types & STRUCT: - write_file(trait + '-struct', mk(STRUCT_FIELDS)) - write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE)) + files += write_file(trait + '-struct', mk(STRUCT_FIELDS)) + files += write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE)) + +print('Generated {files} deriving span test{}.'.format('s' if files != 1 else '', files = files)) From 2ef8493095b7b222270fe55cb2d5e5e26eb81903 Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Wed, 11 Apr 2018 21:20:25 +0200 Subject: [PATCH 09/19] Stop duplicating where clauses from impl's. --- src/librustc_traits/lowering.rs | 16 +++++++--------- src/test/ui/chalkify/lower_impl.stderr | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index 1cc5715f12354..5068662651ac6 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -247,16 +247,15 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>( // Rule Normalize-From-Impl (see rustc guide) // // ```impl Trait for A0 - // where WC // { - // type AssocType where WC1 = T; + // type AssocType where WC = T; // }``` // // ``` // forall { // forall { // Normalize(>::AssocType -> T) :- - // WC && WC1 + // Implemented(A0: Trait) && WC // } // } // ``` @@ -272,19 +271,18 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>( let trait_ref = tcx.impl_trait_ref(impl_id).unwrap(); // `T` let ty = tcx.type_of(item_id); + // `Implemented(A0: Trait)` + let trait_implemented = ty::Binder::dummy(ty::TraitPredicate { trait_ref }.lower()); // `WC` - let impl_where_clauses = tcx.predicates_of(impl_id).predicates.lower(); - // `WC1` let item_where_clauses = tcx.predicates_of(item_id).predicates.lower(); - // `WC && WC1` - let mut where_clauses = vec![]; - where_clauses.extend(impl_where_clauses); + // `Implemented(A0: Trait) && WC` + let mut where_clauses = vec![trait_implemented]; where_clauses.extend(item_where_clauses); // `>::AssocType` let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.name); // `Normalize(>::AssocType -> T)` let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty }); - // `Normalize(... -> T) :- WC && WC1` + // `Normalize(... -> T) :- ...` let clause = ProgramClause { goal: normalize_goal, hypotheses: where_clauses.into_iter().map(|wc| wc.into()).collect(), diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr index 5a32b8567b99f..f253f9847d162 100644 --- a/src/test/ui/chalkify/lower_impl.stderr +++ b/src/test/ui/chalkify/lower_impl.stderr @@ -4,7 +4,7 @@ error: Implemented(T: Foo) :- ProjectionEq(::Item == i LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Normalize(::Assoc == std::vec::Vec) :- ProjectionEq(::Item == i32), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized). +error: Normalize(::Assoc == std::vec::Vec) :- Implemented(T: Bar). --> $DIR/lower_impl.rs:23:5 | LL | #[rustc_dump_program_clauses] //~ ERROR Normalize(::Assoc == std::vec::Vec) :- From ec3bccb69f1d9725a8bd83ce69739d3bad0a76cf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 11 Apr 2018 10:47:16 -0700 Subject: [PATCH 10/19] core: Remove panics from some `Layout` methods `Layout` is often used at the core of allocation APIs and is as a result pretty sensitive to codegen in various circumstances. I was profiling `-C opt-level=z` with a wasm project recently and noticed that the `unwrap()` wasn't removed inside of `Layout`, causing the program to be much larger than it otherwise would be. If inlining were more aggressive LLVM would have figured out that the panic could be eliminated, but in general the methods here can't panic in the first place! As a result this commit makes the following tweaks: * Removes `unwrap()` and replaces it with `unsafe` in `Layout::new` and `Layout::for_value`. For posterity though a debug assertion was left behind. * Removes an `unwrap()` in favor of `?` in the `repeat` method. The comment indicating that the function call couldn't panic wasn't quite right in that if `alloc_size` becomes too large and if `align` is high enough it could indeed cause a panic. This'll hopefully mean that panics never get introduced into code in the first place, ensuring that `opt-level=z` is closer to `opt-level=s` in this regard. --- src/libcore/heap.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libcore/heap.rs b/src/libcore/heap.rs index fe19c923a58d1..3df8fd5fc615e 100644 --- a/src/libcore/heap.rs +++ b/src/libcore/heap.rs @@ -125,7 +125,14 @@ impl Layout { /// Constructs a `Layout` suitable for holding a value of type `T`. pub fn new() -> Self { let (size, align) = size_align::(); - Layout::from_size_align(size, align).unwrap() + // Note that the align is guaranteed by rustc to be a power of two and + // the size+align combo is guaranteed to fit in our address space. As a + // result use the unchecked constructor here to avoid inserting code + // that panics if it isn't optimized well enough. + debug_assert!(Layout::from_size_align(size, align).is_some()); + unsafe { + Layout::from_size_align_unchecked(size, align) + } } /// Produces layout describing a record that could be used to @@ -133,7 +140,11 @@ impl Layout { /// or other unsized type like a slice). pub fn for_value(t: &T) -> Self { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); - Layout::from_size_align(size, align).unwrap() + // See rationale in `new` for why this us using an unsafe variant below + debug_assert!(Layout::from_size_align(size, align).is_some()); + unsafe { + Layout::from_size_align_unchecked(size, align) + } } /// Creates a layout describing the record that can hold a value @@ -212,12 +223,7 @@ impl Layout { pub fn repeat(&self, n: usize) -> Option<(Self, usize)> { let padded_size = self.size.checked_add(self.padding_needed_for(self.align))?; let alloc_size = padded_size.checked_mul(n)?; - - // We can assume that `self.align` is a power-of-two. - // Furthermore, `alloc_size` has already been rounded up - // to a multiple of `self.align`; therefore, the call to - // `Layout::from_size_align` below should never panic. - Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size)) + Some((Layout::from_size_align(alloc_size, self.align)?, padded_size)) } /// Creates a layout describing the record for `self` followed by From d554f4c0b922362f991488cf3bc7aca39e53dbf8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 12 Apr 2018 14:51:10 +0200 Subject: [PATCH 11/19] Add #[no_debug] to trans_fn_attrs() query. --- src/librustc/hir/mod.rs | 1 + src/librustc_typeck/collect.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index be8cceb611896..a65a461a228ad 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2280,6 +2280,7 @@ bitflags! { const NAKED = 0b0001_0000; const NO_MANGLE = 0b0010_0000; const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000; + const NO_DEBUG = 0b1000_0000; } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a4f820d1fdcf9..07f4a13a197ce 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1785,6 +1785,8 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt 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("no_debug") { + trans_fn_attrs.flags |= TransFnAttrFlags::NO_DEBUG; } else if attr.check_name("inline") { trans_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| { if attr.path != "inline" { From f78b8c0f14c259dbe2bc2243737a8442bda01361 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 12 Apr 2018 14:52:09 +0200 Subject: [PATCH 12/19] Support #[no_debug] for global variables. --- src/librustc_trans/debuginfo/metadata.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index f3d95cf794bab..eb550d7a605c5 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -23,6 +23,7 @@ use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock, DIFlags}; +use rustc::hir::TransFnAttrFlags; use rustc::hir::def::CtorKind; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::ty::fold::TypeVisitor; @@ -41,7 +42,7 @@ use std::ffi::CString; use std::fmt::Write; use std::ptr; use std::path::{Path, PathBuf}; -use syntax::{ast, attr}; +use syntax::ast; use syntax::symbol::{Interner, InternedString, Symbol}; use syntax_pos::{self, Span, FileName}; @@ -1644,11 +1645,17 @@ pub fn create_global_var_metadata(cx: &CodegenCx, } let tcx = cx.tcx; - let no_mangle = attr::contains_name(&tcx.get_attrs(def_id), "no_mangle"); + let attrs = tcx.trans_fn_attrs(def_id); + + if attrs.flags.contains(TransFnAttrFlags::NO_DEBUG) { + return; + } + + let no_mangle = attrs.flags.contains(TransFnAttrFlags::NO_MANGLE); // We may want to remove the namespace scope if we're in an extern block, see: // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952 let var_scope = get_namespace_for_item(cx, def_id); - let span = cx.tcx.def_span(def_id); + let span = tcx.def_span(def_id); let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { let loc = span_start(cx, span); From f711c058e7e0ffdcc7e5ae7698d352eb8634a8ca Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 12 Apr 2018 14:52:43 +0200 Subject: [PATCH 13/19] Clean up attribute handling in create_function_debug_context(). --- src/librustc_trans/debuginfo/mod.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 87d9623e40038..a5e50d34da212 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -23,6 +23,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags}; +use rustc::hir::TransFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum}; use rustc::ty::subst::Substs; @@ -30,7 +31,7 @@ use abi::Abi; use common::CodegenCx; use builder::Builder; use monomorphize::Instance; -use rustc::ty::{self, ParamEnv, Ty}; +use rustc::ty::{self, ParamEnv, Ty, InstanceDef}; use rustc::mir; use rustc::session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; @@ -210,13 +211,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return FunctionDebugContext::DebugInfoDisabled; } - for attr in instance.def.attrs(cx.tcx).iter() { - if attr.check_name("no_debug") { - return FunctionDebugContext::FunctionWithoutDebugInfo; - } + let def_id = if let InstanceDef::Item(def_id) = instance.def { + def_id + } else { + return FunctionDebugContext::FunctionWithoutDebugInfo; + }; + + if cx.tcx.trans_fn_attrs(def_id).flags.contains(TransFnAttrFlags::NO_DEBUG) { + return FunctionDebugContext::FunctionWithoutDebugInfo; } - let containing_scope = get_containing_scope(cx, instance); let span = mir.span; // This can be the case for functions inlined from another crate @@ -225,7 +229,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return FunctionDebugContext::FunctionWithoutDebugInfo; } - let def_id = instance.def_id(); + let containing_scope = get_containing_scope(cx, instance); let loc = span_start(cx, span); let file_metadata = file_metadata(cx, &loc.file.name, def_id.krate); From f1610ae8ae00529b02107076e90f2370525fa142 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 12 Apr 2018 14:53:50 +0200 Subject: [PATCH 14/19] Use #[no_debug] to work around LLVM problem with rustc_driver::get_trans::LOAD. --- src/librustc_driver/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3dec84d174dd8..df01c1279e881 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,6 +25,7 @@ #![feature(slice_sort_by_cached_key)] #![feature(set_stdio)] #![feature(rustc_stack_internals)] +#![feature(no_debug)] extern crate arena; extern crate getopts; @@ -230,6 +231,9 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box { pub fn get_trans(sess: &Session) -> Box { static INIT: Once = ONCE_INIT; + + #[allow(deprecated)] + #[no_debug] static mut LOAD: fn() -> Box = || unreachable!(); INIT.call_once(|| { From 6f10146f9f327bfebbae4083d40ffbeb412e3198 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Thu, 12 Apr 2018 15:01:49 +0100 Subject: [PATCH 15/19] Fix test failure in src/tools/rustdoc-themes when rust.rpath = false --- src/bootstrap/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c175d2c69016f..72995db959ab5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -459,7 +459,7 @@ impl Step for RustdocTheme { } fn run(self, builder: &Builder) { - let rustdoc = builder.rustdoc(self.compiler.host); + let rustdoc = builder.out.join("bootstrap/debug/rustdoc"); let mut cmd = builder.tool_cmd(Tool::RustdocTheme); cmd.arg(rustdoc.to_str().unwrap()) .arg(builder.src.join("src/librustdoc/html/static/themes").to_str().unwrap()) From de345332b50a4bce2e56d95b5478439c9501a14b Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Wed, 11 Apr 2018 09:46:58 -0600 Subject: [PATCH 16/19] Add check builder for Windows to Travis --- .travis.yml | 2 ++ src/ci/docker/mingw-check/Dockerfile | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/ci/docker/mingw-check/Dockerfile diff --git a/.travis.yml b/.travis.yml index f36ad67b11103..63831cd596122 100644 --- a/.travis.yml +++ b/.travis.yml @@ -176,6 +176,8 @@ matrix: if: branch = auto - env: IMAGE=x86_64-gnu-distcheck if: branch = auto + - env: IMAGE=mingw-check + if: type = pull_request OR branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/ci/docker/mingw-check/Dockerfile b/src/ci/docker/mingw-check/Dockerfile new file mode 100644 index 0000000000000..ae4641009cf1d --- /dev/null +++ b/src/ci/docker/mingw-check/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + sudo \ + gdb \ + xz-utils \ + libssl-dev \ + pkg-config \ + mingw-w64 + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu From 807c1a0935d4acbf637601e81fc078d7d7098650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Feb 2018 10:52:26 +0100 Subject: [PATCH 17/19] Make OnDiskCache thread-safer --- src/librustc/ty/context.rs | 6 ++-- src/librustc/ty/maps/on_disk_cache.rs | 45 +++++++++++++-------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1e5d0753e6932..6e7b070378e28 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -61,7 +61,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::{Lrc, Lock}; use std::any::Any; use std::borrow::Borrow; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::cmp::Ordering; use std::collections::hash_map::{self, Entry}; use std::hash::{Hash, Hasher}; @@ -867,7 +867,7 @@ pub struct GlobalCtxt<'tcx> { maybe_unused_extern_crates: Vec<(DefId, Span)>, // Internal cache for metadata decoding. No need to track deps on this. - pub rcache: RefCell>>, + pub rcache: Lock>>, /// Caches the results of trait selection. This cache is used /// for things that do not have to do with the parameters in scope. @@ -1263,7 +1263,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { hir, def_path_hash_to_def_id, maps: maps::Maps::new(providers), - rcache: RefCell::new(FxHashMap()), + rcache: Lock::new(FxHashMap()), selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), crate_name: Symbol::intern(crate_name), diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 4d78703613e94..9ea4b21c55221 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -17,7 +17,7 @@ use hir::map::definitions::DefPathHash; use ich::{CachingCodemapView, Fingerprint}; use mir::{self, interpret}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, SpecializedDecoder, SpecializedEncoder, @@ -57,17 +57,17 @@ pub struct OnDiskCache<'sess> { // This field collects all Diagnostics emitted during the current // compilation session. - current_diagnostics: RefCell>>, + current_diagnostics: Lock>>, prev_cnums: Vec<(u32, String, CrateDisambiguator)>, - cnum_map: RefCell>>>, + cnum_map: Once>>, codemap: &'sess CodeMap, file_index_to_stable_id: FxHashMap, // These two fields caches that are populated lazily during decoding. - file_index_to_file: RefCell>>, - synthetic_expansion_infos: RefCell>, + file_index_to_file: Lock>>, + synthetic_expansion_infos: Lock>, // A map from dep-node to the position of the cached query result in // `serialized_data`. @@ -140,14 +140,14 @@ impl<'sess> OnDiskCache<'sess> { OnDiskCache { serialized_data: data, file_index_to_stable_id: footer.file_index_to_stable_id, - file_index_to_file: RefCell::new(FxHashMap()), + file_index_to_file: Lock::new(FxHashMap()), prev_cnums: footer.prev_cnums, - cnum_map: RefCell::new(None), + cnum_map: Once::new(), codemap: sess.codemap(), - current_diagnostics: RefCell::new(FxHashMap()), + current_diagnostics: Lock::new(FxHashMap()), query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), - synthetic_expansion_infos: RefCell::new(FxHashMap()), + synthetic_expansion_infos: Lock::new(FxHashMap()), interpret_alloc_cache: RefCell::new(FxHashMap::default()), interpret_alloc_size: RefCell::new(FxHashMap::default()), } @@ -157,14 +157,14 @@ impl<'sess> OnDiskCache<'sess> { OnDiskCache { serialized_data: Vec::new(), file_index_to_stable_id: FxHashMap(), - file_index_to_file: RefCell::new(FxHashMap()), + file_index_to_file: Lock::new(FxHashMap()), prev_cnums: vec![], - cnum_map: RefCell::new(None), + cnum_map: Once::new(), codemap, - current_diagnostics: RefCell::new(FxHashMap()), + current_diagnostics: Lock::new(FxHashMap()), query_result_index: FxHashMap(), prev_diagnostics_index: FxHashMap(), - synthetic_expansion_infos: RefCell::new(FxHashMap()), + synthetic_expansion_infos: Lock::new(FxHashMap()), interpret_alloc_cache: RefCell::new(FxHashMap::default()), interpret_alloc_size: RefCell::new(FxHashMap::default()), } @@ -383,18 +383,16 @@ impl<'sess> OnDiskCache<'sess> { return None }; - // Initialize the cnum_map if it is not initialized yet. - if self.cnum_map.borrow().is_none() { - let mut cnum_map = self.cnum_map.borrow_mut(); - *cnum_map = Some(Self::compute_cnum_map(tcx, &self.prev_cnums[..])); - } - let cnum_map = self.cnum_map.borrow(); + // Initialize the cnum_map using the value from the thread which finishes the closure first + self.cnum_map.init_nonlocking_same(|| { + Self::compute_cnum_map(tcx, &self.prev_cnums[..]) + }); let mut decoder = CacheDecoder { tcx, opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()), codemap: self.codemap, - cnum_map: cnum_map.as_ref().unwrap(), + cnum_map: self.cnum_map.get(), file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, synthetic_expansion_infos: &self.synthetic_expansion_infos, @@ -458,8 +456,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> { opaque: opaque::Decoder<'x>, codemap: &'x CodeMap, cnum_map: &'x IndexVec>, - synthetic_expansion_infos: &'x RefCell>, - file_index_to_file: &'x RefCell>>, + synthetic_expansion_infos: &'x Lock>, + file_index_to_file: &'x Lock>>, file_index_to_stable_id: &'x FxHashMap, interpret_alloc_cache: &'x RefCell>, interpret_alloc_size: &'x RefCell>, @@ -557,7 +555,8 @@ impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, } let ty = or_insert_with(self)?; - tcx.rcache.borrow_mut().insert(cache_key, ty); + // This may overwrite the entry, but it should overwrite with the same value + tcx.rcache.borrow_mut().insert_same(cache_key, ty); Ok(ty) } From 2f603413ab4764898f63f532c7c26291409e0aa7 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Thu, 12 Apr 2018 22:48:48 +0200 Subject: [PATCH 18/19] improve Atomic*::fetch_update docs --- src/libcore/sync/atomic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index d336934ec7214..62e0979c5fefc 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1425,8 +1425,8 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); doc_comment! { concat!("Fetches the value, and applies a function to it that returns an optional -new value. Returns a `Result` (`Ok(_)` if the function returned `Some(_)`, else `Err(_)`) of the -previous value. +new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else +`Err(previous_value)`. Note: This may call the function multiple times if the value has been changed from other threads in the meantime, as long as the function returns `Some(_)`, but the function will have been applied From 35087fcb89d8d6ba8e9490e9aadeaf6987c55e34 Mon Sep 17 00:00:00 2001 From: Fabio B Date: Fri, 13 Apr 2018 09:43:10 +0200 Subject: [PATCH 19/19] Remove -Z miri debugging option --- src/bootstrap/bin/rustc.rs | 3 --- src/bootstrap/test.rs | 2 +- src/librustc/session/config.rs | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 3dd9b6840591b..b6ae824c37601 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -247,9 +247,6 @@ fn main() { // When running miri tests, we need to generate MIR for all libraries if env::var("TEST_MIRI").ok().map_or(false, |val| val == "true") { cmd.arg("-Zalways-encode-mir"); - if stage != "0" { - cmd.arg("-Zmiri"); - } cmd.arg("-Zmir-emit-validate=1"); } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c175d2c69016f..aff48799526d1 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -875,7 +875,7 @@ impl Step for Compiletest { if build.config.rust_debuginfo_tests { flags.push("-g".to_string()); } - flags.push("-Zmiri -Zunstable-options".to_string()); + flags.push("-Zunstable-options".to_string()); flags.push(build.config.cmd.rustc_args().join(" ")); if let Some(linker) = build.linker(target) { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a07370e1e42a7..f0b4d0cc70a92 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1229,8 +1229,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "print some statistics about MIR"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata"), - miri: bool = (false, parse_bool, [TRACKED], - "check the miri const evaluator against the old ctfe"), osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], "pass `-install_name @rpath/...` to the macOS linker"), sanitizer: Option = (None, parse_sanitizer, [TRACKED],