From 261efb6f5d0b3a7985bd1a76378ab5c9f7014c96 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 17:10:09 -0500 Subject: [PATCH 01/37] suppress the default allow(unused) under --display-warnings --- src/librustdoc/markdown.rs | 1 + src/librustdoc/test.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 0f107457d2bf8..b7d7cc0c44ce4 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -148,6 +148,7 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, let mut opts = TestOptions::default(); opts.no_crate_inject = true; + opts.display_warnings = display_warnings; let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs, true, opts, maybe_sysroot, None, Some(PathBuf::from(input)), diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 117b21d47587f..58bcbe9aa93a1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -45,7 +45,12 @@ use html::markdown; #[derive(Clone, Default)] pub struct TestOptions { + /// Whether to disable the default `extern crate my_crate;` when creating doctests. pub no_crate_inject: bool, + /// Whether to emit compilation warnings when compiling doctests. Setting this will suppress + /// the default `#![allow(unused)]`. + pub display_warnings: bool, + /// Additional crate-level attributes to add to doctests. pub attrs: Vec, } @@ -107,7 +112,8 @@ pub fn run(input_path: &Path, let crate_name = crate_name.unwrap_or_else(|| { ::rustc_trans_utils::link::find_crate_name(None, &hir_forest.krate().attrs, &input) }); - let opts = scrape_test_config(hir_forest.krate()); + let mut opts = scrape_test_config(hir_forest.krate()); + opts.display_warnings |= display_warnings; let mut collector = Collector::new(crate_name, cfgs, libs, @@ -146,6 +152,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions { let mut opts = TestOptions { no_crate_inject: false, + display_warnings: false, attrs: Vec::new(), }; @@ -347,7 +354,7 @@ pub fn make_test(s: &str, let mut line_offset = 0; let mut prog = String::new(); - if opts.attrs.is_empty() { + if opts.attrs.is_empty() && !opts.display_warnings { // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some // lints that are commonly triggered in doctests. The crate-level test attributes are // commonly used to make tests fail in case they trigger warnings, so having this there in @@ -772,6 +779,7 @@ assert_eq!(2+2, 4); //adding it anyway let opts = TestOptions { no_crate_inject: true, + display_warnings: false, attrs: vec![], }; let input = @@ -924,4 +932,19 @@ assert_eq!(2+2, 4);".to_string(); let output = make_test(input, None, true, &opts); assert_eq!(output, (expected.clone(), 1)); } + + #[test] + fn make_test_display_warnings() { + //if the user is asking to display doctest warnings, suppress the default allow(unused) + let mut opts = TestOptions::default(); + opts.display_warnings = true; + let input = +"assert_eq!(2+2, 4);"; + let expected = +"fn main() { +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, None, false, &opts); + assert_eq!(output, (expected.clone(), 2)); + } } From 683ad942966c427be773b412d9314baa55a6e188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:38:12 +0100 Subject: [PATCH 02/37] Add OnDrop --- src/librustc_data_structures/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 81246aea1b56e..bf0b3726bb301 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -76,6 +76,14 @@ pub mod flock; pub mod sync; pub mod owning_ref; +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { + (self.0)(); + } +} + // See comments in src/librustc/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} From 3b43dcbb4c62a36b68afd7f9a1bf12aed1b53d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:11:23 +0100 Subject: [PATCH 03/37] Replace Rc with Lrc --- src/librustc/middle/const_val.rs | 4 ++-- src/librustc/traits/query/dropck_outlives.rs | 6 +++--- src/librustc/traits/query/normalize.rs | 6 +++--- src/librustc/ty/structural_impls.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 6 +++--- src/librustc_traits/dropck_outlives.rs | 4 ++-- src/librustc_traits/normalize_projection_ty.rs | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8c3dfd0bce752..19a7576b7ceac 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -19,7 +19,7 @@ use graphviz::IntoCow; use syntax_pos::Span; use std::borrow::Cow; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; @@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> { #[derive(Clone, Debug)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub kind: Rc>, + pub kind: Lrc>, } #[derive(Clone, Debug)] diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef9..e16a1082214f7 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -15,7 +15,7 @@ use std::iter::FromIterator; use traits::query::CanonicalTyGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Kind; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -182,13 +182,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 70c5cf5f39029..63f50cff4c2ad 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -17,7 +17,7 @@ use infer::at::At; use infer::canonical::{Canonical, Canonicalize, QueryResult}; use middle::const_val::ConstVal; use mir::interpret::GlobalId; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::query::CanonicalProjectionGoal; use traits::project::Normalized; @@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c9a69d5405c9a..3fc20508ad7ee 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; @@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { tcx.lift(&*self.kind).map(|kind| { ConstEvalErr { span: self.span, - kind: Rc::new(kind), + kind: Lrc::new(kind), } }) } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b033..50997089a5764 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory}; use std::fmt; use std::error::Error; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -477,7 +477,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do match-check before building MIR if tcx.check_match(def_id).is_err() { return Err(ConstEvalErr { - kind: Rc::new(CheckMatchError), + kind: Lrc::new(CheckMatchError), span, }); } @@ -489,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Rc::new(TypeckError), + kind: Lrc::new(TypeckError), span, }); } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2a8cfe5cc06b3..1fe2f87128abd 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::FxHashSet; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::codemap::{Span, DUMMY_SP}; use util; crate fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", goal); tcx.infer_ctxt().enter(|ref infcx| { diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc3..62d5ef11551c0 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; use rustc::ty::{ParamEnvAnd, TyCtxt}; use rustc::util::common::CellUsizeExt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::DUMMY_SP; use util; @@ -22,7 +22,7 @@ use util; crate fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess.perf_stats.normalize_projection_ty.increment(); From 910bf840cce1da57b96f7ac15f8b803675bb8a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:09:20 +0100 Subject: [PATCH 04/37] Always print `aborting due to n previous error(s)` and only print it once for multi-threaded code --- src/librustc_driver/lib.rs | 54 +++++++++++++++++++--------------- src/librustc_errors/lib.rs | 34 +++++++++++---------- src/librustc_typeck/astconv.rs | 3 +- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5a1983bfec64f..2a15d57a262e1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -63,6 +63,7 @@ use rustc_resolve as resolve; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::OnDrop; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::CompileIncomplete; use rustc::session::config::{Input, PrintRequest, ErrorOutputType}; @@ -515,30 +516,35 @@ fn run_compiler_impl<'a>(args: &[String], target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; - let plugins = sess.opts.debugging_opts.extra_plugins.clone(); - - let cstore = CStore::new(trans.metadata_loader()); - - do_or_return!(callbacks.late_callback(&*trans, - &matches, - &sess, - &cstore, - &input, - &odir, - &ofile), Some(sess)); - - let control = callbacks.build_controller(&sess, &matches); - - (driver::compile_input(trans, - &sess, - &cstore, - &input_file_path, - &input, - &odir, - &ofile, - Some(plugins), - &control), - Some(sess)) + let result = { + let plugins = sess.opts.debugging_opts.extra_plugins.clone(); + + let cstore = CStore::new(trans.metadata_loader()); + + do_or_return!(callbacks.late_callback(&*trans, + &matches, + &sess, + &cstore, + &input, + &odir, + &ofile), Some(sess)); + + let _sess_abort_error = OnDrop(|| sess.diagnostic().print_error_count()); + + let control = callbacks.build_controller(&sess, &matches); + + driver::compile_input(trans, + &sess, + &cstore, + &input_file_path, + &input, + &odir, + &ofile, + Some(plugins), + &control) + }; + + (result, Some(sess)) } // Extract output directory and file from matches. diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7148969191f2b..b3265c21884be 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -555,21 +555,15 @@ impl Handler { pub fn has_errors(&self) -> bool { self.err_count() > 0 } - pub fn abort_if_errors(&self) { - let s; - match self.err_count() { - 0 => { - if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { - DiagnosticBuilder::new_diagnostic(self, bug).emit(); - } - return; - } - 1 => s = "aborting due to previous error".to_string(), - _ => { - s = format!("aborting due to {} previous errors", self.err_count()); - } - } - let err = self.fatal(&s); + + pub fn print_error_count(&self) { + let s = match self.err_count() { + 0 => return, + 1 => "aborting due to previous error".to_string(), + _ => format!("aborting due to {} previous errors", self.err_count()) + }; + + let _ = self.fatal(&s); let can_show_explain = self.emitter.borrow().should_show_explain(); let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty(); @@ -600,8 +594,16 @@ impl Handler { } } } + } - err.raise(); + pub fn abort_if_errors(&self) { + if self.err_count() == 0 { + if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { + DiagnosticBuilder::new_diagnostic(self, bug).emit(); + } + return; + } + FatalError.raise(); } pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { if lvl == Warning && !self.flags.can_emit_warnings { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 827ca79334cbe..bc69fbdb77837 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -27,6 +27,7 @@ use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; use util::nodemap::FxHashSet; +use errors::FatalError; use std::iter; use syntax::{abi, ast}; @@ -337,7 +338,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::Trait(trait_def_id) => trait_def_id, Def::TraitAlias(alias_def_id) => alias_def_id, Def::Err => { - self.tcx().sess.fatal("cannot continue compilation due to previous error"); + FatalError.raise(); } _ => unreachable!(), } From b1d872b38eaacefbef73faa6a4a0c07622a8c941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 16:13:47 +0100 Subject: [PATCH 05/37] Update tests --- src/test/ui-fulldeps/custom-derive/issue-36935.stderr | 2 ++ src/test/ui-fulldeps/proc-macro/load-panic.stderr | 2 ++ src/test/ui/codemap_tests/two_files.stderr | 3 ++- src/test/ui/cross-file-errors/main.stderr | 2 ++ src/test/ui/did_you_mean/recursion_limit_macro.stderr | 2 ++ src/test/ui/error-codes/E0404.stderr | 3 ++- src/test/ui/error-codes/E0405.stderr | 3 ++- src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr | 2 ++ src/test/ui/feature-gate-fn_must_use.stderr | 2 ++ .../feature-gate/issue-43106-gating-of-builtin-attrs.stderr | 2 ++ .../ui/feature-gate/issue-43106-gating-of-deprecated.stderr | 2 ++ src/test/ui/impl-trait/universal_wrong_bounds.stderr | 4 +++- src/test/ui/issue-22644.stderr | 2 ++ src/test/ui/issue-44406.stderr | 2 ++ src/test/ui/lint-output-format-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels.stderr | 2 ++ src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr | 2 ++ src/test/ui/loops-reject-lifetime-shadowing-label.stderr | 2 ++ src/test/ui/macro-context.stderr | 2 ++ src/test/ui/macros/macro_path_as_generic_bound.stderr | 3 ++- src/test/ui/macros/trace_faulty_macros.stderr | 2 ++ src/test/ui/raw_string.stderr | 2 ++ src/test/ui/resolve/issue-21221-1.stderr | 4 +++- src/test/ui/resolve/issue-21221-2.stderr | 3 ++- src/test/ui/resolve/issue-21221-3.stderr | 3 ++- src/test/ui/resolve/issue-21221-4.stderr | 3 ++- src/test/ui/resolve/issue-3907.stderr | 3 ++- src/test/ui/resolve/issue-5035.stderr | 4 +++- .../ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr | 4 +++- .../generic-associated-types-where.stderr | 2 -- src/test/ui/span/issue-24690.stderr | 2 ++ src/test/ui/span/issue-35987.stderr | 3 ++- 33 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr index b082999a8978d..0278256994120 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr @@ -6,3 +6,5 @@ LL | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked | = help: message: lolnope +error: aborting due to previous error + diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui-fulldeps/proc-macro/load-panic.stderr index edfd134469cda..30ad53f9041f0 100644 --- a/src/test/ui-fulldeps/proc-macro/load-panic.stderr +++ b/src/test/ui-fulldeps/proc-macro/load-panic.stderr @@ -6,3 +6,5 @@ LL | #[derive(A)] | = help: message: nope! +error: aborting due to previous error + diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 614531c982128..e247e86fbcb22 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -4,5 +4,6 @@ error[E0404]: expected trait, found type alias `Bar` LL | impl Bar for Baz { } //~ ERROR expected trait, found type alias | ^^^ type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr index a9db5214e6a2e..8fe795f7f1d8a 100644 --- a/src/test/ui/cross-file-errors/main.stderr +++ b/src/test/ui/cross-file-errors/main.stderr @@ -9,3 +9,5 @@ LL | _ LL | underscore!(); | -------------- in this macro invocation +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index f6bce55528c7d..265a688df9910 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -9,3 +9,5 @@ LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr index 9f705da586167..afb748bedbe0f 100644 --- a/src/test/ui/error-codes/E0404.stderr +++ b/src/test/ui/error-codes/E0404.stderr @@ -10,5 +10,6 @@ error[E0404]: expected trait, found struct `Foo` LL | fn baz(_: T) {} //~ ERROR E0404 | ^^^ not a trait -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/error-codes/E0405.stderr b/src/test/ui/error-codes/E0405.stderr index b5901dd9c848b..27190af1c6c11 100644 --- a/src/test/ui/error-codes/E0405.stderr +++ b/src/test/ui/error-codes/E0405.stderr @@ -4,5 +4,6 @@ error[E0405]: cannot find trait `SomeTrait` in this scope LL | impl SomeTrait for Foo {} //~ ERROR E0405 | ^^^^^^^^^ not found in this scope -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr index a9952ff4fac13..a2c1dedff385a 100644 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr +++ b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr @@ -4,3 +4,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr index 4772cf28f6c12..431c57abd2653 100644 --- a/src/test/ui/feature-gate-fn_must_use.stderr +++ b/src/test/ui/feature-gate-fn_must_use.stderr @@ -20,3 +20,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 9c4fb79f6f1aa..0beed62798710 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1316,3 +1316,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr index 83f6e016370bb..802c5d9384d75 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr @@ -6,3 +6,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index a02fc1f748faa..3cc0bebe81655 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -24,5 +24,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::fmt::Debug; | -error: cannot continue compilation due to previous error +error: aborting due to 3 previous errors +Some errors occurred: E0405, E0425. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 257b9bd235d76..aeb465b2ab233 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -89,3 +89,5 @@ error: expected type, found `4` LL | println!("{}", a: &mut 4); //~ ERROR expected type, found `4` | ^ expecting a type here because of type ascription +error: aborting due to 9 previous errors + diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr index 443b28cf09968..de7c11732e4a3 100644 --- a/src/test/ui/issue-44406.stderr +++ b/src/test/ui/issue-44406.stderr @@ -13,3 +13,5 @@ LL | bar(baz: $rest) LL | foo!(true); //~ ERROR expected type, found keyword | ^^^^ expecting a type here because of type ascription +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint-output-format-2.stderr b/src/test/ui/lint-output-format-2.stderr index b2d1e1ac05822..d484061ef9661 100644 --- a/src/test/ui/lint-output-format-2.stderr +++ b/src/test/ui/lint-output-format-2.stderr @@ -22,3 +22,5 @@ LL | | let _y = bar(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops-reject-duplicate-labels-2.stderr index d35ed4ff88a67..830270a99d112 100644 --- a/src/test/ui/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops-reject-duplicate-labels-2.stderr @@ -70,3 +70,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels.stderr b/src/test/ui/loops-reject-duplicate-labels.stderr index d1b874ea99729..a71f98b812a8c 100644 --- a/src/test/ui/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops-reject-duplicate-labels.stderr @@ -73,3 +73,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr index 0cdd58fdbd75d..af524d5b01766 100644 --- a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr +++ b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr @@ -108,3 +108,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr index a050aec50c72b..999cfb9cc3c6b 100644 --- a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr +++ b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr @@ -14,3 +14,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/macro-context.stderr b/src/test/ui/macro-context.stderr index 4dc6bbe4d656c..b3e67fb2607cd 100644 --- a/src/test/ui/macro-context.stderr +++ b/src/test/ui/macro-context.stderr @@ -43,3 +43,5 @@ LL | () => ( i ; typeof ); //~ ERROR expected expression, found reserved k LL | m!(); | ----- in this macro invocation +error: aborting due to 4 previous errors + diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr index 06d22714dd8b6..0f9f0607c5bf2 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.stderr +++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr @@ -4,5 +4,6 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m` LL | foo!(m::m2::A); //~ ERROR failed to resolve | ^ Use of undeclared type or module `m` -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 9fb5b17a3114b..a9ffef8ef8090 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -45,3 +45,5 @@ LL | my_recursive_macro!(); = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro ! ( ) ;` +error: aborting due to 2 previous errors + diff --git a/src/test/ui/raw_string.stderr b/src/test/ui/raw_string.stderr index b8aa596ef953a..ddf1cfe406f7c 100644 --- a/src/test/ui/raw_string.stderr +++ b/src/test/ui/raw_string.stderr @@ -6,3 +6,5 @@ LL | let x = r##"lol"#; | = note: this raw string should be terminated with `"##` +error: aborting due to previous error + diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index a9d2aeee2d151..3edfa33d80a02 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -45,5 +45,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Div; | -error: cannot continue compilation due to previous error +error: aborting due to 4 previous errors +Some errors occurred: E0405, E0412. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index c61ffe3b33e8a..e11fe9ac4cf11 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use foo::bar::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index 7725f74cb49fc..f406cd6e35fcf 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_3::outer::OuterTrait; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index b0a4d5ba4d898..c0a7f1734f49c 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_4::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 2b8b2b20685f8..3627c09b28fd9 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use issue_3907::Foo; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 6597f05889af8..353a0b1c3d9d0 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -13,5 +13,7 @@ LL | impl K for isize {} //~ ERROR expected trait, found type alias `K` | did you mean `I`? | type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0432. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 6e7bd28d16fc3..f32c5e9b2c6bd 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -10,5 +10,7 @@ error[E0404]: expected trait, found type alias `Typedef` LL | fn g isize>(x: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0405. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr index bb55d86f620b7..e69de29bb2d1d 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr @@ -1,2 +0,0 @@ -error: cannot continue compilation due to previous error - diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 6a4ec73b27a66..b496a1a76c017 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -36,3 +36,5 @@ LL | | println!("{}", theTwo); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 2d4a7cc72f5f6..1dd45bb1e5efe 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. From 9e6268191205c42bc7958d949fa48811d60857f9 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 10:32:29 +0900 Subject: [PATCH 06/37] Remove core::fmt::num::Decimal Before ebf9e1aaf6, it was used for Display::fmt, but ebf9e1aaf6 replaced that with a faster implementation, and nothing else uses it. --- src/libcore/fmt/num.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db34..57e3b849ae1e3 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -107,10 +107,6 @@ struct Binary; #[derive(Clone, PartialEq)] struct Octal; -/// A decimal (base 10) radix -#[derive(Clone, PartialEq)] -struct Decimal; - /// A hexadecimal (base 16) radix, formatted with lower-case characters #[derive(Clone, PartialEq)] struct LowerHex; @@ -136,7 +132,6 @@ macro_rules! radix { radix! { Binary, 2, "0b", x @ 0 ... 1 => b'0' + x } radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x } -radix! { Decimal, 10, "", x @ 0 ... 9 => b'0' + x } radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x, x @ 10 ... 15 => b'a' + (x - 10) } radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, From e85c9227c2e913b71f0d7b6cc2322d7897f28554 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 27 Feb 2018 16:51:12 +0900 Subject: [PATCH 07/37] rustc_driver: get rid of extra thread on Unix --- src/librustc_driver/lib.rs | 51 +++++++++++++++++++++++----- src/libstd/sys_common/thread_info.rs | 4 +++ src/libstd/thread/mod.rs | 8 +++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f1f3a0519bbcb..8605764497a16 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -24,6 +24,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#![feature(rustc_stack_internals)] extern crate arena; extern crate getopts; @@ -1461,16 +1462,50 @@ pub fn in_rustc_thread(f: F) -> Result> // Temporarily have stack size set to 16MB to deal with nom-using crates failing const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB - let mut cfg = thread::Builder::new().name("rustc".to_string()); + #[cfg(unix)] + let spawn_thread = unsafe { + // Fetch the current resource limits + let mut rlim = libc::rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling getrlimit: {}", err); + true + } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { + true + } else { + rlim.rlim_cur = STACK_SIZE as libc::rlim_t; + if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling setrlimit: {}", err); + true + } else { + std::thread::update_stack_guard(); + false + } + } + }; - // FIXME: Hacks on hacks. If the env is trying to override the stack size - // then *don't* set it explicitly. - if env::var_os("RUST_MIN_STACK").is_none() { - cfg = cfg.stack_size(STACK_SIZE); - } + #[cfg(not(unix))] + let spawn_thread = true; + + // The or condition is added from backward compatibility. + if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() { + let mut cfg = thread::Builder::new().name("rustc".to_string()); + + // FIXME: Hacks on hacks. If the env is trying to override the stack size + // then *don't* set it explicitly. + if env::var_os("RUST_MIN_STACK").is_none() { + cfg = cfg.stack_size(STACK_SIZE); + } - let thread = cfg.spawn(f); - thread.unwrap().join() + let thread = cfg.spawn(f); + thread.unwrap().join() + } else { + Ok(f()) + } } /// Get a list of extra command-line flags provided by the user, as strings. diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs index 6a2b6742367a5..d75cbded7347b 100644 --- a/src/libstd/sys_common/thread_info.rs +++ b/src/libstd/sys_common/thread_info.rs @@ -50,3 +50,7 @@ pub fn set(stack_guard: Option, thread: Thread) { thread, })); } + +pub fn reset_guard(stack_guard: Option) { + THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard); +} diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 71aee673cfe3e..b686ddc205ea7 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,6 +208,14 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = imp::guard::init(); + thread_info::reset_guard(main_guard); +} + //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From 1bb89f1b3cf1e4b5fa83391872136251c0030c1e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 6 Mar 2018 13:33:36 +0900 Subject: [PATCH 08/37] rustc_driver: get rid of extra thread on Windows --- src/librustc_driver/lib.rs | 6 +++++- src/rustc/rustc.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8605764497a16..761797239412e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1488,7 +1488,11 @@ pub fn in_rustc_thread(f: F) -> Result> } }; - #[cfg(not(unix))] + // We set the stack size at link time. See src/rustc/rustc.rs. + #[cfg(windows)] + let spawn_thread = false; + + #[cfg(not(any(windows,unix)))] let spawn_thread = true; // The or condition is added from backward compatibility. diff --git a/src/rustc/rustc.rs b/src/rustc/rustc.rs index bfd01146d2c46..bd36aaf01f860 100644 --- a/src/rustc/rustc.rs +++ b/src/rustc/rustc.rs @@ -9,6 +9,15 @@ // except according to those terms. #![feature(rustc_private)] +#![feature(link_args)] + +// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread +// for the rationale. +#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")] +// We only build for msvc and gnu now, but we use a exhaustive condition here +// so we can expect either the stack size to be set or the build fails. +#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")] +extern {} extern crate rustc_driver; From a185b56b7caca17c7aa9d6f702fe1b2209c82e4e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 18 Mar 2018 23:02:06 +0900 Subject: [PATCH 09/37] Address review comments --- src/librustc_driver/lib.rs | 8 +++++--- src/libstd/rt.rs | 15 +++++++++++++++ src/libstd/sys/unix/thread.rs | 20 +++++++++++++++++++- src/libstd/thread/mod.rs | 8 -------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 761797239412e..e39a2c2f5dcd9 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1476,13 +1476,15 @@ pub fn in_rustc_thread(f: F) -> Result> } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { true } else { + std::rt::deinit_stack_guard(); rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - error!("in_rustc_thread: error calling setrlimit: {}", err); - true + // We have already deinited the stack. Further corruption is + // not allowed. + panic!("in_rustc_thread: error calling setrlimit: {}", err); } else { - std::thread::update_stack_guard(); + std::rt::update_stack_guard(); false } } diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index e1392762a59dc..8f945470b7e94 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -73,3 +73,18 @@ fn lang_start { lang_start_internal(&move || main().report(), argc, argv) } + +/// Function used for reverting changes to the main stack before setrlimit(). +/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn deinit_stack_guard() { + ::sys::thread::guard::deinit(); +} + +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = ::sys::thread::guard::init(); + ::sys_common::thread_info::reset_guard(main_guard); +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 72cdb9440b8e7..d94e11a5207cb 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -222,7 +222,7 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::mmap; + use libc::{mmap, munmap}; use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -336,6 +336,24 @@ pub mod guard { } } + pub unsafe fn deinit() { + if !cfg!(target_os = "linux") { + if let Some(mut stackaddr) = get_stack_start() { + // Ensure address is aligned. Same as above. + let remainder = (stackaddr as usize) % PAGE_SIZE; + if remainder != 0 { + stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) + as *mut libc::c_void; + } + + // Undo the guard page mapping. + if munmap(stackaddr, PAGE_SIZE) != 0 { + panic!("unable to deallocate the guard page"); + } + } + } + } + #[cfg(any(target_os = "macos", target_os = "bitrig", target_os = "openbsd", diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index b686ddc205ea7..71aee673cfe3e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,14 +208,6 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; -/// Function used for resetting the main stack guard address after setrlimit(). -/// This is POSIX specific and unlikely to be directly stabilized. -#[unstable(feature = "rustc_stack_internals", issue = "0")] -pub unsafe fn update_stack_guard() { - let main_guard = imp::guard::init(); - thread_info::reset_guard(main_guard); -} - //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From c5c650d670f5f191ea9667b455c15a607e550fdb Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 00:26:41 -0500 Subject: [PATCH 10/37] Split out termination_trait_test feature gate --- src/libsyntax/feature_gate.rs | 3 +++ src/libsyntax/test.rs | 8 +++---- .../feature-gate-termination_trait_test.rs | 22 +++++++++++++++++++ .../termination-trait-in-test.rs | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/feature-gate-termination_trait_test.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd686064..0950965233f6a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -432,6 +432,9 @@ declare_features! ( // Termination trait in main (RFC 1937) (active, termination_trait, "1.24.0", Some(43301), None), + // Termination trait in tests (RFC 1937) + (active, termination_trait_test, "1.24.0", Some(48854), None), + // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9edfa767d3195..d107ab59a9ad9 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -332,7 +332,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -359,7 +359,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { match has_test_signature(cx, i) { Yes => true, No => { - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as tests can not have any arguments"); } else { diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"); @@ -388,7 +388,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -416,7 +416,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { if has_bench_attr && !has_bench_signature { let diag = cx.span_diagnostic; - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> impl Termination`"); } else { diff --git a/src/test/compile-fail/feature-gate-termination_trait_test.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs new file mode 100644 index 0000000000000..4af7e94671627 --- /dev/null +++ b/src/test/compile-fail/feature-gate-termination_trait_test.rs @@ -0,0 +1,22 @@ +// 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. + +// compile-flags: --test + +fn main() {} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() -> Result<(), ()> { + //~^ ERROR functions used as tests must have signature fn() -> () + Ok(()) + } +} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs index 494500d522abe..11997eb691728 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -10,7 +10,7 @@ // compile-flags: --test -#![feature(termination_trait)] +#![feature(termination_trait_test)] #![feature(test)] extern crate test; From 685c3c1b4a7c1949048177409ca43fc05daefd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:01:11 -0700 Subject: [PATCH 11/37] Reduce the diagnostic span when multiple fields are missing in pattern --- src/librustc_typeck/check/_match.rs | 70 +++++++++++-------- .../ui/missing-fields-in-struct-pattern.rs | 17 +++++ 2 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.rs diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 379fd93ba2bd6..0b5383f1f8d1e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -904,6 +904,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap(); + let mut inexistent_fields = vec![]; // Typecheck each field. for &Spanned { node: ref field, span } in fields { let field_ty = match used_fields.entry(field.name) { @@ -927,34 +928,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.field_ty(span, f, substs) }) .unwrap_or_else(|| { - let mut err = struct_span_err!( - tcx.sess, - span, - E0026, - "{} `{}` does not have a field named `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name - ); - err.span_label(span, - format!("{} `{}` does not have field `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name)); - if tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "This error indicates that a struct pattern attempted to \ - extract a non-existent field from a struct. Struct fields \ - are identified by the name used before the colon : so struct \ - patterns should resemble the declaration of the struct type \ - being matched.\n\n\ - If you are using shorthand field patterns but want to refer \ - to the struct field by a different name, you should rename \ - it explicitly." - ); - } - err.emit(); - + inexistent_fields.push((span, field.name)); tcx.types.err }) } @@ -963,6 +937,46 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.check_pat_walk(&field.pat, field_ty, def_bm, true); } + if inexistent_fields.len() > 0 { + let field_names = if inexistent_fields.len() == 1 { + format!("a field named `{}`", inexistent_fields[0].1) + } else { + format!("fields named {}", + inexistent_fields.iter() + .map(|(_, name)| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; + let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); + let mut err = struct_span_err!(tcx.sess, + spans, + E0026, + "{} `{}` does not have {}", + kind_name, + tcx.item_path_str(variant.did), + field_names); + for (span, name) in &inexistent_fields { + err.span_label(*span, + format!("{} `{}` does not have field `{}`", + kind_name, + tcx.item_path_str(variant.did), + name)); + } + if tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "This error indicates that a struct pattern attempted to \ + extract a non-existent field from a struct. Struct fields \ + are identified by the name used before the colon : so struct \ + patterns should resemble the declaration of the struct type \ + being matched.\n\n\ + If you are using shorthand field patterns but want to refer \ + to the struct field by a different name, you should rename \ + it explicitly." + ); + } + err.emit(); + } + // Require `..` if struct has non_exhaustive attribute. if adt.is_struct() && adt.is_non_exhaustive() && !adt.did.is_local() && !etc { span_err!(tcx.sess, span, E0638, diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs new file mode 100644 index 0000000000000..2469f24534543 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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. + +struct S(usize, usize, usize, usize); + +fn main() { + if let S { a, b, c, d } = S(1, 2, 3, 4) { + println!("hi"); + } +} From 97b3bf99f667736c3220a91b72a587eafe4cda49 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:31:04 -0500 Subject: [PATCH 12/37] Stabilize termination_trait This stabilizes `main` with non-() return types; see #48453. --- src/librustc_typeck/check/mod.rs | 35 +++++++++---------- src/librustc_typeck/lib.rs | 3 +- src/libstd/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 5 ++- .../termination-trait-main-i32.rs} | 3 +- .../termination-trait-main-wrong-type.rs | 1 - .../termination-trait-not-satisfied.rs | 2 -- .../termination-trait-for-never.rs | 2 -- ...mination-trait-for-result-box-error_err.rs | 2 -- .../termination-trait-for-empty.rs | 2 -- .../termination-trait-for-exitcode.rs | 1 - ...rmination-trait-for-result-box-error_ok.rs | 2 -- .../termination-trait-for-result.rs | 2 -- 13 files changed, 22 insertions(+), 40 deletions(-) rename src/test/compile-fail/{feature-gate-termination_trait.rs => rfc-1937-termination-trait/termination-trait-main-i32.rs} (82%) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4a685cfddb7a4..42bf516a0afa5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1106,25 +1106,22 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } fcx.demand_suptype(span, ret_ty, actual_return_ty); - if fcx.tcx.features().termination_trait { - // If the termination trait language item is activated, check that the main return type - // implements the termination trait. - if let Some(term_id) = fcx.tcx.lang_items().termination() { - if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { - if id == fn_id { - match fcx.sess().entry_type.get() { - Some(config::EntryMain) => { - let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); - let trait_ref = ty::TraitRef::new(term_id, substs); - let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); - - inherited.register_predicate( - traits::Obligation::new( - cause, param_env, trait_ref.to_predicate())); - }, - _ => {}, - } + // Check that the main return type implements the termination trait. + if let Some(term_id) = fcx.tcx.lang_items().termination() { + if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { + if id == fn_id { + match fcx.sess().entry_type.get() { + Some(config::EntryMain) => { + let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); + let trait_ref = ty::TraitRef::new(term_id, substs); + let cause = traits::ObligationCause::new( + span, fn_id, ObligationCauseCode::MainFunctionType); + + inherited.register_predicate( + traits::Obligation::new( + cause, param_env, trait_ref.to_predicate())); + }, + _ => {}, } } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 964c0021133aa..8089014044211 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -208,8 +208,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let actual = tcx.fn_sig(main_def_id); - let expected_return_type = if tcx.lang_items().termination().is_some() - && tcx.features().termination_trait { + let expected_return_type = if tcx.lang_items().termination().is_some() { // we take the return type of the given main function, the real check is done // in `check_fn` actual.output().skip_binder() diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a159..33da0e5788653 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -308,7 +308,6 @@ #![feature(str_char)] #![feature(str_internals)] #![feature(str_utf16)] -#![feature(termination_trait)] #![feature(test, rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] @@ -325,6 +324,7 @@ #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(used))] #![cfg_attr(stage0, feature(never_type))] +#![cfg_attr(stage0, feature(termination_trait))] #![default_lib_allocator] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0950965233f6a..781071b7f7f07 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -429,9 +429,6 @@ declare_features! ( // `foo.rs` as an alternative to `foo/mod.rs` (active, non_modrs_mods, "1.24.0", Some(44660), None), - // Termination trait in main (RFC 1937) - (active, termination_trait, "1.24.0", Some(43301), None), - // Termination trait in tests (RFC 1937) (active, termination_trait_test, "1.24.0", Some(48854), None), @@ -558,6 +555,8 @@ declare_features! ( (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/feature-gate-termination_trait.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs similarity index 82% rename from src/test/compile-fail/feature-gate-termination_trait.rs rename to src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 5a56445b64e57..ff2b32f3fd93b 100644 --- a/src/test/compile-fail/feature-gate-termination_trait.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() -> i32 { //~ ERROR main function has wrong type [E0580] +fn main() -> i32 { +//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 93e2561adf753..ea39ba92f4143 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] fn main() -> char { //~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index e87e0ceebf1b1..bab02fc559706 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - struct ReturnType {} fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs index c1dd44a91765e..863de85af88fb 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - // error-pattern:oh, dear fn main() -> ! { diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs index 8ce27c0a06250..0c6cb4de9567d 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs @@ -11,8 +11,6 @@ // must-compile-successfully // failure-status: 1 -#![feature(termination_trait)] - use std::io::{Error, ErrorKind}; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs index 5e534da012875..046d27a9f0fe5 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - fn main() {} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs index 80fa4d17b6116..4aa7d8c3a77d2 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] #![feature(process_exitcode_placeholder)] use std::process::ExitCode; diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs index 269ac451cf4d8..33686ed0b8fa2 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs index 751db0fb50082..1c87e31e763e9 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Error> { From e5a55e74405dedf8bc0744300a8c506eea94bc18 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:59:51 -0500 Subject: [PATCH 13/37] Stabilize termination_trait in 1.25, not 1.26 --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 781071b7f7f07..e71726bcebdc9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From 8236e431ce67f0cd32e0584a826586648842eaa3 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 19 Mar 2018 22:09:47 +0900 Subject: [PATCH 14/37] Document only-X test header --- src/test/COMPILER_TESTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index c255294e790b7..8553665c01797 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -54,6 +54,8 @@ be compiled or run. * `ignore-test` always ignores the test * `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger. +`only-X` is the opposite. The test will run only when `X` matches. + Some examples of `X` in `ignore-X`: * Architecture: `aarch64`, `arm`, `asmjs`, `mips`, `wasm32`, `x86_64`, `x86`, ... From f332a9ce5676859f0f07c4d6bf2d2c415be67066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:26:57 -0700 Subject: [PATCH 15/37] Single diagnostic for all non-mentioned fields in a pattern --- src/librustc_typeck/check/_match.rs | 22 ++++++++++++++----- .../ui/missing-fields-in-struct-pattern.rs | 2 ++ .../missing-fields-in-struct-pattern.stderr | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0b5383f1f8d1e..cc72a565ba28e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -993,13 +993,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); tcx.sess.span_err(span, "`..` cannot be used in union patterns"); } } else if !etc { - for field in variant.fields + let unmentioned_fields = variant.fields .iter() - .filter(|field| !used_fields.contains_key(&field.name)) { + .map(|field| field.name) + .filter(|field| !used_fields.contains_key(&field)) + .collect::>(); + if unmentioned_fields.len() > 0 { + let field_names = if unmentioned_fields.len() == 1 { + format!("field `{}`", unmentioned_fields[0]) + } else { + format!("fields {}", + unmentioned_fields.iter() + .map(|name| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; let mut diag = struct_span_err!(tcx.sess, span, E0027, - "pattern does not mention field `{}`", - field.name); - diag.span_label(span, format!("missing field `{}`", field.name)); + "pattern does not mention {}", + field_names); + diag.span_label(span, format!("missing {}", field_names)); if variant.ctor_kind == CtorKind::Fn { diag.note("trying to match a tuple variant with a struct variant pattern"); } diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 2469f24534543..28ed151b98606 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -12,6 +12,8 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { + //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] + //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr new file mode 100644 index 0000000000000..88fba19d14e35 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -0,0 +1,22 @@ +error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` + --> $DIR/missing-fields-in-struct-pattern.rs:14:16 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^ ^ ^ ^ struct `S` does not have field `d` + | | | | + | | | struct `S` does not have field `c` + | | struct `S` does not have field `b` + | struct `S` does not have field `a` + +error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` + --> $DIR/missing-fields-in-struct-pattern.rs:14:12 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3` + | + = note: trying to match a tuple variant with a struct variant pattern + +error: aborting due to 2 previous errors + +Some errors occurred: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. From 062a46fdd1d49b1ccdc4f713433521463224d7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Mar 2018 14:13:57 -0700 Subject: [PATCH 16/37] Reduce diagnostic verbosity by removing labels --- src/librustc_typeck/check/_match.rs | 17 +++++++++-------- .../compile-fail/struct-pat-derived-error.rs | 6 ++---- src/test/ui/error-codes/E0026-teach.stderr | 2 +- src/test/ui/error-codes/E0026.stderr | 2 +- src/test/ui/missing-fields-in-struct-pattern.rs | 2 +- .../ui/missing-fields-in-struct-pattern.stderr | 6 +----- src/test/ui/numeric-fields.stderr | 2 +- src/test/ui/type-check/issue-41314.stderr | 2 +- src/test/ui/union/union-fields-2.stderr | 2 +- 9 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cc72a565ba28e..7965806af5d09 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -938,14 +938,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } if inexistent_fields.len() > 0 { - let field_names = if inexistent_fields.len() == 1 { - format!("a field named `{}`", inexistent_fields[0].1) + let (field_names, t, plural) = if inexistent_fields.len() == 1 { + (format!("a field named `{}`", inexistent_fields[0].1), "this", "") } else { - format!("fields named {}", - inexistent_fields.iter() + (format!("fields named {}", + inexistent_fields.iter() .map(|(_, name)| format!("`{}`", name)) .collect::>() - .join(", ")) + .join(", ")), "these", "s") }; let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); let mut err = struct_span_err!(tcx.sess, @@ -955,12 +955,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); kind_name, tcx.item_path_str(variant.did), field_names); - for (span, name) in &inexistent_fields { + if let Some((span, _)) = inexistent_fields.last() { err.span_label(*span, - format!("{} `{}` does not have field `{}`", + format!("{} `{}` does not have {} field{}", kind_name, tcx.item_path_str(variant.did), - name)); + t, + plural)); } if tcx.sess.teach(&err.get_code().unwrap()) { err.note( diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs index f525ec373753d..d3130c4e831f6 100644 --- a/src/test/compile-fail/struct-pat-derived-error.rs +++ b/src/test/compile-fail/struct-pat-derived-error.rs @@ -16,10 +16,8 @@ struct a { impl a { fn foo(&self) { let a { x, y } = self.d; //~ ERROR no field `d` on type `&a` - //~^ ERROR struct `a` does not have a field named `x` - //~^^ ERROR struct `a` does not have a field named `y` - //~^^^ ERROR pattern does not mention field `b` - //~^^^^ ERROR pattern does not mention field `c` + //~^ ERROR struct `a` does not have fields named `x`, `y` + //~| ERROR pattern does not mention fields `b`, `c` } } diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr index 63d072fe03d0a..67ea32fba86d6 100644 --- a/src/test/ui/error-codes/E0026-teach.stderr +++ b/src/test/ui/error-codes/E0026-teach.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026-teach.rs:21:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field | = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr index af8519511276c..9dabbc8a775fb 100644 --- a/src/test/ui/error-codes/E0026.stderr +++ b/src/test/ui/error-codes/E0026.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026.rs:19:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field error: aborting due to previous error diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 28ed151b98606..dfde37994998b 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -13,7 +13,7 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] - //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] + //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr index 88fba19d14e35..d1c3260f11e30 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.stderr +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -2,11 +2,7 @@ error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` --> $DIR/missing-fields-in-struct-pattern.rs:14:16 | LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^ ^ ^ ^ struct `S` does not have field `d` - | | | | - | | | struct `S` does not have field `c` - | | struct `S` does not have field `b` - | struct `S` does not have field `a` + | ^ ^ ^ ^ struct `S` does not have these fields error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` --> $DIR/missing-fields-in-struct-pattern.rs:14:12 diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr index 607980ba3bf54..68a87da8ded32 100644 --- a/src/test/ui/numeric-fields.stderr +++ b/src/test/ui/numeric-fields.stderr @@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:17:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^^^^ struct `S` does not have field `0x1` + | ^^^^^^ struct `S` does not have this field error: aborting due to 2 previous errors diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index bcb0f9a99a779..f7d4bb9a02f45 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -2,7 +2,7 @@ error[E0026]: variant `X::Y` does not have a field named `number` --> $DIR/issue-41314.rs:17:16 | LL | X::Y { number } => {} //~ ERROR does not have a field named `number` - | ^^^^^^ variant `X::Y` does not have field `number` + | ^^^^^^ variant `X::Y` does not have this field error[E0027]: pattern does not mention field `0` --> $DIR/issue-41314.rs:17:9 diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index 3ea4d3426dad7..cfb5bc7520b59 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -52,7 +52,7 @@ error[E0026]: union `U` does not have a field named `c` --> $DIR/union-fields-2.rs:28:19 | LL | let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field - | ^ union `U` does not have field `c` + | ^ union `U` does not have this field error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:28:9 From be29e52c5a3d9da894a0292f9175106a955071c9 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:02:17 -0500 Subject: [PATCH 17/37] Match against friendly error message --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ff2b32f3fd93b..67ee39d10d91c 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` fn main() -> i32 { -//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index ea39ba92f4143..5f4ccf2b5862e 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `char fn main() -> char { -//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied ' ' } From 5ccf3ffab24a4237e467b884af6783b1af54bdd8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:06:46 -0500 Subject: [PATCH 18/37] diagnostics: Remove main return type errors from E0580 --- src/librustc/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b3a904f2f5fec..7627071e56037 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1764,12 +1764,12 @@ The `main` function was incorrectly declared. Erroneous code example: ```compile_fail,E0580 -fn main() -> i32 { // error: main function has wrong type - 0 +fn main(x: i32) { // error: main function has wrong type + println!("{}", x); } ``` -The `main` function prototype should never take arguments or return type. +The `main` function prototype should never take arguments. Example: ``` From 8c8a72f8224b9cbf283cd120d87397c032ed62f1 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:15:21 +0900 Subject: [PATCH 19/37] Reinit the stack guard on unexpected failure --- src/librustc_driver/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e39a2c2f5dcd9..e56c9928dccd6 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1480,9 +1480,9 @@ pub fn in_rustc_thread(f: F) -> Result> rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - // We have already deinited the stack. Further corruption is - // not allowed. - panic!("in_rustc_thread: error calling setrlimit: {}", err); + error!("in_rustc_thread: error calling setrlimit: {}", err); + std::rt::update_stack_guard(); + true } else { std::rt::update_stack_guard(); false From 2928c7a8a253b655132ac9f2beb4ca74540f0e14 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:22:45 +0900 Subject: [PATCH 20/37] Refactor the stack addr aligning code into a function --- src/libstd/sys/unix/thread.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index d94e11a5207cb..4364089a18184 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -284,10 +284,10 @@ pub mod guard { ret } - pub unsafe fn init() -> Option { - PAGE_SIZE = os::page_size(); - - let mut stackaddr = get_stack_start()?; + // Precondition: PAGE_SIZE is initialized. + unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { + assert!(PAGE_SIZE != 0); + let stackaddr = get_stack_start()?; // Ensure stackaddr is page aligned! A parent process might // have reset RLIMIT_STACK to be non-page aligned. The @@ -296,10 +296,17 @@ pub mod guard { // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } + Some(if remainder == 0 { + stackaddr + } else { + ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void + }) + } + + pub unsafe fn init() -> Option { + PAGE_SIZE = os::page_size(); + + let stackaddr = get_stack_start_aligned()?; if cfg!(target_os = "linux") { // Linux doesn't allocate the whole stack right away, and @@ -338,14 +345,7 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { - if let Some(mut stackaddr) = get_stack_start() { - // Ensure address is aligned. Same as above. - let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } - + if let Some(stackaddr) = get_stack_start_aligned() { // Undo the guard page mapping. if munmap(stackaddr, PAGE_SIZE) != 0 { panic!("unable to deallocate the guard page"); From df76629da77b58cd9a63d41b7bc1cc987dcc2bb8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 20 Mar 2018 17:14:33 +0100 Subject: [PATCH 21/37] Remove outdated comment --- src/librustc/ty/sty.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bb5c7b5fd2a5e..3fe310c54bfe1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1667,7 +1667,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub struct Const<'tcx> { pub ty: Ty<'tcx>, - // FIXME(eddyb) Replace this with a miri value. pub val: ConstVal<'tcx>, } From 3c8d55549728ec117fb6e3de93ce3d96fb6622d4 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:30:06 -0700 Subject: [PATCH 22/37] rename epoch to edition --- src/librustc/lint/context.rs | 12 ++--- src/librustc/lint/mod.rs | 20 ++++----- src/librustc/session/config.rs | 24 +++++----- src/librustc/session/mod.rs | 10 ++--- src/librustc_driver/driver.rs | 2 +- src/librustc_lint/lib.rs | 34 +++++++------- src/librustc_typeck/check/method/probe.rs | 2 +- src/libsyntax/config.rs | 6 +-- src/libsyntax/{epoch.rs => edition.rs} | 44 +++++++++---------- src/libsyntax/feature_gate.rs | 20 ++++----- src/libsyntax/lib.rs | 2 +- ....rs => edition-raw-pointer-method-2015.rs} | 4 +- ....rs => edition-raw-pointer-method-2018.rs} | 4 +- src/test/run-pass/dyn-trait.rs | 2 +- src/test/run-pass/epoch-gate-feature.rs | 2 +- ...ference-variable-behind-raw-pointer.stderr | 2 +- 16 files changed, 95 insertions(+), 95 deletions(-) rename src/libsyntax/{epoch.rs => edition.rs} (56%) rename src/test/compile-fail/{epoch-raw-pointer-method-2015.rs => edition-raw-pointer-method-2015.rs} (85%) rename src/test/compile-fail/{epoch-raw-pointer-method-2018.rs => edition-raw-pointer-method-2018.rs} (85%) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4fa6594df169c..936aa71f16cea 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -41,7 +41,7 @@ use util::nodemap::FxHashMap; use std::default::Default as StdDefault; use std::cell::{Ref, RefCell}; use syntax::ast; -use syntax::epoch; +use syntax::edition; use syntax_pos::{MultiSpan, Span}; use errors::DiagnosticBuilder; use hir; @@ -103,9 +103,9 @@ pub struct FutureIncompatibleInfo { pub id: LintId, /// e.g., a URL for an issue/PR/RFC or error code pub reference: &'static str, - /// If this is an epoch fixing lint, the epoch in which + /// If this is an edition fixing lint, the edition in which /// this lint becomes obsolete - pub epoch: Option, + pub edition: Option, } /// The target of the `by_name` map, which accounts for renaming/deprecation. @@ -201,11 +201,11 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for epoch in epoch::ALL_EPOCHS { - let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id) + for edition in edition::ALL_EPOCHS { + let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, epoch.lint_name(), lints) + self.register_group(sess, false, edition.lint_name(), lints) } } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7c103dc272109..cd038d067a1fd 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -42,7 +42,7 @@ use session::{Session, DiagnosticMessageId}; use std::hash; use syntax::ast; use syntax::codemap::MultiSpan; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::symbol::Symbol; use syntax::visit as ast_visit; use syntax_pos::Span; @@ -77,8 +77,8 @@ pub struct Lint { /// e.g. "imports that are never used" pub desc: &'static str, - /// Deny lint after this epoch - pub epoch_deny: Option, + /// Deny lint after this edition + pub edition_deny: Option, } impl Lint { @@ -88,8 +88,8 @@ impl Lint { } pub fn default_level(&self, session: &Session) -> Level { - if let Some(epoch_deny) = self.epoch_deny { - if session.epoch() >= epoch_deny { + if let Some(edition_deny) = self.edition_deny { + if session.edition() >= edition_deny { return Level::Deny } } @@ -100,12 +100,12 @@ impl Lint { /// Declare a static item of type `&'static Lint`. #[macro_export] macro_rules! declare_lint { - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $edition: expr) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: Some($epoch) + edition_deny: Some($edition) }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( @@ -113,7 +113,7 @@ macro_rules! declare_lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: None, + edition_deny: None, }; ); } @@ -499,8 +499,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, // Check for future incompatibility lints and issue a stronger warning. let lints = sess.lint_store.borrow(); if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) { - let future = if let Some(epoch) = future_incompatible.epoch { - format!("the {} epoch", epoch) + let future = if let Some(edition) = future_incompatible.edition { + format!("the {} edition", edition) } else { "a future release".to_owned() }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0d91074e946bd..4ba634f8b25cd 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -28,7 +28,7 @@ use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; use syntax::codemap::{FileName, FilePathMapping}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -771,7 +771,7 @@ macro_rules! options { Some("`string` or `string=string`"); pub const parse_lto: Option<&'static str> = Some("one of `thin`, `fat`, or omitted"); - pub const parse_epoch: Option<&'static str> = + pub const parse_edition: Option<&'static str> = Some("one of: `2015`, `2018`"); } @@ -780,7 +780,7 @@ macro_rules! options { use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; - use syntax::epoch::Epoch; + use syntax::edition::Edition; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -983,11 +983,11 @@ macro_rules! options { true } - fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool { + fn parse_edition(slot: &mut Edition, v: Option<&str>) -> bool { match v { Some(s) => { - let epoch = s.parse(); - if let Ok(parsed) = epoch { + let edition = s.parse(); + if let Ok(parsed) = edition { *slot = parsed; true } else { @@ -1280,10 +1280,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, `everybody_loops` (all function bodies replaced with `loop {}`), `hir` (the HIR), `hir,identified`, or `hir,typed` (HIR with types for each node)."), - epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED], - "The epoch to build Rust with. Newer epochs may include features - that require breaking changes. The default epoch is 2015 (the first - epoch). Crates compiled with different epochs can be linked together."), + edition: Edition = (Edition::Edition2015, parse_edition, [TRACKED], + "The edition to build Rust with. Newer editions may include features + that require breaking changes. The default edition is 2015 (the first + edition). Crates compiled with different editions can be linked together."), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], @@ -2258,7 +2258,7 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{CrateType, DebugInfoLevel, Epoch, ErrorOutputType, Lto, OptLevel, OutputTypes, + use super::{CrateType, DebugInfoLevel, Edition, ErrorOutputType, Lto, OptLevel, OutputTypes, Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2320,7 +2320,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Epoch); + impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3f52ecfc0999b..556255e06ed00 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -31,7 +31,7 @@ use rustc_data_structures::sync::{Lrc, Lock}; use syntax::ast::NodeId; use errors::{self, DiagnosticBuilder, DiagnosticId}; use errors::emitter::{Emitter, EmitterWriter}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::json::JsonEmitter; use syntax::feature_gate; use syntax::symbol::Symbol; @@ -976,13 +976,13 @@ impl Session { self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code) } - /// Are we allowed to use features from the Rust 2018 epoch? + /// Are we allowed to use features from the Rust 2018 edition? pub fn rust_2018(&self) -> bool { - self.opts.debugging_opts.epoch >= Epoch::Epoch2018 + self.opts.debugging_opts.edition >= Edition::Edition2018 } - pub fn epoch(&self) -> Epoch { - self.opts.debugging_opts.epoch + pub fn edition(&self) -> Edition { + self.opts.debugging_opts.edition } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f2fe6542db171..a3115544f30b9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -648,7 +648,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, { let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test, - sess.opts.debugging_opts.epoch); + sess.opts.debugging_opts.edition); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ce896bfb701ba..59d2d3e8fdc07 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -48,7 +48,7 @@ use rustc::session; use rustc::util; use session::Session; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -197,82 +197,82 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), reference: "issue #35203 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), reference: "issue #36887 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), reference: "issue #37872 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_IMPORTS), reference: "issue #38260 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), reference: "issue #39207 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), reference: "issue #41620 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ANONYMOUS_PARAMETERS), reference: "issue #41686 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), reference: "issue #42238 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), reference: "issue #42868 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_PACKED_BORROWS), reference: "issue #46043 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS), reference: "issue #46205 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(TYVAR_BEHIND_RAW_POINTER), reference: "issue #46906 ", - epoch: Some(Epoch::Epoch2018), + edition: Some(Edition::Edition2018), } ]); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4d344eb279903..c7921d2bd4588 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -326,7 +326,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if reached_raw_pointer && !self.tcx.features().arbitrary_self_types { // this case used to be allowed by the compiler, - // so we do a future-compat lint here for the 2015 epoch + // so we do a future-compat lint here for the 2015 edition // (see https://github.com/rust-lang/rust/issues/46906) if self.tcx.sess.rust_2018() { span_err!(self.tcx.sess, span, E0908, diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 6013c20daf235..56b1306e5b33f 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -13,7 +13,7 @@ use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features use {fold, attr}; use ast; use codemap::Spanned; -use epoch::Epoch; +use edition::Edition; use parse::{token, ParseSess}; use ptr::P; @@ -27,7 +27,7 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch) +pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, edition: Edition) -> (ast::Crate, Features) { let features; { @@ -47,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoc return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, epoch); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/epoch.rs b/src/libsyntax/edition.rs similarity index 56% rename from src/libsyntax/epoch.rs rename to src/libsyntax/edition.rs index 32cbc79c550e3..12ac6410ce193 100644 --- a/src/libsyntax/epoch.rs +++ b/src/libsyntax/edition.rs @@ -11,58 +11,58 @@ use std::fmt; use std::str::FromStr; -/// The epoch of the compiler (RFC 2052) +/// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)] #[non_exhaustive] -pub enum Epoch { - // epochs must be kept in order, newest to oldest +pub enum Edition { + // editions must be kept in order, newest to oldest - /// The 2015 epoch - Epoch2015, - /// The 2018 epoch - Epoch2018, + /// The 2015 edition + Edition2015, + /// The 2018 edition + Edition2018, - // when adding new epochs, be sure to update: + // when adding new editions, be sure to update: // - // - the list in the `parse_epoch` static in librustc::session::config + // - the list in the `parse_edition` static in librustc::session::config // - add a `rust_####()` function to the session // - update the enum in Cargo's sources as well // - // When -Zepoch becomes --epoch, there will - // also be a check for the epoch being nightly-only + // When -Zedition becomes --edition, there will + // also be a check for the edition being nightly-only // somewhere. That will need to be updated - // whenever we're stabilizing/introducing a new epoch + // whenever we're stabilizing/introducing a new edition // as well as changing the default Cargo template. } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018]; +pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; -impl fmt::Display for Epoch { +impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { - Epoch::Epoch2015 => "2015", - Epoch::Epoch2018 => "2018", + Edition::Edition2015 => "2015", + Edition::Edition2018 => "2018", }; write!(f, "{}", s) } } -impl Epoch { +impl Edition { pub fn lint_name(&self) -> &'static str { match *self { - Epoch::Epoch2015 => "epoch_2015", - Epoch::Epoch2018 => "epoch_2018", + Edition::Edition2015 => "edition_2015", + Edition::Edition2018 => "edition_2018", } } } -impl FromStr for Epoch { +impl FromStr for Edition { type Err = (); fn from_str(s: &str) -> Result { match s { - "2015" => Ok(Epoch::Epoch2015), - "2018" => Ok(Epoch::Epoch2018), + "2015" => Ok(Edition::Edition2015), + "2018" => Ok(Edition::Edition2018), _ => Err(()) } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 915396d29fe26..8feb8d6a4020d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,7 +28,7 @@ use self::AttributeGate::*; use abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; -use epoch::Epoch; +use edition::Edition; use codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; @@ -55,13 +55,13 @@ macro_rules! set { } macro_rules! declare_features { - ($((active, $feature: ident, $ver: expr, $issue: expr, $epoch: expr),)+) => { + ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => { /// Represents active features that are currently being implemented or /// currently being considered for addition/removal. const ACTIVE_FEATURES: &'static [(&'static str, &'static str, Option, - Option, fn(&mut Features, Span))] = - &[$((stringify!($feature), $ver, $issue, $epoch, set!($feature))),+]; + Option, fn(&mut Features, Span))] = + &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+]; /// A set of features to be used by later passes. #[derive(Clone)] @@ -402,7 +402,7 @@ declare_features! ( (active, match_default_bindings, "1.22.0", Some(42640), None), // Trait object syntax with `dyn` prefix - (active, dyn_trait, "1.22.0", Some(44662), Some(Epoch::Epoch2018)), + (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), // `crate` as visibility modifier, synonymous to `pub(crate)` (active, crate_visibility_modifier, "1.23.0", Some(45388), None), @@ -1800,16 +1800,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - epoch: Epoch) -> Features { + edition: Edition) -> Features { let mut features = Features::new(); let mut feature_checker = FeatureChecker::default(); - for &(.., f_epoch, set) in ACTIVE_FEATURES.iter() { - if let Some(f_epoch) = f_epoch { - if epoch >= f_epoch { + for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { + if let Some(f_edition) = f_edition { + if edition >= f_edition { // FIXME(Manishearth) there is currently no way to set - // lang features by epoch + // lang features by edition set(&mut features, DUMMY_SP); } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 5f58b3bc3a050..74f1ee373ec63 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -145,7 +145,7 @@ pub mod codemap; #[macro_use] pub mod config; pub mod entry; -pub mod epoch; +pub mod edition; pub mod feature_gate; pub mod fold; pub mod parse; diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/edition-raw-pointer-method-2015.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2015.rs rename to src/test/compile-fail/edition-raw-pointer-method-2015.rs index 6aa83a38b7ee9..fdc9b4f704cd1 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2015.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2015 -Zunstable-options +// compile-flags: -Zedition=2015 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2018.rs rename to src/test/compile-fail/edition-raw-pointer-method-2018.rs index c4815de2306e9..58b34591029ba 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2018 -Zunstable-options +// compile-flags: -Zedition=2018 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs index fdec6a26ac945..399823ec92d0c 100644 --- a/src/test/run-pass/dyn-trait.rs +++ b/src/test/run-pass/dyn-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty `dyn ::foo` parses differently in the current epoch +// ignore-pretty `dyn ::foo` parses differently in the current edition #![feature(dyn_trait)] diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs index 37d092c06e02b..f3d8f216e1132 100644 --- a/src/test/run-pass/epoch-gate-feature.rs +++ b/src/test/run-pass/epoch-gate-feature.rs @@ -11,7 +11,7 @@ // Checks if the correct registers are being used to pass arguments // when the sysv64 ABI is specified. -// compile-flags: -Zepoch=2018 +// compile-flags: -Zedition=2018 pub trait Foo {} diff --git a/src/test/ui/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference-variable-behind-raw-pointer.stderr index eb40151615dad..fe6dc0b07482f 100644 --- a/src/test/ui/inference-variable-behind-raw-pointer.stderr +++ b/src/test/ui/inference-variable-behind-raw-pointer.stderr @@ -5,6 +5,6 @@ LL | if data.is_null() {} | ^^^^^^^ | = note: #[warn(tyvar_behind_raw_pointer)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 epoch! + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 From 11f14060a4da7776c5f56e7dc53cc9545e4ab25f Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:56:13 -0700 Subject: [PATCH 23/37] change all appropriate EPOCH to EDITION --- src/librustc/lint/context.rs | 2 +- src/libsyntax/edition.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 936aa71f16cea..3c833251f72a7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -201,7 +201,7 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for edition in edition::ALL_EPOCHS { + for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index 12ac6410ce193..61246d4493ca3 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -36,7 +36,7 @@ pub enum Edition { } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 72334fee6fad3c51a036d7f592915ea472959714 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 14:19:16 -0500 Subject: [PATCH 24/37] typeck: Report main return type errors on return type span --- src/librustc_typeck/check/mod.rs | 3 ++- .../termination-trait-main-wrong-type.rs | 3 +-- .../termination-trait-main-wrong-type.stderr | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) rename src/test/{compile-fail => ui}/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs (80%) create mode 100644 src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 42bf516a0afa5..a951fa7eb220e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1114,8 +1114,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, Some(config::EntryMain) => { let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); let trait_ref = ty::TraitRef::new(term_id, substs); + let return_ty_span = decl.output.span(); let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); + return_ty_span, fn_id, ObligationCauseCode::MainFunctionType); inherited.register_predicate( traits::Obligation::new( diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs similarity index 80% rename from src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs rename to src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 5f4ccf2b5862e..425f51ca2fb54 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `char -fn main() -> char { +fn main() -> char { //~ ERROR ' ' } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr new file mode 100644 index 0000000000000..d09aac3ac2f27 --- /dev/null +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `char: std::process::Termination` is not satisfied + --> $DIR/termination-trait-main-wrong-type.rs:11:14 + | +LL | fn main() -> char { //~ ERROR + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | + = help: the trait `std::process::Termination` is not implemented for `char` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 1937661961fa54aa2bce8c301d85536916224a74 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 22:45:35 -0500 Subject: [PATCH 25/37] Revert "Stabilize termination_trait in 1.25, not 1.26" This reverts commit e5a55e74405dedf8bc0744300a8c506eea94bc18. --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e71726bcebdc9..781071b7f7f07 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From 94bdeb64f96b266d990ba7b76cd78a1e2ed1977f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 23:01:42 -0500 Subject: [PATCH 26/37] termination_trait: Add () example to error message --- src/libstd/process.rs | 2 +- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831f..a6aa3502f26bb 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] + "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 67ee39d10d91c..ffff33da581bf 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` +// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index d09aac3ac2f27..24371c27742d2 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` | = help: the trait `std::process::Termination` is not implemented for `char` From 2cdc7af41366182259a05435e325d7444653a3e8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 00:24:06 -0500 Subject: [PATCH 27/37] Use NOTE instead of error-pattern directive --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ffff33da581bf..053d6bbf93a2d 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { +//~^ ERROR `i32: std::process::Termination` is not satisfied +//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` 0 } From b6934c91b23517c4e17d8016b6c46ffd0703eded Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 13:32:46 -0500 Subject: [PATCH 28/37] termination_trait: Put examples in error help, not label --- src/librustc/traits/error_reporting.rs | 23 +++++++++++-------- src/libstd/process.rs | 2 +- .../termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7e5dc02798dff..8572c4077142b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,20 +585,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); + let explanation = match obligation.cause.code { + ObligationCauseCode::MainFunctionType => { + "consider using `()`, or a `Result`".to_owned() + } + _ => { + format!("{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref, + trait_ref.self_ty()) + } + }; + if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" // error message, let's display it as the label! err.span_label(span, s.as_str()); - err.help(&format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.help(&explanation); } else { - err.span_label(span, - &*format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.span_label(span, explanation); } if let Some(ref s) = note { // If it has a custom "#[rustc_on_unimplemented]" note, let's display it diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a6aa3502f26bb..d5ac2d19e831f 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] + "`main` can only return types that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 053d6bbf93a2d..2cf9fdcfb4dbd 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -10,6 +10,6 @@ fn main() -> i32 { //~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` +//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 24371c27742d2..211247757cbc1 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,9 +2,9 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` | - = help: the trait `std::process::Termination` is not implemented for `char` + = help: consider using `()`, or a `Result` error: aborting due to previous error From 178652a2988d9ecd478a4116237e1d7ea6b777f7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:06:38 +0000 Subject: [PATCH 29/37] Add support to rustbuild for a 'rustc docs' component tarball --- src/bootstrap/builder.rs | 12 ++-- src/bootstrap/dist.rs | 69 +++++++++++++++++--- src/bootstrap/doc.rs | 133 ++++++++++++++++++++++++++++++--------- src/bootstrap/lib.rs | 5 ++ 4 files changed, 178 insertions(+), 41 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437eef..9f779da6f65b3 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -316,11 +316,13 @@ impl<'a> Builder<'a> { test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, - doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, - doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook), - Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts, - dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo, - dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign), + doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc, + doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample, + doc::CargoBook), + Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc, + dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src, + dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended, + dist::HashSign), Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls, install::Rustfmt, install::Analysis, install::Src, install::Rustc), } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dcb572416594e..e25a7e1852586 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -102,7 +102,7 @@ impl Step for Docs { let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); - let src = build.out.join(host).join("doc"); + let src = build.doc_out(host); cp_r(&src, &dst); let mut cmd = rust_installer(builder); @@ -120,14 +120,69 @@ impl Step for Docs { build.run(&mut cmd); t!(fs::remove_dir_all(&image)); - // As part of this step, *also* copy the docs directory to a directory which - // buildbot typically uploads. - if host == build.build { - let dst = distdir(build).join("doc").join(build.rust_package_vers()); - t!(fs::create_dir_all(&dst)); - cp_r(&src, &dst); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustcDocs { + pub stage: u32, + pub host: Interned, +} + +impl Step for RustcDocs { + type Output = PathBuf; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("src/librustc") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(RustcDocs { + stage: run.builder.top_stage, + host: run.target, + }); + } + + /// Builds the `rustc-docs` installer component. + fn run(self, builder: &Builder) -> PathBuf { + let build = builder.build; + let host = self.host; + + let name = pkgname(build, "rustc-docs"); + + println!("Dist compiler docs ({})", host); + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return distdir(build).join(format!("{}-{}.tar.gz", name, host)); } + builder.default_doc(None); + + let image = tmpdir(build).join(format!("{}-{}-image", name, host)); + let _ = fs::remove_dir_all(&image); + + let dst = image.join("share/doc/rustc/html"); + t!(fs::create_dir_all(&dst)); + let src = build.compiler_doc_out(host); + cp_r(&src, &dst); + + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rustc-Documentation") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rustc-documentation-is-installed.") + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rustc-docs") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--bulk-dirs=share/doc/rustc/html"); + build.run(&mut cmd); + t!(fs::remove_dir_all(&image)); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) } } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5bc582b3507bb..ca45adb4649af 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -483,21 +483,17 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc"); compile::std_cargo(builder, &compiler, target, &mut cargo); - // We don't want to build docs for internal std dependencies unless - // in compiler-docs mode. When not in that mode, we whitelist the crates - // for which docs must be built. - if !build.config.compiler_docs { - cargo.arg("--no-deps"); - for krate in &["alloc", "core", "std", "std_unicode"] { - cargo.arg("-p").arg(krate); - // Create all crate output directories first to make sure rustdoc uses - // relative links. - // FIXME: Cargo should probably do this itself. - t!(fs::create_dir_all(out_dir.join(krate))); - } + // Keep a whitelist so we do not build internal stdlib crates, these will be + // build by the rustc step later if enabled. + cargo.arg("--no-deps"); + for krate in &["alloc", "core", "std", "std_unicode"] { + cargo.arg("-p").arg(krate); + // Create all crate output directories first to make sure rustdoc uses + // relative links. + // FIXME: Cargo should probably do this itself. + t!(fs::create_dir_all(out_dir.join(krate))); } - build.run(&mut cargo); cp_r(&my_out, &out); } @@ -563,6 +559,81 @@ impl Step for Test { } } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct WhitelistedRustc { + stage: u32, + target: Interned, +} + +impl Step for WhitelistedRustc { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + let builder = run.builder; + run.krate("rustc-main").default_condition(builder.build.config.docs) + } + + fn make_run(run: RunConfig) { + run.builder.ensure(WhitelistedRustc { + stage: run.builder.top_stage, + target: run.target, + }); + } + + /// Generate whitelisted compiler crate documentation. + /// + /// This will generate all documentation for crates that are whitelisted + /// to be included in the standard documentation. This documentation is + /// included in the standard Rust documentation, so we should always + /// document it and symlink to merge with the rest of the std and test + /// documentation. We don't build other compiler documentation + /// here as we want to be able to keep it separate from the standard + /// documentation. This is largely just a wrapper around `cargo doc`. + fn run(self, builder: &Builder) { + let build = builder.build; + let stage = self.stage; + let target = self.target; + println!("Documenting stage{} whitelisted compiler ({})", stage, target); + let out = build.doc_out(target); + t!(fs::create_dir_all(&out)); + let compiler = builder.compiler(stage, build.build); + let rustdoc = builder.rustdoc(compiler.host); + let compiler = if build.force_use_stage1(compiler, target) { + builder.compiler(1, compiler.host) + } else { + compiler + }; + + // Build libstd docs so that we generate relative links + builder.ensure(Std { stage, target }); + + builder.ensure(compile::Rustc { compiler, target }); + let out_dir = build.stage_out(compiler, Mode::Librustc) + .join(target).join("doc"); + + // See docs in std above for why we symlink + let my_out = build.crate_doc_out(target); + build.clear_if_dirty(&my_out, &rustdoc); + t!(symlink_dir_force(&my_out, &out_dir)); + + let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); + compile::rustc_cargo(build, &mut cargo); + + // We don't want to build docs for internal compiler dependencies in this + // step (there is another step for that). Therefore, we whitelist the crates + // for which docs must be built. + cargo.arg("--no-deps"); + for krate in &["proc_macro"] { + cargo.arg("-p").arg(krate); + } + + build.run(&mut cargo); + cp_r(&my_out, &out); + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustc { stage: u32, @@ -586,16 +657,18 @@ impl Step for Rustc { }); } - /// Generate all compiler documentation. + /// Generate compiler documentation. /// - /// This will generate all documentation for the compiler libraries and their - /// dependencies. This is largely just a wrapper around `cargo doc`. + /// This will generate all documentation for compiler and dependencies. + /// Compiler documentation is distributed separately, so we make sure + /// we do not merge it with the other documentation from std, test and + /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder) { let build = builder.build; let stage = self.stage; let target = self.target; println!("Documenting stage{} compiler ({})", stage, target); - let out = build.doc_out(target); + let out = build.compiler_doc_out(target); t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, build.build); let rustdoc = builder.rustdoc(compiler.host); @@ -605,6 +678,11 @@ impl Step for Rustc { compiler }; + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return; + } + // Build libstd docs so that we generate relative links builder.ensure(Std { stage, target }); @@ -613,6 +691,12 @@ impl Step for Rustc { .join(target).join("doc"); // See docs in std above for why we symlink + // + // This step must happen after other documentation steps. This + // invariant ensures that compiler documentation is not included + // in the standard documentation tarballs but that all the + // documentation from the standard documentation tarballs is included + // in the compiler documentation tarball. let my_out = build.crate_doc_out(target); build.clear_if_dirty(&my_out, &rustdoc); t!(symlink_dir_force(&my_out, &out_dir)); @@ -620,18 +704,9 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - if build.config.compiler_docs { - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); - } else { - // Like with libstd above if compiler docs aren't enabled then we're not - // documenting internal dependencies, so we have a whitelist. - cargo.arg("--no-deps"); - for krate in &["proc_macro"] { - cargo.arg("-p").arg(krate); - } - } + // src/rustc/Cargo.toml contains a bin crate called rustc which + // would otherwise overwrite the docs for the real rustc lib crate. + cargo.arg("-p").arg("rustc_driver"); build.run(&mut cargo); cp_r(&my_out, &out); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b778ba33d89cc..b2c8ac24d72d8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -511,6 +511,11 @@ impl Build { self.out.join(&*target).join("doc") } + /// Output directory for all documentation for a target + fn compiler_doc_out(&self, target: Interned) -> PathBuf { + self.out.join(&*target).join("compiler-doc") + } + /// Output directory for some generated md crate documentation for a target (temporary) fn md_doc_out(&self, target: Interned) -> Interned { INTERNER.intern_path(self.out.join(&*target).join("md-doc")) From 1392179cdc9c96e75353771959c246553b918d57 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:07:16 +0000 Subject: [PATCH 30/37] Configure the dist-x86_64-linux builder to produce compiler documentation --- src/ci/docker/dist-x86_64-linux/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index 3b98b0aa926bd..28c97e8c6dbf9 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -84,7 +84,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-sanitizers \ - --enable-profiler + --enable-profiler \ + --enable-compiler-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs From 2b13d95da02d318c12814261dd36edd91ae6879e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 23:28:48 -0500 Subject: [PATCH 31/37] termination_trait: Make error message more helpful --- src/librustc/traits/error_reporting.rs | 16 +++++++--------- src/libstd/process.rs | 5 +++-- .../termination-trait-main-i32.rs | 5 +++-- .../termination-trait-not-satisfied.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8572c4077142b..47e6b0feceae3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,17 +585,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); - let explanation = match obligation.cause.code { - ObligationCauseCode::MainFunctionType => { + let explanation = + if obligation.cause.code == ObligationCauseCode::MainFunctionType { "consider using `()`, or a `Result`".to_owned() - } - _ => { + } else { format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty()) - } - }; + pre_message, + trait_ref, + trait_ref.self_ty()) + }; if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831f..c877bf6aa35cd 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1442,8 +1442,9 @@ pub fn id() -> u32 { /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] -#[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] +#[rustc_on_unimplemented( + message="`main` has invalid return type `{Self}`", + label="`main` can only return types that implement {Termination}")] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 2cf9fdcfb4dbd..0e6ddf7c92f1a 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -9,7 +9,8 @@ // except according to those terms. fn main() -> i32 { -//~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` +//~^ ERROR `main` has invalid return type `i32` +//~| NOTE `main` can only return types that implement std::process::Termination +//~| HELP consider using `()`, or a `Result` 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index bab02fc559706..b5f5472b49290 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -10,6 +10,6 @@ struct ReturnType {} -fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied +fn main() -> ReturnType { //~ ERROR `main` has invalid return type `ReturnType` ReturnType {} } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 211247757cbc1..5109d9275c58b 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `char: std::process::Termination` is not satisfied +error[E0277]: `main` has invalid return type `char` --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination | = help: consider using `()`, or a `Result` From b48a26cdd1d086a3ca7ffae35b73b72f9ce85b8f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 09:56:04 +0100 Subject: [PATCH 32/37] Produce nice array lengths on a best effort basis --- src/librustc/traits/error_reporting.rs | 16 ++++++++++--- src/librustc/util/ppaux.rs | 4 ++-- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 2 +- .../ui/unevaluated_fixed_size_array_len.rs | 23 +++++++++++++++++++ .../unevaluated_fixed_size_array_len.stderr | 17 ++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.rs create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ab3c619dcdcd0..79d5cf7935941 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -443,10 +443,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { 4 }; + + let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }); + err.help(&format!("the following implementations were found:{}{}", - &impl_candidates[0..end].iter().map(|candidate| { - format!("\n {:?}", candidate) - }).collect::(), + &impl_candidates[0..end].iter().map(normalize).collect::(), if impl_candidates.len() > 5 { format!("\nand {} others", impl_candidates.len() - 4) } else { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2c3ee1ec285a9..056f1278c47c7 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1177,8 +1177,8 @@ define_print! { ConstVal::Value(Value::ByVal(PrimVal::Bytes(sz))) => { write!(f, "{}", sz)?; } - ConstVal::Unevaluated(_def_id, substs) => { - write!(f, "", &substs[..])?; + ConstVal::Unevaluated(_def_id, _substs) => { + write!(f, "_")?; } _ => { write!(f, "{:?}", sz)?; diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 45dce3d8740d1..169a12ef92e98 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -46,7 +46,7 @@ error[E0223]: ambiguous associated type LL | type A = [u8; 4]::AssocTy; | ^^^^^^^^^^^^^^^^ ambiguous associated type | - = note: specify the type using the syntax `<[u8; ] as Trait>::AssocTy` + = note: specify the type using the syntax `<[u8; _] as Trait>::AssocTy` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:15:10 diff --git a/src/test/ui/unevaluated_fixed_size_array_len.rs b/src/test/ui/unevaluated_fixed_size_array_len.rs new file mode 100644 index 0000000000000..a6ed9f32106fb --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.rs @@ -0,0 +1,23 @@ +// Copyright 2018 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. + +// https://github.com/rust-lang/rust/issues/49208 + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() //~ ERROR E0277 +} diff --git a/src/test/ui/unevaluated_fixed_size_array_len.stderr b/src/test/ui/unevaluated_fixed_size_array_len.stderr new file mode 100644 index 0000000000000..6e959da99397b --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied + --> $DIR/unevaluated_fixed_size_array_len.rs:22:5 + | +LL | <[(); 0] as Foo>::foo() //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` + | + = help: the following implementations were found: + <[(); 1] as Foo> +note: required by `Foo::foo` + --> $DIR/unevaluated_fixed_size_array_len.rs:14:5 + | +LL | fn foo(); + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 25c5b03aa58331e2d7c92c11dddd023b96d7fb98 Mon Sep 17 00:00:00 2001 From: Hidehito Yabuuchi Date: Thu, 22 Mar 2018 20:57:12 +0900 Subject: [PATCH 33/37] Better diagnostics for '..' pattern fragment not in the last position --- src/libsyntax/parse/parser.rs | 8 +++++++- src/test/ui/issue-49257.rs | 23 +++++++++++++++++++++++ src/test/ui/issue-49257.stderr | 21 +++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issue-49257.rs create mode 100644 src/test/ui/issue-49257.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6d8975197d55c..c471b2325f9dd 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3672,7 +3672,13 @@ impl<'a> Parser<'a> { if self.token != token::CloseDelim(token::Brace) { let token_str = self.this_token_to_string(); let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str)); - err.span_label(self.span, "expected `}`"); + if self.token == token::Comma { // Issue #49257 + err.span_label(self.span, + "`..` must be in the last position, \ + and cannot have a trailing comma"); + } else { + err.span_label(self.span, "expected `}`"); + } return Err(err); } etc = true; diff --git a/src/test/ui/issue-49257.rs b/src/test/ui/issue-49257.rs new file mode 100644 index 0000000000000..75b9e12684165 --- /dev/null +++ b/src/test/ui/issue-49257.rs @@ -0,0 +1,23 @@ +// Copyright 2018 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. + +// Test for #49257: +// emits good diagnostics for `..` pattern fragments not in the last position. + +#![allow(unused)] + +struct Point { x: u8, y: u8 } + +fn main() { + let p = Point { x: 0, y: 0 }; + let Point { .., y } = p; //~ ERROR expected `}`, found `,` + //~^ pattern does not mention field `x` + //~^^ pattern does not mention field `y` +} diff --git a/src/test/ui/issue-49257.stderr b/src/test/ui/issue-49257.stderr new file mode 100644 index 0000000000000..ecaf36520aec9 --- /dev/null +++ b/src/test/ui/issue-49257.stderr @@ -0,0 +1,21 @@ +error: expected `}`, found `,` + --> $DIR/issue-49257.rs:20:19 + | +LL | let Point { .., y } = p; //~ ERROR expected `}`, found `,` + | ^ `..` must be in the last position, and cannot have a trailing comma + +error[E0027]: pattern does not mention field `x` + --> $DIR/issue-49257.rs:20:9 + | +LL | let Point { .., y } = p; //~ ERROR expected `}`, found `,` + | ^^^^^^^^^^^^^^^ missing field `x` + +error[E0027]: pattern does not mention field `y` + --> $DIR/issue-49257.rs:20:9 + | +LL | let Point { .., y } = p; //~ ERROR expected `}`, found `,` + | ^^^^^^^^^^^^^^^ missing field `y` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0027`. From de1c929adaeb5b1e466b6f8485a9f7cf92969185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Thu, 22 Mar 2018 11:27:59 +0100 Subject: [PATCH 34/37] Use GNU version of fgrep/egrep tool if available It is mostly for BSD system. Some tests (run-make/issue-35164 and run-make/cat-and-grep-sanity-check) are failing with BSD fgrep, whereas they pass with gnu version (gfgrep). --- src/etc/cat-and-grep.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/etc/cat-and-grep.sh b/src/etc/cat-and-grep.sh index ef9884d2e980d..361e8d8e60eed 100755 --- a/src/etc/cat-and-grep.sh +++ b/src/etc/cat-and-grep.sh @@ -63,6 +63,11 @@ done shift $((OPTIND - 1)) +# use gnu version of tool if available (for bsd) +if command -v "g${GREPPER}"; then + GREPPER="g${GREPPER}" +fi + LOG=$(mktemp -t cgrep.XXXXXX) trap "rm -f $LOG" EXIT From 347b9d6b563f8f436a27fa5cfd10bc2e43cbb8b7 Mon Sep 17 00:00:00 2001 From: Hidehito Yabuuchi Date: Fri, 23 Mar 2018 01:15:27 +0900 Subject: [PATCH 35/37] Fix error annotations in test --- src/test/ui/issue-49257.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/issue-49257.rs b/src/test/ui/issue-49257.rs index 75b9e12684165..61883294594bc 100644 --- a/src/test/ui/issue-49257.rs +++ b/src/test/ui/issue-49257.rs @@ -18,6 +18,6 @@ struct Point { x: u8, y: u8 } fn main() { let p = Point { x: 0, y: 0 }; let Point { .., y } = p; //~ ERROR expected `}`, found `,` - //~^ pattern does not mention field `x` - //~^^ pattern does not mention field `y` + //~| ERROR pattern does not mention field `x` + //~| ERROR pattern does not mention field `y` } From 1b0e9f5af9283b003f5fce6f19ede145c1776684 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 14:57:28 +0000 Subject: [PATCH 36/37] Only generate documentation for local rustc crates. --- src/bootstrap/doc.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ca45adb4649af..e525bdb98fc0c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -17,12 +17,13 @@ //! Everything here is basically just a shim around calling either `rustbook` or //! `rustdoc`. +use std::collections::HashSet; use std::fs::{self, File}; use std::io::prelude::*; use std::io; use std::path::{PathBuf, Path}; -use Mode; +use {Build, Mode}; use build_helper::up_to_date; use util::{cp_r, symlink_dir}; @@ -704,15 +705,41 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); + // Only include compiler crates, no dependencies of those, such as `libc`. + cargo.arg("--no-deps"); + + // Find dependencies for top level crates. + let mut compiler_crates = HashSet::new(); + for root_crate in &["rustc", "rustc_driver"] { + let interned_root_crate = INTERNER.intern_str(root_crate); + find_compiler_crates(&build, &interned_root_crate, &mut compiler_crates); + } + + for krate in &compiler_crates { + cargo.arg("-p").arg(krate); + } build.run(&mut cargo); cp_r(&my_out, &out); } } +fn find_compiler_crates( + build: &Build, + name: &Interned, + crates: &mut HashSet> +) { + // Add current crate. + crates.insert(*name); + + // Look for dependencies. + for dep in build.crates.get(name).unwrap().deps.iter() { + if build.crates.get(dep).unwrap().is_local(build) { + find_compiler_crates(build, dep, crates); + } + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { target: Interned, From 73fa6d52ed99651940267affa941a1069cc20f35 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 20:49:05 +0000 Subject: [PATCH 37/37] Remove std/test documentation from compiler docs. --- src/bootstrap/dist.rs | 4 ++-- src/bootstrap/doc.rs | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e25a7e1852586..5563b153f5aff 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -163,7 +163,7 @@ impl Step for RustcDocs { let image = tmpdir(build).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); - let dst = image.join("share/doc/rustc/html"); + let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); let src = build.compiler_doc_out(host); cp_r(&src, &dst); @@ -179,7 +179,7 @@ impl Step for RustcDocs { .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rustc/html"); + .arg("--bulk-dirs=share/doc/rust/html"); build.run(&mut cmd); t!(fs::remove_dir_all(&image)); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index e525bdb98fc0c..44073a5b07572 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -690,17 +690,10 @@ impl Step for Rustc { builder.ensure(compile::Rustc { compiler, target }); let out_dir = build.stage_out(compiler, Mode::Librustc) .join(target).join("doc"); - - // See docs in std above for why we symlink - // - // This step must happen after other documentation steps. This - // invariant ensures that compiler documentation is not included - // in the standard documentation tarballs but that all the - // documentation from the standard documentation tarballs is included - // in the compiler documentation tarball. - let my_out = build.crate_doc_out(target); - build.clear_if_dirty(&my_out, &rustdoc); - t!(symlink_dir_force(&my_out, &out_dir)); + // We do not symlink to the same shared folder that already contains std library + // documentation from previous steps as we do not want to include that. + build.clear_if_dirty(&out, &rustdoc); + t!(symlink_dir_force(&out, &out_dir)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); @@ -720,7 +713,6 @@ impl Step for Rustc { } build.run(&mut cargo); - cp_r(&my_out, &out); } }