From ba53f956769362329a83d73561c6790c91ae7c4d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jul 2017 17:44:48 -0700 Subject: [PATCH 01/38] E0122: clarify wording --- src/librustc_typeck/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 87e59683fd2a..050d89678165 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1611,8 +1611,8 @@ static BAR: _ = "test"; // error, explicitly write out the type instead "##, E0122: r##" -An attempt was made to add a generic constraint to a type alias. While Rust will -allow this with a warning, it will not currently enforce the constraint. +An attempt was made to add a generic constraint to a type alias. This constraint is +entirely ignored. For backwards compatibility, Rust still allows this with a warning. Consider the example below: ``` From 5067ef224f1dd2b14a0907e9b058b25f48a82abd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jul 2017 21:10:57 -0700 Subject: [PATCH 02/38] fix line lengths --- src/librustc_typeck/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 050d89678165..2b2ff66e3b37 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1611,9 +1611,9 @@ static BAR: _ = "test"; // error, explicitly write out the type instead "##, E0122: r##" -An attempt was made to add a generic constraint to a type alias. This constraint is -entirely ignored. For backwards compatibility, Rust still allows this with a warning. -Consider the example below: +An attempt was made to add a generic constraint to a type alias. This constraint +is entirely ignored. For backwards compatibility, Rust still allows this with a +warning. Consider the example below: ``` trait Foo{} From d2fc06e7f6068f3e30a21099f4cf4a2e423e9159 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Mon, 17 Jul 2017 22:26:21 -0400 Subject: [PATCH 03/38] Renumber regions as the first step of the non-lexical lifetimes inference --- src/librustc_mir/transform/nll.rs | 94 +++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll.rs index 3273b4ff347e..65294e9ef24b 100644 --- a/src/librustc_mir/transform/nll.rs +++ b/src/librustc_mir/transform/nll.rs @@ -8,26 +8,90 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::ty::TyCtxt; -use rustc::mir::Mir; +use rustc::ty::TypeFoldable; +use rustc::ty::subst::Substs; +use rustc::ty::{Ty, TyCtxt, ClosureSubsts}; +use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::mir::transform::{MirPass, MirSource}; +use rustc::infer::{self, InferCtxt}; +use syntax_pos::Span; #[allow(dead_code)] -struct NLLVisitor<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, +struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + infcx: InferCtxt<'a, 'gcx, 'tcx>, + source: Mir<'tcx> } -impl<'a, 'tcx> NLLVisitor<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { +impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { + pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: Mir<'tcx>) -> Self { NLLVisitor { - tcx: tcx + infcx: infcx, + source: source, } } + + fn renumber_regions(&self, value: &T, span: Span) -> T where T: TypeFoldable<'tcx> { + self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { + self.infcx.next_region_var(infer::MiscVariable(span)) + }) + } } -impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> { - // FIXME: Nashenas88: implement me! +fn span_from_location<'tcx>(source: Mir<'tcx>, location: Location) -> Span { + source[location.block].statements[location.statement_index].source_info.span +} + +impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { + fn visit_ty(&mut self, ty: &mut Ty<'tcx>) { + let old_ty = *ty; + // FIXME: Nashenas88 - span should be narrowed down + *ty = self.renumber_regions(&old_ty, self.source.span); + } + + fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) { + // FIXME: Nashenas88 - span should be narrowed down + *substs = self.renumber_regions(&{*substs}, self.source.span); + } + + fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { + match *rvalue { + Rvalue::Ref(ref mut r, _, _) => { + let span = span_from_location(location); + let old_r = *r; + *r = self.renumber_regions(&old_r, span); + } + Rvalue::Use(..) | + Rvalue::Repeat(..) | + Rvalue::Len(..) | + Rvalue::Cast(..) | + Rvalue::BinaryOp(..) | + Rvalue::CheckedBinaryOp(..) | + Rvalue::UnaryOp(..) | + Rvalue::Discriminant(..) | + Rvalue::NullaryOp(..) | + Rvalue::Aggregate(..) => { + // These variants don't contain regions. + } + } + self.super_rvalue(rvalue, location); + } + + fn visit_closure_substs(&mut self, + substs: &mut ClosureSubsts<'tcx>) { + // FIXME: Nashenas88 - span should be narrowed down + *substs = self.renumber_regions(substs, self.source.span); + } + + fn visit_statement(&mut self, + block: BasicBlock, + statement: &mut Statement<'tcx>, + location: Location) { + if let StatementKind::EndRegion(_) = statement.kind { + statement.kind = StatementKind::Nop; + } + self.super_statement(block, statement, location); + } } // MIR Pass for non-lexical lifetimes @@ -38,10 +102,16 @@ impl MirPass for NLL { tcx: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) { - if tcx.sess.opts.debugging_opts.nll { + if !tcx.sess.opts.debugging_opts.nll { + return; + } + + tcx.infer_ctxt().enter(|infcx| { + let mut visitor = NLLVisitor::new(infcx, mir.clone()); // Clone mir so we can mutate it without disturbing the rest // of the compiler - NLLVisitor::new(tcx).visit_mir(&mut mir.clone()); - } + let mut mir = mir.clone(); + visitor.visit_mir(&mut mir); + }) } } \ No newline at end of file From 5b2f6c7302cd81040d77e35aabac376bc33e4512 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Sun, 30 Jul 2017 15:08:07 -0400 Subject: [PATCH 04/38] Consume MirVisitor changes and use more accurate spans for region renumbering --- src/librustc_mir/transform/nll.rs | 41 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll.rs index 65294e9ef24b..0793bdabf0ba 100644 --- a/src/librustc_mir/transform/nll.rs +++ b/src/librustc_mir/transform/nll.rs @@ -12,7 +12,7 @@ use rustc::ty::TypeFoldable; use rustc::ty::subst::Substs; use rustc::ty::{Ty, TyCtxt, ClosureSubsts}; use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind}; -use rustc::mir::visit::MutVisitor; +use rustc::mir::visit::{MutVisitor, Lookup}; use rustc::mir::transform::{MirPass, MirSource}; use rustc::infer::{self, InferCtxt}; use syntax_pos::Span; @@ -20,11 +20,11 @@ use syntax_pos::Span; #[allow(dead_code)] struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { infcx: InferCtxt<'a, 'gcx, 'tcx>, - source: Mir<'tcx> + source: &'a Mir<'tcx> } impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { - pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: Mir<'tcx>) -> Self { + pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: &'a Mir<'tcx>) -> Self { NLLVisitor { infcx: infcx, source: source, @@ -38,28 +38,29 @@ impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { } } -fn span_from_location<'tcx>(source: Mir<'tcx>, location: Location) -> Span { +fn span_from_location<'tcx>(source: &Mir<'tcx>, location: Location) -> Span { source[location.block].statements[location.statement_index].source_info.span } impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { - fn visit_ty(&mut self, ty: &mut Ty<'tcx>) { + fn visit_ty(&mut self, ty: &mut Ty<'tcx>, lookup: Lookup) { let old_ty = *ty; - // FIXME: Nashenas88 - span should be narrowed down - *ty = self.renumber_regions(&old_ty, self.source.span); + let span = match lookup { + Lookup::Loc(location) => span_from_location(self.source, location), + Lookup::Src(source_info) => source_info.span, + }; + *ty = self.renumber_regions(&old_ty, span); } - fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) { - // FIXME: Nashenas88 - span should be narrowed down - *substs = self.renumber_regions(&{*substs}, self.source.span); + fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) { + *substs = self.renumber_regions(&{*substs}, span_from_location(self.source, location)); } fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { match *rvalue { Rvalue::Ref(ref mut r, _, _) => { - let span = span_from_location(location); let old_r = *r; - *r = self.renumber_regions(&old_r, span); + *r = self.renumber_regions(&old_r, span_from_location(self.source, location)); } Rvalue::Use(..) | Rvalue::Repeat(..) | @@ -78,9 +79,9 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { } fn visit_closure_substs(&mut self, - substs: &mut ClosureSubsts<'tcx>) { - // FIXME: Nashenas88 - span should be narrowed down - *substs = self.renumber_regions(substs, self.source.span); + substs: &mut ClosureSubsts<'tcx>, + location: Location) { + *substs = self.renumber_regions(substs, span_from_location(self.source, location)); } fn visit_statement(&mut self, @@ -107,11 +108,15 @@ impl MirPass for NLL { } tcx.infer_ctxt().enter(|infcx| { - let mut visitor = NLLVisitor::new(infcx, mir.clone()); // Clone mir so we can mutate it without disturbing the rest // of the compiler - let mut mir = mir.clone(); - visitor.visit_mir(&mut mir); + let mut renumbered_mir = mir.clone(); + + // Note that we're using the passed-in mir for the visitor. This is + // so we can lookup locations during traversal without worrying about + // maintaing both a mutable and immutable reference to the same object + let mut visitor = NLLVisitor::new(infcx, &mir); + visitor.visit_mir(&mut renumbered_mir); }) } } \ No newline at end of file From 7193c68271f62bc311e57ea5126e795babf02f1e Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Thu, 3 Aug 2017 00:16:36 -0400 Subject: [PATCH 05/38] Store map of region variable ids to lookups in nll visitor and remove reference to mir --- src/librustc/mir/visit.rs | 1 + src/librustc_mir/transform/nll.rs | 71 ++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index fd3a9f8cd2d9..2b3bb098a802 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -741,6 +741,7 @@ macro_rules! make_mir_visitor { make_mir_visitor!(Visitor,); make_mir_visitor!(MutVisitor,mut); +#[derive(Copy, Clone, Debug)] pub enum Lookup { Loc(Location), Src(SourceInfo), diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll.rs index 0793bdabf0ba..9699495eb0ef 100644 --- a/src/librustc_mir/transform/nll.rs +++ b/src/librustc_mir/transform/nll.rs @@ -9,58 +9,78 @@ // except according to those terms. use rustc::ty::TypeFoldable; -use rustc::ty::subst::Substs; -use rustc::ty::{Ty, TyCtxt, ClosureSubsts}; +use rustc::ty::subst::{Kind, Substs}; +use rustc::ty::{Ty, TyCtxt, ClosureSubsts, RegionVid, RegionKind}; use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind}; use rustc::mir::visit::{MutVisitor, Lookup}; use rustc::mir::transform::{MirPass, MirSource}; use rustc::infer::{self, InferCtxt}; -use syntax_pos::Span; +use syntax_pos::DUMMY_SP; +use std::collections::HashMap; #[allow(dead_code)] struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + pub lookup_map: HashMap, infcx: InferCtxt<'a, 'gcx, 'tcx>, - source: &'a Mir<'tcx> } impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { - pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: &'a Mir<'tcx>) -> Self { + pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self { NLLVisitor { infcx: infcx, - source: source, + lookup_map: HashMap::new(), } } - fn renumber_regions(&self, value: &T, span: Span) -> T where T: TypeFoldable<'tcx> { + fn renumber_regions(&self, value: &T) -> T where T: TypeFoldable<'tcx> { self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { - self.infcx.next_region_var(infer::MiscVariable(span)) + self.infcx.next_region_var(infer::MiscVariable(DUMMY_SP)) }) } -} -fn span_from_location<'tcx>(source: &Mir<'tcx>, location: Location) -> Span { - source[location.block].statements[location.statement_index].source_info.span + fn store_region(&mut self, region: &RegionKind, lookup: Lookup) { + if let RegionKind::ReVar(rid) = *region { + self.lookup_map.entry(rid).or_insert(lookup); + } + } + + fn store_ty_regions(&mut self, ty: &Ty<'tcx>, lookup: Lookup) { + for region in ty.regions() { + self.store_region(region, lookup); + } + } + + fn store_kind_regions(&mut self, kind: &'tcx Kind, lookup: Lookup) { + if let Some(ty) = kind.as_type() { + self.store_ty_regions(&ty, lookup); + } else if let Some(region) = kind.as_region() { + self.store_region(region, lookup); + } + } } impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { fn visit_ty(&mut self, ty: &mut Ty<'tcx>, lookup: Lookup) { let old_ty = *ty; - let span = match lookup { - Lookup::Loc(location) => span_from_location(self.source, location), - Lookup::Src(source_info) => source_info.span, - }; - *ty = self.renumber_regions(&old_ty, span); + *ty = self.renumber_regions(&old_ty); + self.store_ty_regions(ty, lookup); } fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) { - *substs = self.renumber_regions(&{*substs}, span_from_location(self.source, location)); + *substs = self.renumber_regions(&{*substs}); + let lookup = Lookup::Loc(location); + for kind in *substs { + self.store_kind_regions(kind, lookup); + } } fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { match *rvalue { Rvalue::Ref(ref mut r, _, _) => { let old_r = *r; - *r = self.renumber_regions(&old_r, span_from_location(self.source, location)); + *r = self.renumber_regions(&old_r); + let lookup = Lookup::Loc(location); + self.store_region(r, lookup); } Rvalue::Use(..) | Rvalue::Repeat(..) | @@ -81,7 +101,11 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: Location) { - *substs = self.renumber_regions(substs, span_from_location(self.source, location)); + *substs = self.renumber_regions(substs); + let lookup = Lookup::Loc(location); + for kind in substs.substs { + self.store_kind_regions(kind, lookup); + } } fn visit_statement(&mut self, @@ -108,14 +132,9 @@ impl MirPass for NLL { } tcx.infer_ctxt().enter(|infcx| { - // Clone mir so we can mutate it without disturbing the rest - // of the compiler + // Clone mir so we can mutate it without disturbing the rest of the compiler let mut renumbered_mir = mir.clone(); - - // Note that we're using the passed-in mir for the visitor. This is - // so we can lookup locations during traversal without worrying about - // maintaing both a mutable and immutable reference to the same object - let mut visitor = NLLVisitor::new(infcx, &mir); + let mut visitor = NLLVisitor::new(infcx); visitor.visit_mir(&mut renumbered_mir); }) } From 5b30cc178a5f890a9b5b1930a7062e8b05544f49 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Thu, 3 Aug 2017 21:13:27 +0200 Subject: [PATCH 06/38] Detect relative urls in tidy check --- src/tools/tidy/src/style.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index b42beb37821c..d0483e64b403 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -79,11 +79,11 @@ fn line_is_url(line: &str) -> bool { => state = EXP_URL, (EXP_LINK_LABEL_OR_URL, w) - if w.starts_with("http://") || w.starts_with("https://") + if w.starts_with("http://") || w.starts_with("https://") || w.starts_with("../") => state = EXP_END, (EXP_URL, w) - if w.starts_with("http://") || w.starts_with("https://") + if w.starts_with("http://") || w.starts_with("https://") || w.starts_with("../") => state = EXP_END, (_, _) => return false, From 0f924b86c496bf4224fc5f84b7ce40c93bb2c7a9 Mon Sep 17 00:00:00 2001 From: arshiamufti Date: Fri, 4 Aug 2017 00:53:09 -0700 Subject: [PATCH 07/38] add test --- src/test/run-pass/weird-exprs.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index 20f58301d452..64fd9e0a7721 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -107,6 +107,10 @@ fn fishy() { String::<>::from::<>("><>").chars::<>().rev::<>().collect::()); } +fn union() { + union union<'union> { union: &'union union<'union>, } +} + pub fn main() { strange(); funny(); @@ -119,4 +123,5 @@ pub fn main() { dots(); you_eight(); fishy(); + union(); } From 608863d81770c804f6e527ec16b2cc843ee0c050 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Fri, 4 Aug 2017 13:24:00 +0200 Subject: [PATCH 08/38] Only allow long relative urls after a link label Yellow is indeed a nice color for a bikeshed. --- src/tools/tidy/src/style.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index d0483e64b403..a689d8a8be41 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -79,7 +79,7 @@ fn line_is_url(line: &str) -> bool { => state = EXP_URL, (EXP_LINK_LABEL_OR_URL, w) - if w.starts_with("http://") || w.starts_with("https://") || w.starts_with("../") + if w.starts_with("http://") || w.starts_with("https://") => state = EXP_END, (EXP_URL, w) From 0d29cd4c80a9cc042d34ea31d70ff42830df0001 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Fri, 4 Aug 2017 09:06:55 -0400 Subject: [PATCH 09/38] Keep map hidden and instead move it out after visitor is finished --- src/librustc_mir/transform/nll.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll.rs index 9699495eb0ef..fb4764c49626 100644 --- a/src/librustc_mir/transform/nll.rs +++ b/src/librustc_mir/transform/nll.rs @@ -20,7 +20,7 @@ use std::collections::HashMap; #[allow(dead_code)] struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { - pub lookup_map: HashMap, + lookup_map: HashMap, infcx: InferCtxt<'a, 'gcx, 'tcx>, } @@ -32,6 +32,10 @@ impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { } } + pub fn into_results(self) -> HashMap { + self.lookup_map + } + fn renumber_regions(&self, value: &T) -> T where T: TypeFoldable<'tcx> { self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { self.infcx.next_region_var(infer::MiscVariable(DUMMY_SP)) @@ -136,6 +140,7 @@ impl MirPass for NLL { let mut renumbered_mir = mir.clone(); let mut visitor = NLLVisitor::new(infcx); visitor.visit_mir(&mut renumbered_mir); + let _results = visitor.into_results(); }) } } \ No newline at end of file From b298a58c782f1434b09d4aaea6bffd4f99d3e7f6 Mon Sep 17 00:00:00 2001 From: Natalie Boehm Date: Fri, 4 Aug 2017 12:25:05 -0400 Subject: [PATCH 10/38] Update String Deref to explain why using &String does not always work --- src/liballoc/string.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 622cc68964bf..110699c1e03b 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -144,7 +144,7 @@ use boxed::Box; /// # Deref /// /// `String`s implement [`Deref`]``, and so inherit all of [`str`]'s -/// methods. In addition, this means that you can pass a `String` to any +/// methods. In addition, this means that you can pass a `String` to a /// function which takes a [`&str`] by using an ampersand (`&`): /// /// ``` @@ -160,8 +160,31 @@ use boxed::Box; /// /// This will create a [`&str`] from the `String` and pass it in. This /// conversion is very inexpensive, and so generally, functions will accept -/// [`&str`]s as arguments unless they need a `String` for some specific reason. +/// [`&str`]s as arguments unless they need a `String` for some specific +/// reason. /// +/// In certain cases Rust doesn't have enough information to make this conversion, +/// known as deref coercion. For example, in this case a string slice implements +/// a trait and the function takes anything that implements the trait, Rust would +/// need to make two implicit conversions which Rust doesn't know how to do. The +/// following example will not compile for that reason. +/// +/// ```compile_fail,E0277 +/// trait TraitExample {} +/// +/// impl<'a> TraitExample for &'a str {} +/// +/// fn example_func(example_arg: A) {} +/// +/// fn main() { +/// let example_string = String::from("example_string"); +/// example_func(&example_string); +/// } +/// ``` +/// +/// What would work in this case is changing the line `example_func(&example_string);` +/// to `example_func(example_string.to_str());`. This works because we're doing the +/// conversion explicitly, rather than relying on the implicit conversion. /// /// # Representation /// From 94f7511ac242dbdc171be2acefa089e5a9b32562 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 4 Aug 2017 17:00:21 -0700 Subject: [PATCH 11/38] test MIR validation statements in closures --- src/test/mir-opt/validate_1.rs | 28 +++++++++++++++++++++++----- src/test/mir-opt/validate_4.rs | 25 ++++++++++++++++++++++++- src/test/mir-opt/validate_5.rs | 26 +++++++++++++++++++++----- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index 9ac76a5f4ea6..677c92ea71b7 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=1 +// compile-flags: -Z verbose -Z mir-emit-validate=1 -Z span_free_formats struct Test(i32); @@ -20,16 +20,13 @@ impl Test { fn main() { let mut x = 0; - Test(0).foo(&mut x); + Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor // Also test closures let c = |x: &mut i32| { let y = &*x; *y }; c(&mut x); } -// FIXME: Also test code generated inside the closure, make sure it has validation. Unfortunately, -// the interesting lines of code also contain name of the source file, so we cannot test for it. - // END RUST SOURCE // START rustc.node12.EraseRegions.after.mir // bb0: { @@ -57,3 +54,24 @@ fn main() { // } // } // END rustc.node23.EraseRegions.after.mir +// START rustc.node50.EraseRegions.after.mir +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 { +// bb0: { +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_1/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_1/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// StorageLive(_3); +// _3 = _2; +// StorageLive(_4); +// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: NodeId(41), first_statement_index: 0 }))), [(*_3): i32]); +// _4 = &ReErased (*_3); +// Validate(Acquire, [(*_4): i32/ReScope(Remainder(BlockRemainder { block: NodeId(41), first_statement_index: 0 })) (imm)]); +// StorageLive(_5); +// _5 = (*_4); +// _0 = _5; +// StorageDead(_5); +// StorageDead(_4); +// EndRegion(ReScope(Remainder(BlockRemainder { block: NodeId(41), first_statement_index: 0 }))); +// StorageDead(_3); +// return; +// } +// } +// END rustc.node50.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs index 591de975740f..2ee459d6809c 100644 --- a/src/test/mir-opt/validate_4.rs +++ b/src/test/mir-opt/validate_4.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=1 +// compile-flags: -Z verbose -Z mir-emit-validate=1 -Z span_free_formats // Make sure unsafe fns and fns with an unsafe block only get restricted validation. @@ -45,6 +45,19 @@ fn main() { // } // } // END rustc.node4.EraseRegions.after.mir +// START rustc.node22.EraseRegions.after.mir +// fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () { +// bb0: { +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483659) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]); +// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483659) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]); +// StorageLive(_3); +// _3 = _2; +// (*_3) = const 23i32; +// StorageDead(_3); +// return; +// } +// } +// END rustc.node22.EraseRegions.after.mir // START rustc.node31.EraseRegions.after.mir // fn test(_1: &ReErased mut i32) -> () { // bb0: { @@ -58,3 +71,13 @@ fn main() { // } // } // END rustc.node31.EraseRegions.after.mir +// START rustc.node60.EraseRegions.after.mir +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool { +// bb0: { +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483663) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// StorageLive(_3); +// _0 = const write_42(_4) -> bb1; +// } +// } +// END rustc.node60.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index e9919af9fd3a..150aa2baf2d3 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=2 +// compile-flags: -Z verbose -Z mir-emit-validate=2 -Z span_free_formats -// Make sure unsafe fns and fns with an unsafe block only get full validation. +// Make sure unsafe fns and fns with an unsafe block still get full validation. unsafe fn write_42(x: *mut i32) -> bool { *x = 42; @@ -29,9 +29,6 @@ fn main() { test_closure(&mut 0); } -// FIXME: Also test code generated inside the closure, make sure it has validation. Unfortunately, -// the interesting lines of code also contain name of the source file, so we cannot test for it. - // END RUST SOURCE // START rustc.node17.EraseRegions.after.mir // fn test(_1: &ReErased mut i32) -> () { @@ -42,3 +39,22 @@ fn main() { // } // } // END rustc.node17.EraseRegions.after.mir +// START rustc.node46.EraseRegions.after.mir +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool { +// bb0: { +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483660) => validate_5/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(2147483660) => validate_5/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// StorageLive(_3); +// _3 = _2; +// StorageLive(_4); +// StorageLive(_5); +// Validate(Suspend(ReScope(Misc(NodeId(44)))), [(*_3): i32]); +// _5 = &ReErased mut (*_3); +// Validate(Acquire, [(*_5): i32/ReScope(Misc(NodeId(44)))]); +// _4 = _5 as *mut i32 (Misc); +// StorageDead(_5); +// EndRegion(ReScope(Misc(NodeId(44)))); +// Validate(Release, [_0: bool, _4: *mut i32]); +// _0 = const write_42(_4) -> bb1; +// } +// } +// END rustc.node46.EraseRegions.after.mir From 970c78094f4c9e7182c110027d90bd630191cd23 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 7 Aug 2017 10:22:28 +0200 Subject: [PATCH 12/38] Reexport all SyntaxExtension variants --- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7eeafa72c682..194d30e25d41 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::SyntaxExtension::{MultiDecorator, MultiModifier, NormalTT, IdentTT}; +pub use self::SyntaxExtension::*; use ast::{self, Attribute, Name, PatKind, MetaItem}; use attr::HasAttrs; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 16c264e0f941..4843a66a750f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -294,7 +294,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item = match self.cx.resolver.resolve_macro( Mark::root(), path, MacroKind::Derive, false) { Ok(ext) => match *ext { - SyntaxExtension::BuiltinDerive(..) => item_with_markers.clone(), + BuiltinDerive(..) => item_with_markers.clone(), _ => item.clone(), }, _ => item.clone(), @@ -427,7 +427,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { items.push(item); kind.expect_from_annotatables(items) } - SyntaxExtension::AttrProcMacro(ref mac) => { + AttrProcMacro(ref mac) => { let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item { Annotatable::Item(item) => token::NtItem(item), Annotatable::TraitItem(item) => token::NtTraitItem(item.unwrap()), @@ -436,7 +436,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let tok_result = mac.expand(self.cx, attr.span, attr.tokens, item_tok); self.parse_expansion(tok_result, kind, &attr.path, attr.span) } - SyntaxExtension::ProcMacroDerive(..) | SyntaxExtension::BuiltinDerive(..) => { + ProcMacroDerive(..) | BuiltinDerive(..) => { self.cx.span_err(attr.span, &format!("`{}` is a derive mode", attr.path)); kind.dummy(attr.span) } @@ -474,7 +474,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - SyntaxExtension::DeclMacro(ref expand, def_span) => { + DeclMacro(ref expand, def_span) => { if let Err(msg) = validate_and_set_expn_info(def_span.map(|(_, s)| s), false) { self.cx.span_err(path.span, &msg); @@ -512,18 +512,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> { kind.make_from(expander.expand(self.cx, span, ident, input)) } - MultiDecorator(..) | MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => { + MultiDecorator(..) | MultiModifier(..) | AttrProcMacro(..) => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); return kind.dummy(span); } - SyntaxExtension::ProcMacroDerive(..) | SyntaxExtension::BuiltinDerive(..) => { + ProcMacroDerive(..) | BuiltinDerive(..) => { self.cx.span_err(path.span, &format!("`{}` is a derive mode", path)); return kind.dummy(span); } - SyntaxExtension::ProcMacro(ref expandfun) => { + ProcMacro(ref expandfun) => { if ident.name != keywords::Invalid.name() { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -582,7 +582,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; match *ext { - SyntaxExtension::ProcMacroDerive(ref ext, _) => { + ProcMacroDerive(ref ext, _) => { invoc.expansion_data.mark.set_expn_info(expn_info); let span = Span { ctxt: self.cx.backtrace(), ..span }; let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this @@ -592,7 +592,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; kind.expect_from_annotatables(ext.expand(self.cx, span, &dummy, item)) } - SyntaxExtension::BuiltinDerive(func) => { + BuiltinDerive(func) => { expn_info.callee.allow_internal_unstable = true; invoc.expansion_data.mark.set_expn_info(expn_info); let span = Span { ctxt: self.cx.backtrace(), ..span }; From 49310a9d4dfea8b5b23e9a69c2d78c0dfa6d2851 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 7 Aug 2017 16:30:56 +0100 Subject: [PATCH 13/38] Stop using URL shortener in docs tidy will no longer complain about long lines containing links so there is no reason to use a URL shortener here. --- src/libstd/net/ip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 1e5368896af9..0abf8179cc97 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -466,7 +466,7 @@ impl Ipv4Addr { /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24) /// - the unspecified address (0.0.0.0) /// - /// [ipv4-sr]: http://goo.gl/RaZ7lg + /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml /// [`true`]: ../../std/primitive.bool.html /// /// # Examples From 2a62b91343b4de94b6cfe401e8ad9bc0414f245f Mon Sep 17 00:00:00 2001 From: Natalie Boehm Date: Mon, 7 Aug 2017 13:56:20 -0400 Subject: [PATCH 14/38] Update explanation of deref coercion --- src/liballoc/string.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 110699c1e03b..89f3ddcd18a7 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -163,11 +163,12 @@ use boxed::Box; /// [`&str`]s as arguments unless they need a `String` for some specific /// reason. /// -/// In certain cases Rust doesn't have enough information to make this conversion, -/// known as deref coercion. For example, in this case a string slice implements -/// a trait and the function takes anything that implements the trait, Rust would -/// need to make two implicit conversions which Rust doesn't know how to do. The -/// following example will not compile for that reason. +/// In certain cases Rust doesn't have enough information to make this +/// conversion, known as deref coercion. In the following example a string +/// slice `&'a str` implements the trait `TraitExample`, and the function +/// `example_func` takes anything that implements the trait. In this case Rust +/// would need to make two implicit conversions, which Rust doesn't have the +/// means to do. For that reason, the following example will not compile. /// /// ```compile_fail,E0277 /// trait TraitExample {} @@ -182,9 +183,10 @@ use boxed::Box; /// } /// ``` /// -/// What would work in this case is changing the line `example_func(&example_string);` -/// to `example_func(example_string.to_str());`. This works because we're doing the -/// conversion explicitly, rather than relying on the implicit conversion. +/// What would work in this case is changing the line +/// `example_func(&example_string);` to +/// `example_func(example_string.to_str());`. This works because we're doing +/// the conversion explicitly, rather than relying on the implicit conversion. /// /// # Representation /// From 458ba7aeb5c1ad3e18dd5c0fe261e1004dbb7a42 Mon Sep 17 00:00:00 2001 From: Aidan Hobson Sayers Date: Tue, 1 Aug 2017 15:37:10 +0100 Subject: [PATCH 15/38] Make a disable-jemalloc build work Fixes #43510 --- src/libstd/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bd9c9c747848..8850a8a5582d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -318,6 +318,16 @@ #![default_lib_allocator] +// Always use alloc_system during stage0 since we don't know if the alloc_* +// crate the stage0 compiler will pick by default is available (most +// obviously, if the user has disabled jemalloc in `./configure`). +// `force_alloc_system` is *only* intended as a workaround for local rebuilds +// with a rustc without jemalloc. +#![cfg_attr(any(stage0, feature = "force_alloc_system"), feature(global_allocator))] +#[cfg(any(stage0, feature = "force_alloc_system"))] +#[global_allocator] +static ALLOC: alloc_system::System = alloc_system::System; + // Explicitly import the prelude. The compiler uses this same unstable attribute // to import the prelude implicitly when building crates that depend on std. #[prelude_import] From 43760a4f9b901ba16239909f32542e685a2b9279 Mon Sep 17 00:00:00 2001 From: Inokentiy Babushkin Date: Tue, 8 Aug 2017 15:12:39 +0200 Subject: [PATCH 16/38] Encode proper spans in crate metadata. The spans previously encoded only span the first token after the opening brace, up to the closing brace of inline `mod` declarations. Thus, when examining exports from an external crate, the spans don't include the header of inline `mod` declarations. --- src/librustc_metadata/encoder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index c35d8407c9d3..8a753a0ae4b5 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -563,7 +563,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { Entry { kind: EntryKind::Mod(self.lazy(&data)), visibility: self.lazy(&ty::Visibility::from_hir(vis, id, tcx)), - span: self.lazy(&md.inner), + span: self.lazy(&tcx.def_span(def_id)), attributes: self.encode_attributes(attrs), children: self.lazy_seq(md.item_ids.iter().map(|item_id| { tcx.hir.local_def_id(item_id.id).index From 6c0f2aa279113810cfc1076cf3cf09b1e140bb12 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Tue, 8 Aug 2017 10:08:08 -0400 Subject: [PATCH 17/38] fix assertion - trait object pointers don't have infinite fields --- src/librustc/ty/layout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index e770f1d55dcf..4ee9b2e65a78 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2197,8 +2197,8 @@ impl<'a, 'tcx> TyLayout<'tcx> { let tcx = cx.tcx(); let ptr_field_type = |pointee: Ty<'tcx>| { + assert!(i < 2); let slice = |element: Ty<'tcx>| { - assert!(i < 2); if i == 0 { tcx.mk_mut_ptr(element) } else { From d07dd4ab444bb14746c3cc80186c979e5c51c3a1 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 8 Aug 2017 17:56:28 +0200 Subject: [PATCH 18/38] Implement HashStable for Xyz<'gcx> instead of Xyz<'lcx>. --- src/librustc/ich/impls_mir.rs | 24 ++++++++++++------------ src/librustc/ich/impls_ty.rs | 32 +++++++++++++++++++------------- src/librustc/macros.rs | 16 ++++++++-------- src/librustc/ty/mod.rs | 2 +- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index c20864183f47..faf579186e5f 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -33,7 +33,7 @@ impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref }); impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup }); impl<'a, 'gcx, 'tcx> HashStable> -for mir::Terminator<'tcx> { +for mir::Terminator<'gcx> { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, @@ -125,7 +125,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for mir::P } impl<'a, 'gcx, 'tcx> HashStable> -for mir::TerminatorKind<'tcx> { +for mir::TerminatorKind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -186,7 +186,7 @@ for mir::TerminatorKind<'tcx> { } impl<'a, 'gcx, 'tcx> HashStable> -for mir::AssertMessage<'tcx> { +for mir::AssertMessage<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -207,7 +207,7 @@ for mir::AssertMessage<'tcx> { impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind }); impl<'a, 'gcx, 'tcx> HashStable> -for mir::StatementKind<'tcx> { +for mir::StatementKind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -244,7 +244,7 @@ for mir::StatementKind<'tcx> { } impl<'a, 'gcx, 'tcx, T> HashStable> - for mir::ValidationOperand<'tcx, T> + for mir::ValidationOperand<'gcx, T> where T: HashStable> { fn hash_stable(&self, @@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx, T> HashStable> impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) }); -impl<'a, 'gcx, 'tcx> HashStable> for mir::Lvalue<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for mir::Lvalue<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for mir::L } impl<'a, 'gcx, 'tcx, B, V, T> HashStable> -for mir::Projection<'tcx, B, V, T> +for mir::Projection<'gcx, B, V, T> where B: HashStable>, V: HashStable>, T: HashStable> @@ -299,7 +299,7 @@ for mir::Projection<'tcx, B, V, T> } impl<'a, 'gcx, 'tcx, V, T> HashStable> -for mir::ProjectionElem<'tcx, V, T> +for mir::ProjectionElem<'gcx, V, T> where V: HashStable>, T: HashStable> { @@ -335,7 +335,7 @@ for mir::ProjectionElem<'tcx, V, T> impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope }); -impl<'a, 'gcx, 'tcx> HashStable> for mir::Operand<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for mir::Operand<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for mir::O } } -impl<'a, 'gcx, 'tcx> HashStable> for mir::Rvalue<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for mir::Rvalue<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -413,7 +413,7 @@ impl_stable_hash_for!(enum mir::CastKind { }); impl<'a, 'gcx, 'tcx> HashStable> -for mir::AggregateKind<'tcx> { +for mir::AggregateKind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -469,7 +469,7 @@ impl_stable_hash_for!(enum mir::NullOp { impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal }); -impl<'a, 'gcx, 'tcx> HashStable> for mir::Literal<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for mir::Literal<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 5269ec90def5..ec3f3c113e83 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -20,7 +20,7 @@ use syntax_pos::symbol::InternedString; use ty; impl<'a, 'gcx, 'tcx, T> HashStable> -for &'tcx ty::Slice +for &'gcx ty::Slice where T: HashStable> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, @@ -30,7 +30,7 @@ for &'tcx ty::Slice } impl<'a, 'gcx, 'tcx> HashStable> -for ty::subst::Kind<'tcx> { +for ty::subst::Kind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -55,6 +55,11 @@ for ty::RegionKind { db.depth.hash_stable(hcx, hasher); i.hash_stable(hcx, hasher); } + ty::ReLateBound(db, ty::BrNamed(def_id, name)) => { + db.depth.hash_stable(hcx, hasher); + def_id.hash_stable(hcx, hasher); + name.hash_stable(hcx, hasher); + } ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => { def_id.hash_stable(hcx, hasher); index.hash_stable(hcx, hasher); @@ -76,7 +81,7 @@ for ty::RegionKind { } impl<'a, 'gcx, 'tcx> HashStable> -for ty::adjustment::AutoBorrow<'tcx> { +for ty::adjustment::AutoBorrow<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -94,7 +99,7 @@ for ty::adjustment::AutoBorrow<'tcx> { } impl<'a, 'gcx, 'tcx> HashStable> -for ty::adjustment::Adjust<'tcx> { +for ty::adjustment::Adjust<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -128,7 +133,7 @@ impl_stable_hash_for!(enum ty::BorrowKind { }); impl<'a, 'gcx, 'tcx> HashStable> -for ty::UpvarCapture<'tcx> { +for ty::UpvarCapture<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -150,12 +155,13 @@ impl_stable_hash_for!(struct ty::FnSig<'tcx> { }); impl<'a, 'gcx, 'tcx, T> HashStable> for ty::Binder - where T: HashStable> + ty::fold::TypeFoldable<'tcx> + where T: HashStable> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { - hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher); + let ty::Binder(ref inner) = *self; + inner.hash_stable(hcx, hasher); } } @@ -190,7 +196,7 @@ impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty } impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id }); -impl<'a, 'gcx, 'tcx> HashStable> for ty::Predicate<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for ty::Predicate<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -256,7 +262,7 @@ impl_stable_hash_for!(struct ty::FieldDef { }); impl<'a, 'gcx, 'tcx> HashStable> -for ::middle::const_val::ConstVal<'tcx> { +for ::middle::const_val::ConstVal<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -483,7 +489,7 @@ impl_stable_hash_for!(enum ty::BoundRegion { }); impl<'a, 'gcx, 'tcx> HashStable> -for ty::TypeVariants<'tcx> +for ty::TypeVariants<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, @@ -574,7 +580,7 @@ impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> { }); impl<'a, 'gcx, 'tcx> HashStable> -for ty::ExistentialPredicate<'tcx> +for ty::ExistentialPredicate<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, @@ -607,7 +613,7 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> { impl<'a, 'gcx, 'tcx> HashStable> -for ty::TypeckTables<'tcx> { +for ty::TypeckTables<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { @@ -689,7 +695,7 @@ impl_stable_hash_for!(struct ty::Instance<'tcx> { substs }); -impl<'a, 'gcx, 'tcx> HashStable> for ty::InstanceDef<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for ty::InstanceDef<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index f814f941b06f..f3d66b49de5a 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -73,10 +73,10 @@ macro_rules! __impl_stable_hash_field { #[macro_export] macro_rules! impl_stable_hash_for { (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => { - impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $enum_name { + impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $enum_name { #[inline] fn hash_stable(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>, + __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { use $enum_name::*; ::std::mem::discriminant(self).hash_stable(__ctx, __hasher); @@ -92,10 +92,10 @@ macro_rules! impl_stable_hash_for { } }; (struct $struct_name:path { $($field:ident),* }) => { - impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $struct_name { + impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name { #[inline] fn hash_stable(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>, + __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { let $struct_name { $(ref $field),* @@ -106,10 +106,10 @@ macro_rules! impl_stable_hash_for { } }; (tuple_struct $struct_name:path { $($field:ident),* }) => { - impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $struct_name { + impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name { #[inline] fn hash_stable(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>, + __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { let $struct_name ( $(ref $field),* @@ -125,11 +125,11 @@ macro_rules! impl_stable_hash_for { macro_rules! impl_stable_hash_for_spanned { ($T:path) => ( - impl<'a, 'gcx, 'tcx> HashStable> for ::syntax::codemap::Spanned<$T> + impl<'a, 'tcx, 'lcx> HashStable> for ::syntax::codemap::Spanned<$T> { #[inline] fn hash_stable(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'a, 'tcx, 'lcx>, hasher: &mut StableHasher) { self.node.hash_stable(hcx, hasher); self.span.hash_stable(hcx, hasher); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index eef0bcc37535..93687d6299a9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -497,7 +497,7 @@ impl<'tcx> TyS<'tcx> { } } -impl<'a, 'gcx, 'tcx> HashStable> for ty::TyS<'tcx> { +impl<'a, 'gcx, 'tcx> HashStable> for ty::TyS<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { From 3cb23a714f2b7adbf1eee697fb6471c4dd733f04 Mon Sep 17 00:00:00 2001 From: kennytm Date: Tue, 8 Aug 2017 23:28:09 +0800 Subject: [PATCH 19/38] Type-check `break value;` even outside of `loop {}`. Fix #43162, fix #43727. --- src/librustc_typeck/check/mod.rs | 31 +++++++++++++++++++++++++++ src/test/compile-fail/issue-43162.rs | 17 +++++++++++++++ src/test/run-pass/loop-break-value.rs | 6 ++++++ 3 files changed, 54 insertions(+) create mode 100644 src/test/compile-fail/issue-43162.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e53e5e7b08c9..f146742f5aef 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3652,6 +3652,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // inside a loop at all, which is caught by the // loop-checking pass. assert!(self.tcx.sess.err_count() > 0); + + // We still need to assign a type to the inner expression to + // prevent the ICE in #43162. + if let Some(ref e) = *expr_opt { + self.check_expr_with_hint(e, tcx.types.err); + + // ... except when we try to 'break rust;'. + // ICE this expression in particular (see #43162). + if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node { + if path.segments.len() == 1 && path.segments[0].name == "rust" { + fatally_break_rust(self.tcx.sess); + } + } + } } // the type of a `break` is always `!`, since it diverges @@ -4857,3 +4871,20 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } } + +fn fatally_break_rust(sess: &Session) { + let handler = sess.diagnostic(); + handler.span_bug_no_panic( + MultiSpan::new(), + "It looks like you're trying to break rust; would you like some ICE?", + ); + handler.note_without_error("the compiler expectedly panicked. this is a feature."); + handler.note_without_error( + "we would appreciate a joke overview: \ + https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675" + ); + handler.note_without_error(&format!("rustc {} running on {}", + option_env!("CFG_VERSION").unwrap_or("unknown_version"), + ::session::config::host_triple(), + )); +} diff --git a/src/test/compile-fail/issue-43162.rs b/src/test/compile-fail/issue-43162.rs new file mode 100644 index 000000000000..8f4661299e9d --- /dev/null +++ b/src/test/compile-fail/issue-43162.rs @@ -0,0 +1,17 @@ +// 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. + +fn foo() -> bool { + break true; //~ ERROR E0268 +} + +fn main() { + break {}; //~ ERROR E0268 +} diff --git a/src/test/run-pass/loop-break-value.rs b/src/test/run-pass/loop-break-value.rs index 1d5c83bc20d9..39053769b24b 100644 --- a/src/test/run-pass/loop-break-value.rs +++ b/src/test/run-pass/loop-break-value.rs @@ -137,4 +137,10 @@ pub fn main() { panic!("from outer"); }; assert_eq!(break_from_while_to_outer, 567); + + let rust = true; + let value = loop { + break rust; + }; + assert!(value); } From cf7f3055e5e2eacffde33fbc06ec0187ff828b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malo=20Jaffr=C3=A9?= Date: Tue, 8 Aug 2017 16:53:49 +0200 Subject: [PATCH 20/38] Ignore tests that fail on stage1 That makes ./x.py test --stage 1 work on x86_64-unknown-linux-gnu. --- .../proc-macro/attribute-with-error.rs | 1 + .../proc-macro/attributes-included.rs | 1 + src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs | 1 + .../proc-macro/expand-to-unstable-2.rs | 1 + .../compile-fail-fulldeps/proc-macro/expand-to-unstable.rs | 1 + src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs | 1 + src/test/compile-fail-fulldeps/proc-macro/item-error.rs | 1 + .../proc-macro/lints_in_proc_macros.rs | 1 + .../proc-macro/proc-macro-attributes.rs | 1 + src/test/run-make/issue-37839/Makefile | 6 ++++++ src/test/run-make/issue-37893/Makefile | 6 ++++++ src/test/run-make/issue-38237/Makefile | 6 ++++++ src/test/run-make/llvm-pass/Makefile | 7 +++++++ src/test/run-make/rustc-macro-dep-files/Makefile | 6 ++++++ src/test/run-pass-fulldeps/issue-40663.rs | 1 + src/test/run-pass-fulldeps/proc-macro/add-impl.rs | 1 + src/test/run-pass-fulldeps/proc-macro/append-impl.rs | 1 + src/test/run-pass-fulldeps/proc-macro/attr-args.rs | 1 + src/test/run-pass-fulldeps/proc-macro/bang-macro.rs | 1 + .../run-pass-fulldeps/proc-macro/count_compound_ops.rs | 1 + src/test/run-pass-fulldeps/proc-macro/crate-var.rs | 1 + .../run-pass-fulldeps/proc-macro/derive-same-struct.rs | 1 + src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs | 1 + src/test/run-pass-fulldeps/proc-macro/issue-39889.rs | 1 + src/test/run-pass-fulldeps/proc-macro/issue-40001.rs | 1 + src/test/run-pass-fulldeps/proc-macro/load-two.rs | 1 + src/test/run-pass-fulldeps/proc-macro/use-reexport.rs | 1 + 27 files changed, 53 insertions(+) diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs index 65f4b6350c4e..00a27818327f 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:attribute-with-error.rs +// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs b/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs index 508f8dac5711..0cb4135d953f 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:attributes-included.rs +// ignore-stage1 #![feature(proc_macro, rustc_attrs)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs index 42fad803bfa6..b03409c9c285 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-bad.rs +// ignore-stage1 #[macro_use] extern crate derive_bad; diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs index e4fcbb117a50..6f254dcbdb11 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-unstable-2.rs +// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs index 836e336fc22f..ca0f0e382ed0 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-unstable.rs +// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs index 42475e6de90c..1d645a7ec510 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:issue_38586.rs +// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs index 4133e75e3a62..c0d4d71a6ec8 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-b.rs +// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs index 93dead1a1568..b1fb7d42d868 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:bang_proc_macro2.rs +// ignore-stage1 #![feature(proc_macro)] #![allow(unused_macros)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs index df881bedec1b..153e4dd05717 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-b.rs +// ignore-stage1 #![allow(warnings)] diff --git a/src/test/run-make/issue-37839/Makefile b/src/test/run-make/issue-37839/Makefile index f17ce537fb81..8b3355b96226 100644 --- a/src/test/run-make/issue-37839/Makefile +++ b/src/test/run-make/issue-37839/Makefile @@ -1,6 +1,12 @@ -include ../tools.mk +ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1) +# ignore stage1 +all: + +else all: $(RUSTC) a.rs && $(RUSTC) b.rs $(BARE_RUSTC) c.rs -L dependency=$(TMPDIR) --extern b=$(TMPDIR)/libb.rlib \ --out-dir=$(TMPDIR) +endif diff --git a/src/test/run-make/issue-37893/Makefile b/src/test/run-make/issue-37893/Makefile index 27b69baf9778..c7732cc2682b 100644 --- a/src/test/run-make/issue-37893/Makefile +++ b/src/test/run-make/issue-37893/Makefile @@ -1,4 +1,10 @@ -include ../tools.mk +ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1) +# ignore stage1 +all: + +else all: $(RUSTC) a.rs && $(RUSTC) b.rs && $(RUSTC) c.rs +endif diff --git a/src/test/run-make/issue-38237/Makefile b/src/test/run-make/issue-38237/Makefile index 0a681401b1af..855d958b344a 100644 --- a/src/test/run-make/issue-38237/Makefile +++ b/src/test/run-make/issue-38237/Makefile @@ -1,5 +1,11 @@ -include ../tools.mk +ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1) +# ignore stage1 +all: + +else all: $(RUSTC) foo.rs; $(RUSTC) bar.rs $(RUSTDOC) baz.rs -L $(TMPDIR) -o $(TMPDIR) +endif diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make/llvm-pass/Makefile index aab6e895f226..0d31d2c82350 100644 --- a/src/test/run-make/llvm-pass/Makefile +++ b/src/test/run-make/llvm-pass/Makefile @@ -1,5 +1,10 @@ -include ../tools.mk +ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1) +# ignore stage1 +all: + +else # Windows doesn't correctly handle include statements with escaping paths, # so this test will not get run on Windows. ifdef IS_WINDOWS @@ -15,3 +20,5 @@ $(TMPDIR)/libllvm-function-pass.o: $(TMPDIR)/libllvm-module-pass.o: $(CXX) $(CFLAGS) $(LLVM_CXXFLAGS) -c llvm-module-pass.so.cc -o $(TMPDIR)/libllvm-module-pass.o endif + +endif diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make/rustc-macro-dep-files/Makefile index e3a6776c8080..1ab27397e314 100644 --- a/src/test/run-make/rustc-macro-dep-files/Makefile +++ b/src/test/run-make/rustc-macro-dep-files/Makefile @@ -1,6 +1,12 @@ -include ../tools.mk +ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1) +# ignore stage1 +all: + +else all: $(RUSTC) foo.rs $(RUSTC) bar.rs --emit dep-info grep "proc-macro source" $(TMPDIR)/bar.d && exit 1 || exit 0 +endif diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs index d030eab64e56..8cb9dc4a1b6e 100644 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ b/src/test/run-pass-fulldeps/issue-40663.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:custom_derive_plugin.rs +// ignore-stage1 #![feature(plugin, custom_derive)] #![plugin(custom_derive_plugin)] diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs index 7ea7ceafc287..5175fe174a9e 100644 --- a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:add-impl.rs +// ignore-stage1 #[macro_use] extern crate add_impl; diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs index 591f3331d28c..37aef7ef1318 100644 --- a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:append-impl.rs +// ignore-stage1 #![allow(warnings)] diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs b/src/test/run-pass-fulldeps/proc-macro/attr-args.rs index 8a9fdd753677..2968cc7871d7 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-args.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:attr-args.rs +// ignore-stage1 #![allow(warnings)] #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs index 531bd0dd3569..ffa4731f1e63 100644 --- a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:bang-macro.rs +// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs b/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs index 1a2b144e4717..00ad0e76ed01 100644 --- a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs +++ b/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:count_compound_ops.rs +// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs index ba1417ecb56e..b6acb0faab2a 100644 --- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs +++ b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:double.rs +// ignore-stage1 #![allow(unused)] diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs index ce3ba60b0ecf..ba5a639a759c 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-same-struct.rs +// ignore-stage1 #[macro_use] extern crate derive_same_struct; diff --git a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs b/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs index 51198db5aa76..4cac7d19b4de 100644 --- a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs +++ b/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs @@ -10,6 +10,7 @@ // aux-build:hygiene_example_codegen.rs // aux-build:hygiene_example.rs +// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs b/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs index 05610116ad6b..87130242c0f0 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:issue-39889.rs +// ignore-stage1 #![feature(proc_macro)] #![allow(unused)] diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-40001.rs b/src/test/run-pass-fulldeps/proc-macro/issue-40001.rs index 54e84b7f6189..b7826edd8b4e 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-40001.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-40001.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:issue-40001-plugin.rs +// ignore-stage1 #![feature(proc_macro, plugin)] #![plugin(issue_40001_plugin)] diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass-fulldeps/proc-macro/load-two.rs index d15a83a2cbe4..67c123778147 100644 --- a/src/test/run-pass-fulldeps/proc-macro/load-two.rs +++ b/src/test/run-pass-fulldeps/proc-macro/load-two.rs @@ -10,6 +10,7 @@ // aux-build:derive-atob.rs // aux-build:derive-ctod.rs +// ignore-stage1 #[macro_use] extern crate derive_atob; diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs index f0a1bfe65285..03dfeb1f5c9a 100644 --- a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs +++ b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs @@ -10,6 +10,7 @@ // aux-build:derive-a.rs // aux-build:derive-reexport.rs +// ignore-stage1 #[macro_use] extern crate derive_reexport; From 40f5b308bcf8024cd17b982d543695873bc9dd53 Mon Sep 17 00:00:00 2001 From: Natalie Boehm Date: Tue, 8 Aug 2017 14:57:34 -0400 Subject: [PATCH 21/38] Update solution to add using `&*` as well as `as_str()` --- src/liballoc/string.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 89f3ddcd18a7..a1f0b4f0de19 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -183,10 +183,15 @@ use boxed::Box; /// } /// ``` /// -/// What would work in this case is changing the line -/// `example_func(&example_string);` to -/// `example_func(example_string.to_str());`. This works because we're doing -/// the conversion explicitly, rather than relying on the implicit conversion. +/// There are two options that would work instead. The first would be to +/// change the line `example_func(&example_string);` to +/// `example_func(example_string.as_str());`, using the method `as_str()` +/// to explicitly extract the string slice containing the string. The second +/// way changes `example_func(&example_string);` to +/// `example_func(&*example_string);`. In this case we are dereferencing a +/// `String` to a `str`, then referencing the `str` back to `&str`. The +/// second way is more idiomatic, however both work to do the conversion +/// explicitly rather than relying on the implicit conversion. /// /// # Representation /// From 8ac43366929e2ea66abbf0fc8fe535ecfbea0262 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 8 Aug 2017 22:16:08 +0200 Subject: [PATCH 22/38] Improve headers linking --- src/librustdoc/html/render.rs | 44 +++++++++++++------------- src/librustdoc/html/static/rustdoc.css | 10 ++++++ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index fc0adef70baa..563c5618759b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2141,8 +2141,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, if !types.is_empty() { write!(w, " -

- Associated Types +

+ Associated Types

")?; @@ -2154,8 +2154,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, if !consts.is_empty() { write!(w, " -

- Associated Constants +

+ Associated Constants

")?; @@ -2168,8 +2168,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, // Output the documentation for each function individually if !required.is_empty() { write!(w, " -

- Required Methods +

+ Required Methods

")?; @@ -2180,8 +2180,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } if !provided.is_empty() { write!(w, " -

- Provided Methods +

+ Provided Methods

")?; @@ -2196,8 +2196,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let cache = cache(); write!(w, " -

- Implementors +

+ Implementors

    ")?; @@ -2436,8 +2436,8 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, }).peekable(); if let doctree::Plain = s.struct_type { if fields.peek().is_some() { - write!(w, "

    - Fields

    ")?; + write!(w, "

    + Fields

    ")?; for (field, ty) in fields { let id = derive_id(format!("{}.{}", ItemType::StructField, @@ -2485,8 +2485,8 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } }).peekable(); if fields.peek().is_some() { - write!(w, "

    - Fields

    ")?; + write!(w, "

    + Fields

    ")?; for (field, ty) in fields { write!(w, "{name}: {ty} ", @@ -2558,8 +2558,8 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, document(w, cx, it)?; if !e.variants.is_empty() { - write!(w, "

    - Variants

    \n")?; + write!(w, "

    + Variants

    \n")?; for variant in &e.variants { let id = derive_id(format!("{}.{}", ItemType::Variant, @@ -2831,16 +2831,16 @@ fn render_assoc_items(w: &mut fmt::Formatter, let render_mode = match what { AssocItemRender::All => { write!(w, " -

    - Methods +

    + Methods

    ")?; RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { write!(w, " -

    - Methods from {}<Target = {}> +

    + Methods from {}<Target = {}>

    ", trait_, type_)?; RenderMode::ForDeref { mut_: deref_mut_ } @@ -2865,8 +2865,8 @@ fn render_assoc_items(w: &mut fmt::Formatter, render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?; } write!(w, " -

    - Trait Implementations +

    + Trait Implementations

    ")?; for i in &traits { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 51465bafc42e..24c0ec04fa18 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -438,6 +438,16 @@ a { background: transparent; } +.small-section-header:hover > .anchor { + display: initial; +} +.anchor { + display: none; +} +.anchor:after { + content: '\2002\00a7\2002'; +} + .docblock a:hover, .docblock-short a:hover, .stability a { text-decoration: underline; } From fac6ce79e54a2d5bdbdc5157c645970a479e2fb1 Mon Sep 17 00:00:00 2001 From: Natalie Boehm Date: Tue, 8 Aug 2017 16:57:11 -0400 Subject: [PATCH 23/38] Fix trait name `Deref` --- src/liballoc/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index a1f0b4f0de19..322b137e99f0 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -164,7 +164,7 @@ use boxed::Box; /// reason. /// /// In certain cases Rust doesn't have enough information to make this -/// conversion, known as deref coercion. In the following example a string +/// conversion, known as `Deref` coercion. In the following example a string /// slice `&'a str` implements the trait `TraitExample`, and the function /// `example_func` takes anything that implements the trait. In this case Rust /// would need to make two implicit conversions, which Rust doesn't have the From 21a707ee97e8d274acf0359a3c3e33050245056e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 8 Aug 2017 14:50:27 -0700 Subject: [PATCH 24/38] explain that the example is indeed UB, but that's okay --- src/test/mir-opt/validate_5.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index 150aa2baf2d3..0182e6e29644 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -26,6 +26,9 @@ fn main() { test(&mut 0); let test_closure = unsafe { |x: &mut i32| write_42(x) }; + // Note that validation will fail if this is executed: The closure keeps the lock on + // x, so the write in write_42 fails. This test just checks code generation, + // so the UB doesn't matter. test_closure(&mut 0); } From 6dbd84640f7efa2e6d8a2bc13e9a30cbe5c3f96c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 8 Aug 2017 18:11:39 +0200 Subject: [PATCH 25/38] Erase/anonymize regions while computing TypeId hash. --- src/librustc/ty/util.rs | 5 +++++ src/test/run-pass/type-id-higher-rank.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index df4bbad3859f..ca95ff5722a1 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -214,6 +214,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { let mut hasher = StableHasher::new(); let mut hcx = StableHashingContext::new(self); + // We want the type_id be independent of the types free regions, so we + // erase them. The erase_regions() call will also anonymize bound + // regions, which is desirable too. + let ty = self.erase_regions(&ty); + hcx.while_hashing_spans(false, |hcx| { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { ty.hash_stable(hcx, &mut hasher); diff --git a/src/test/run-pass/type-id-higher-rank.rs b/src/test/run-pass/type-id-higher-rank.rs index 827b05c0801e..2865b5d04e5b 100644 --- a/src/test/run-pass/type-id-higher-rank.rs +++ b/src/test/run-pass/type-id-higher-rank.rs @@ -45,6 +45,11 @@ fn main() { assert!(g != h); assert!(g != i); assert!(h != i); + + // Make sure lifetime anonymization handles nesting correctly + let j = TypeId::of:: fn(&'a isize) -> &'a usize)>(); + let k = TypeId::of:: fn(&'b isize) -> &'b usize)>(); + assert_eq!(j, k); } // Boxed unboxed closures { From e5261c0bbf0362f1c36dddaa8da4d1dbbe23d905 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 9 Aug 2017 13:41:55 +0100 Subject: [PATCH 26/38] rustdoc: Fix broken CSS in search results The layout is currently broken for struct/union fields and enum variants in the search results when searching from a struct, union or enum page. --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 51465bafc42e..245c9fee59c7 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -695,7 +695,7 @@ span.since { margin-bottom: 25px; } -.enum .variant, .struct .structfield, .union .structfield { +#main > .variant, #main > .structfield { display: block; } From 718a8d1c3836170eaee78d337a40e14d5a0adee6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 9 Aug 2017 11:30:55 -0700 Subject: [PATCH 27/38] run AddCallGuards for *all* call edges before running AddValidation --- src/librustc_driver/driver.rs | 11 +-- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/add_call_guards.rs | 79 +++++++++++-------- 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 12cb556afdab..443bdf6a373a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -942,15 +942,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, // These next passes must be executed together passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads); - passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards); + passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges); passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops); passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads); + // AddValidation needs to run after ElaborateDrops and before EraseRegions, and it needs + // an AllCallEdges pass right before it. + passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AllCallEdges); + passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation); passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops")); // No lifetime analysis based on borrowing can be done from here on out. - // AddValidation needs to run after ElaborateDrops and before EraseRegions. - passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation); - // From here on out, regions are gone. passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions); @@ -960,7 +961,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator); passes.push_pass(MIR_OPTIMIZED, mir::transform::copy_prop::CopyPropagation); passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyLocals); - passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards); + passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges); passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans")); TyCtxt::create_and_enter(sess, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 11ad5d1509d2..62e762be93a7 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -105,7 +105,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, debug!("make_shim({:?}) = untransformed {:?}", instance, result); no_landing_pads::no_landing_pads(tcx, &mut result); simplify::simplify_cfg(&mut result); - add_call_guards::add_call_guards(&mut result); + add_call_guards::CriticalCallEdges.add_call_guards(&mut result); debug!("make_shim({:?}) = {:?}", instance, result); tcx.alloc_mir(result) diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index b7c7a1774dd3..23a9c4c57ca6 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -13,7 +13,12 @@ use rustc::mir::*; use rustc::mir::transform::{MirPass, MirSource}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -pub struct AddCallGuards; +#[derive(PartialEq)] +pub enum AddCallGuards { + AllCallEdges, + CriticalCallEdges, +} +pub use self::AddCallGuards::*; /** * Breaks outgoing critical edges for call terminators in the MIR. @@ -40,48 +45,52 @@ impl MirPass for AddCallGuards { _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) { - add_call_guards(mir); + self.add_call_guards(mir); } } -pub fn add_call_guards(mir: &mut Mir) { - let pred_count: IndexVec<_, _> = - mir.predecessors().iter().map(|ps| ps.len()).collect(); +impl AddCallGuards { + pub fn add_call_guards(&self, mir: &mut Mir) { + let pred_count: IndexVec<_, _> = + mir.predecessors().iter().map(|ps| ps.len()).collect(); - // We need a place to store the new blocks generated - let mut new_blocks = Vec::new(); + // We need a place to store the new blocks generated + let mut new_blocks = Vec::new(); - let cur_len = mir.basic_blocks().len(); + let cur_len = mir.basic_blocks().len(); - for block in mir.basic_blocks_mut() { - match block.terminator { - Some(Terminator { - kind: TerminatorKind::Call { - destination: Some((_, ref mut destination)), - cleanup: Some(_), - .. - }, source_info - }) if pred_count[*destination] > 1 => { - // It's a critical edge, break it - let call_guard = BasicBlockData { - statements: vec![], - is_cleanup: block.is_cleanup, - terminator: Some(Terminator { - source_info: source_info, - kind: TerminatorKind::Goto { target: *destination } - }) - }; + for block in mir.basic_blocks_mut() { + match block.terminator { + Some(Terminator { + kind: TerminatorKind::Call { + destination: Some((_, ref mut destination)), + cleanup, + .. + }, source_info + }) if pred_count[*destination] > 1 && + (cleanup.is_some() || self == &AllCallEdges) => + { + // It's a critical edge, break it + let call_guard = BasicBlockData { + statements: vec![], + is_cleanup: block.is_cleanup, + terminator: Some(Terminator { + source_info: source_info, + kind: TerminatorKind::Goto { target: *destination } + }) + }; - // Get the index it will be when inserted into the MIR - let idx = cur_len + new_blocks.len(); - new_blocks.push(call_guard); - *destination = BasicBlock::new(idx); + // Get the index it will be when inserted into the MIR + let idx = cur_len + new_blocks.len(); + new_blocks.push(call_guard); + *destination = BasicBlock::new(idx); + } + _ => {} } - _ => {} } + + debug!("Broke {} N edges", new_blocks.len()); + + mir.basic_blocks_mut().extend(new_blocks); } - - debug!("Broke {} N edges", new_blocks.len()); - - mir.basic_blocks_mut().extend(new_blocks); } From 445c08d2129e389fb9d0b7345598d0f6aac524b7 Mon Sep 17 00:00:00 2001 From: nicole mazzuca Date: Wed, 9 Aug 2017 13:52:43 -0700 Subject: [PATCH 28/38] fix a typo (this should not have been merged with this typo) --- src/libsyntax/parse/lexer/unicode_chars.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 85df4eee9134..6904fc950fa7 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -82,7 +82,7 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[ ('։', "Armenian Full Stop", ':'), ('܃', "Syriac Supralinear Colon", ':'), ('܄', "Syriac Sublinear Colon", ':'), - ('᛬', "Runic Multiple Ponctuation", ':'), + ('᛬', "Runic Multiple Punctuation", ':'), ('︰', "Presentation Form For Vertical Two Dot Leader", ':'), ('᠃', "Mongolian Full Stop", ':'), ('᠉', "Mongolian Manchu Full Stop", ':'), From 8c311e56b0630cef0a8a4f07b14f6e4693432878 Mon Sep 17 00:00:00 2001 From: Matt Ickstadt Date: Wed, 9 Aug 2017 19:23:05 -0500 Subject: [PATCH 29/38] Fix typo in unicode char definition --- src/libsyntax/parse/lexer/unicode_chars.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 85df4eee9134..a8d191f2ec9b 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -264,7 +264,7 @@ const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[ ('ꝸ', "Latin Small Letter Um", '&'), ('&', "Fullwidth Ampersand", '&'), - ('᛭', "Runic Cros Punctuation", '+'), + ('᛭', "Runic Cross Punctuation", '+'), ('➕', "Heavy Plus Sign", '+'), ('𐊛', "Lycian Letter H", '+'), ('﬩', "Hebrew Letter Alternative Plus Sign", '+'), From 27d7e61f1bbb6799adffebd56d64227e7b5a956c Mon Sep 17 00:00:00 2001 From: Foucher Date: Thu, 10 Aug 2017 08:49:40 +0200 Subject: [PATCH 30/38] Fix typo corersponding -> corresponding --- src/libstd/sys/unix/ext/net.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 94b87a6bff49..7701ae25b418 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -655,7 +655,7 @@ impl UnixListener { /// Accepts a new incoming connection to this listener. /// /// This function will block the calling thread until a new Unix connection - /// is established. When established, the corersponding [`UnixStream`] and + /// is established. When established, the corresponding [`UnixStream`] and /// the remote peer's address will be returned. /// /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html From 56a07539c0efd865b33dd07cd14b97d8ba23c584 Mon Sep 17 00:00:00 2001 From: Aidan Hobson Sayers Date: Thu, 10 Aug 2017 14:40:42 +0100 Subject: [PATCH 31/38] Fix cross-crate global allocators on windows --- src/librustc_trans/back/symbol_export.rs | 9 +++++++++ src/libstd/lib.rs | 14 ++++++++++---- src/tools/tidy/src/pal.rs | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 72071f8cec99..971483e91b6f 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -13,6 +13,7 @@ use rustc::util::nodemap::{FxHashMap, NodeSet}; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX}; use rustc::session::config; use rustc::ty::TyCtxt; +use rustc_allocator::ALLOCATOR_METHODS; use syntax::attr; /// The SymbolExportLevel of a symbols specifies from which kinds of crates @@ -83,6 +84,14 @@ impl ExportedSymbols { SymbolExportLevel::C)); } + if tcx.sess.allocator_kind.get().is_some() { + for method in ALLOCATOR_METHODS { + local_crate.push((format!("__rust_{}", method.name), + INVALID_DEF_ID, + SymbolExportLevel::Rust)); + } + } + if let Some(id) = tcx.sess.derive_registrar_fn.get() { let def_id = tcx.hir.local_def_id(id); let idx = def_id.index; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 8850a8a5582d..f7748aa3f041 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -319,12 +319,18 @@ #![default_lib_allocator] // Always use alloc_system during stage0 since we don't know if the alloc_* -// crate the stage0 compiler will pick by default is available (most -// obviously, if the user has disabled jemalloc in `./configure`). +// crate the stage0 compiler will pick by default is enabled (e.g. +// if the user has disabled jemalloc in `./configure`). // `force_alloc_system` is *only* intended as a workaround for local rebuilds // with a rustc without jemalloc. -#![cfg_attr(any(stage0, feature = "force_alloc_system"), feature(global_allocator))] -#[cfg(any(stage0, feature = "force_alloc_system"))] +// The not(stage0+msvc) gates will only last until the next stage0 bump +#![cfg_attr(all( + not(all(stage0, target_env = "msvc")), + any(stage0, feature = "force_alloc_system")), + feature(global_allocator))] +#[cfg(all( + not(all(stage0, target_env = "msvc")), + any(stage0, feature = "force_alloc_system")))] #[global_allocator] static ALLOC: alloc_system::System = alloc_system::System; diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 1065749a6961..10c997138204 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -69,6 +69,7 @@ const EXCEPTION_PATHS: &'static [&'static str] = &[ "src/libstd/path.rs", "src/libstd/f32.rs", "src/libstd/f64.rs", + "src/libstd/lib.rs", // Until next stage0 snapshot bump "src/libstd/sys_common/mod.rs", "src/libstd/sys_common/net.rs", "src/libterm", // Not sure how to make this crate portable, but test needs it From 645117fd96831ddcda35e4d6d2bdba9935c58e53 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Aug 2017 22:50:29 +0200 Subject: [PATCH 32/38] Add missing links on File struct docs --- src/libstd/fs.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 38d3312b4e7d..adbfcc366af9 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -28,7 +28,7 @@ use time::SystemTime; /// A reference to an open file on the filesystem. /// /// An instance of a `File` can be read and/or written depending on what options -/// it was opened with. Files also implement `Seek` to alter the logical cursor +/// it was opened with. Files also implement [`Seek`] to alter the logical cursor /// that the file contains internally. /// /// Files are automatically closed when they go out of scope. @@ -48,7 +48,7 @@ use time::SystemTime; /// # } /// ``` /// -/// Read the contents of a file into a `String`: +/// Read the contents of a file into a [`String`]: /// /// ```no_run /// use std::fs::File; @@ -81,6 +81,8 @@ use time::SystemTime; /// # } /// ``` /// +/// [`Seek`]: ../io/trait.Seek.html +/// [`String`]: ../string/struct.String.html /// [`Read`]: ../io/trait.Read.html /// [`BufReader`]: ../io/struct.BufReader.html #[stable(feature = "rust1", since = "1.0.0")] From 9e25984ee1bfb797ad1c889b4296277045389d8b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Aug 2017 23:01:59 +0200 Subject: [PATCH 33/38] Add missing links in ReadDir docs --- src/libstd/fs.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index adbfcc366af9..062186ef7086 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -106,19 +106,19 @@ pub struct Metadata(fs_imp::FileAttr); /// Iterator over the entries in a directory. /// /// This iterator is returned from the [`read_dir`] function of this module and -/// will yield instances of `io::Result`. Through a [`DirEntry`] +/// will yield instances of [`io::Result`]`<`[`DirEntry`]`>`. Through a [`DirEntry`] /// information like the entry's path and possibly other metadata can be /// learned. /// -/// [`read_dir`]: fn.read_dir.html -/// [`DirEntry`]: struct.DirEntry.html -/// /// # Errors /// -/// This [`io::Result`] will be an `Err` if there's some sort of intermittent +/// This [`io::Result`] will be an [`Err`] if there's some sort of intermittent /// IO error during iteration. /// +/// [`read_dir`]: fn.read_dir.html +/// [`DirEntry`]: struct.DirEntry.html /// [`io::Result`]: ../io/type.Result.html +/// [`Err`]: ../result/enum.Result.html#variant.Err #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct ReadDir(fs_imp::ReadDir); From ac0ee51c1793029e93961e5a34458a6d3a049ac6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Aug 2017 23:05:50 +0200 Subject: [PATCH 34/38] Add missing links in io::Error docs --- src/libstd/io/error.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 0a5804a77441..12716b9b502e 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -17,17 +17,21 @@ use convert::From; /// A specialized [`Result`](../result/enum.Result.html) type for I/O /// operations. /// -/// This type is broadly used across `std::io` for any operation which may +/// This type is broadly used across [`std::io`] for any operation which may /// produce an error. /// -/// This typedef is generally used to avoid writing out `io::Error` directly and -/// is otherwise a direct mapping to `Result`. +/// This typedef is generally used to avoid writing out [`io::Error`] directly and +/// is otherwise a direct mapping to [`Result`]. /// -/// While usual Rust style is to import types directly, aliases of `Result` -/// often are not, to make it easier to distinguish between them. `Result` is -/// generally assumed to be `std::result::Result`, and so users of this alias +/// While usual Rust style is to import types directly, aliases of [`Result`] +/// often are not, to make it easier to distinguish between them. [`Result`] is +/// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias /// will generally use `io::Result` instead of shadowing the prelude's import -/// of `std::result::Result`. +/// of [`std::result::Result`][`Result`]. +/// +/// [`std::io`]: ../io/index.html +/// [`io::Error`]: ../io/struct.Error.html +/// [`Result`]: ../result/enum.Result.html /// /// # Examples /// From 592bdc3974005a82ec2701a9ef10f49f3bbd0ef7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Aug 2017 23:11:40 +0200 Subject: [PATCH 35/38] Add missing links in io module docs --- src/libstd/io/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 9a3036f753ed..f486493f98b4 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -22,7 +22,7 @@ //! you'll see a few different types of I/O throughout the documentation in //! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec`]s. For //! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on -//! `File`s: +//! [`File`]s: //! //! ``` //! use std::io; @@ -146,9 +146,9 @@ //! # } //! ``` //! -//! Note that you cannot use the `?` operator in functions that do not return -//! a `Result` (e.g. `main`). Instead, you can call `.unwrap()` or `match` -//! on the return value to catch any possible errors: +//! Note that you cannot use the [`?` operator] in functions that do not return +//! a [`Result`][`Result`] (e.g. `main`). Instead, you can call [`.unwrap()`] +//! or `match` on the return value to catch any possible errors: //! //! ``` //! use std::io; @@ -265,6 +265,8 @@ //! [`io::Result`]: type.Result.html //! [`?` operator]: ../../book/first-edition/syntax-index.html //! [`Read::read`]: trait.Read.html#tymethod.read +//! [`Result`]: ../result/enum.Result.html +//! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap #![stable(feature = "rust1", since = "1.0.0")] From 972d67cec1fc0aeafebcc60ffcdf4dea0eadff8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Aug 2017 23:14:49 +0200 Subject: [PATCH 36/38] Add missing links for Error docs --- src/libstd/io/error.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 12716b9b502e..68f55221a6c9 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -51,13 +51,16 @@ use convert::From; #[stable(feature = "rust1", since = "1.0.0")] pub type Result = result::Result; -/// The error type for I/O operations of the `Read`, `Write`, `Seek`, and +/// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and /// associated traits. /// /// Errors mostly originate from the underlying OS, but custom instances of /// `Error` can be created with crafted error messages and a particular value of /// [`ErrorKind`]. /// +/// [`Read`]: ../io/trait.Read.html +/// [`Write`]: ../io/trait.Write.html +/// [`Seek`]: ../io/trait.Seek.html /// [`ErrorKind`]: enum.ErrorKind.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] From 4b80d598c5a87a1b069814c8be744709a1efc460 Mon Sep 17 00:00:00 2001 From: Justin Browne Date: Thu, 10 Aug 2017 18:03:22 -0400 Subject: [PATCH 37/38] Fix broken links in Arc documentation --- src/liballoc/arc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 9e3142519341..daf556795fa6 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -95,7 +95,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// # Cloning references /// /// Creating a new reference from an existing reference counted pointer is done using the -/// `Clone` trait implemented for [`Arc`][`arc`] and [`Weak`][`weak`]. +/// `Clone` trait implemented for [`Arc`][arc] and [`Weak`][weak]. /// /// ``` /// use std::sync::Arc; From b6172008bf3165dcc28973e64ef3ff346be9f23a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Aug 2017 00:23:42 +0200 Subject: [PATCH 38/38] Improve enum variants display --- src/librustdoc/html/static/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 51465bafc42e..8146c005a5e9 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -677,6 +677,10 @@ span.since { left: 0; } +.variant + .toggle-wrapper + .docblock > p { + margin-top: 5px; +} + .variant + .toggle-wrapper > a { margin-top: 5px; }