use syntax::ptr::P;
use syntax_pos::Span;
use errors::DiagnosticBuilder;
+use util::common::ErrorReported;
use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
use rustc_back::slice;
pub fn krate(sess: &Session,
hir_map: &Map)
- -> Result<NamedRegionMap, usize> {
+ -> Result<NamedRegionMap, ErrorReported> {
let krate = hir_map.krate();
let mut map = NamedRegionMap {
defs: NodeMap(),
use session::config::DebugInfoLevel;
use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
-use util::common::duration_to_secs_str;
+use util::common::{duration_to_secs_str, ErrorReported};
use syntax::ast::NodeId;
use errors::{self, DiagnosticBuilder};
pub fn abort_if_errors(&self) {
self.diagnostic().abort_if_errors();
}
- pub fn track_errors<F, T>(&self, f: F) -> Result<T, usize>
+ pub fn compile_status(&self) -> Result<(), CompileIncomplete> {
+ compile_result_from_err_count(self.err_count())
+ }
+ pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorReported>
where F: FnOnce() -> T
{
let old_count = self.err_count();
if errors == 0 {
Ok(result)
} else {
- Err(errors)
+ Err(ErrorReported)
}
}
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
}
-// Err(0) means compilation was stopped, but no errors were found.
-// This would be better as a dedicated enum, but using try! is so convenient.
-pub type CompileResult = Result<(), usize>;
+#[derive(Copy, Clone, Debug)]
+pub enum CompileIncomplete {
+ Stopped,
+ Errored(ErrorReported)
+}
+impl From<ErrorReported> for CompileIncomplete {
+ fn from(err: ErrorReported) -> CompileIncomplete {
+ CompileIncomplete::Errored(err)
+ }
+}
+pub type CompileResult = Result<(), CompileIncomplete>;
pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
if err_count == 0 {
Ok(())
} else {
- Err(err_count)
+ Err(CompileIncomplete::Errored(ErrorReported))
}
}
use rustc::ich::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_mir as mir;
-use rustc::session::{Session, CompileResult, compile_result_from_err_count};
+use rustc::session::{Session, CompileResult};
+use rustc::session::CompileIncomplete;
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
OutputTypes};
use rustc::session::search_paths::PathKind;
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
use rustc::traits;
-use rustc::util::common::time;
+use rustc::util::common::{ErrorReported, time};
use rustc::util::nodemap::NodeSet;
use rustc::util::fs::rename_or_copy_remove;
use rustc_borrowck as borrowck;
}
if control.$point.stop == Compilation::Stop {
- return compile_result_from_err_count($tsess.err_count());
+ // FIXME: shouldn't this return Err(CompileIncomplete::Stopped)
+ // if there are no errors?
+ return $tsess.compile_status();
}
}}
}
Ok(krate) => krate,
Err(mut parse_error) => {
parse_error.emit();
- return Err(1);
+ return Err(CompileIncomplete::Errored(ErrorReported));
}
};
(control.after_analysis.callback)(&mut state);
if control.after_analysis.stop == Compilation::Stop {
- return result.and_then(|_| Err(0usize));
+ return result.and_then(|_| Err(CompileIncomplete::Stopped));
}
}
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
after_expand: F)
- -> Result<ExpansionResult, usize>
+ -> Result<ExpansionResult, CompileIncomplete>
where F: FnOnce(&ast::Crate) -> CompileResult,
{
let time_passes = sess.time_passes();
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
super::describe_lints(&sess.lint_store.borrow(), true);
- return Err(0);
+ return Err(CompileIncomplete::Stopped);
}
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
arenas: &'tcx GlobalArenas<'tcx>,
name: &str,
f: F)
- -> Result<R, usize>
+ -> Result<R, CompileIncomplete>
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
ty::CrateAnalysis,
IncrementalHashesMap,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
- return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
+ return Ok(f(tcx, analysis, incremental_hashes_map, sess.compile_status()));
}
analysis.reachable =
time(time_passes, "lint checking", || lint::check_crate(tcx));
- // The above three passes generate errors w/o aborting
- if sess.err_count() > 0 {
- return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
- }
-
- Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
+ return Ok(f(tcx, analysis, incremental_hashes_map, tcx.sess.compile_status()));
})
}
"serialize work products",
move || rustc_incremental::save_work_products(sess));
- if sess.err_count() > 0 {
- Err(sess.err_count())
- } else {
- Ok(())
- }
+ sess.compile_status()
}
/// Run the linker on any artifacts that resulted from the LLVM run.
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config, Session, build_session, CompileResult};
+use rustc::session::CompileIncomplete;
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::session::config::nightly_options;
use rustc::session::{early_error, early_warn};
use rustc::lint;
use rustc_metadata::locator;
use rustc_metadata::cstore::CStore;
-use rustc::util::common::time;
+use rustc::util::common::{time, ErrorReported};
use serialize::json::ToJson;
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
md#bug-reports";
-#[inline]
-fn abort_msg(err_count: usize) -> String {
- match err_count {
- 0 => "aborting with no errors (maybe a bug?)".to_owned(),
- 1 => "aborting due to previous error".to_owned(),
- e => format!("aborting due to {} previous errors", e),
- }
-}
-
-pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
+pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) -> T {
match result {
- Err(err_count) => {
- sess.fatal(&abort_msg(err_count));
+ Err(CompileIncomplete::Errored(ErrorReported)) => {
+ sess.abort_if_errors();
+ panic!("error reported but abort_if_errors didn't abort???");
+ }
+ Err(CompileIncomplete::Stopped) => {
+ sess.fatal("compilation terminated");
}
Ok(x) => x,
}
{
monitor(move || {
let (result, session) = run_compiler();
- if let Err(err_count) = result {
- if err_count > 0 {
- match session {
- Some(sess) => sess.fatal(&abort_msg(err_count)),
- None => {
- let emitter =
- errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
- let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
- handler.emit(&MultiSpan::new(),
- &abort_msg(err_count),
- errors::Level::Fatal);
- exit_on_err();
- }
+ if let Err(CompileIncomplete::Errored(_)) = result {
+ match session {
+ Some(sess) => {
+ sess.abort_if_errors();
+ panic!("error reported but abort_if_errors didn't abort???");
+ }
+ None => {
+ let emitter =
+ errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
+ let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
+ handler.emit(&MultiSpan::new(),
+ "aborting due to previous error(s)",
+ errors::Level::Fatal);
+ exit_on_err();
}
}
}
// recursively.
use rustc::hir::map as hir_map;
-use rustc::session::{CompileResult, Session};
+use rustc::session::Session;
use rustc::hir::def::{Def, CtorKind};
+use rustc::util::common::ErrorReported;
use rustc::util::nodemap::{NodeMap, NodeSet};
use syntax::ast;
}
}
-pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) -> CompileResult {
+pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>)
+ -> Result<(), ErrorReported>
+{
let mut visitor = CheckCrateVisitor {
sess: sess,
hir_map: hir_map,
use rustc::ty::util::{Representability, IntTypeExt};
use errors::DiagnosticBuilder;
use require_c_abi_if_variadic;
-use session::{Session, CompileResult};
+use session::{CompileIncomplete, Session};
use TypeAndSubsts;
use lint;
use util::common::{ErrorReported, indenter};
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
}
-pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
+pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
tcx.sess.track_errors(|| {
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
})
}
-pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
+pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
tcx.sess.track_errors(|| {
tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
})
}
-pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
+pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
tcx.typeck_item_bodies(LOCAL_CRATE)
}
-fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
+fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
+ -> Result<(), CompileIncomplete>
+{
debug_assert!(crate_num == LOCAL_CRATE);
- tcx.sess.track_errors(|| {
+ Ok(tcx.sess.track_errors(|| {
for body_owner_def_id in tcx.body_owners() {
tcx.typeck_tables_of(body_owner_def_id);
}
- })
+ })?)
}
pub fn provide(providers: &mut Providers) {
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
-use session::config;
+use session::{CompileIncomplete, config};
use util::common::time;
use syntax::ast;
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
- -> Result<(), usize> {
+ -> Result<(), CompileIncomplete>
+{
let time_passes = tcx.sess.time_passes();
// this ensures that later parts of type checking can assume that items
check_unused::check_crate(tcx);
check_for_entry_fn(tcx);
- let err_count = tcx.sess.err_count();
- if err_count == 0 {
- Ok(())
- } else {
- Err(err_count)
- }
+ tcx.sess.compile_status()
}
/// A quasi-deprecated helper used in rustdoc and save-analysis to get
use rustc::dep_graph::DepGraph;
use rustc::hir;
use rustc::hir::intravisit;
-use rustc::session::{self, config};
+use rustc::session::{self, CompileIncomplete, config};
use rustc::session::config::{OutputType, OutputTypes, Externs};
use rustc::session::search_paths::{SearchPaths, PathKind};
use rustc_back::dynamic_lib::DynamicLibrary;
driver::compile_input(&sess, &cstore, &input, &out, &None, None, &control)
}));
- match res {
- Ok(r) => {
- match r {
- Err(count) => {
- if count > 0 && !compile_fail {
- sess.fatal("aborting due to previous error(s)")
- } else if count == 0 && compile_fail {
- panic!("test compiled while it wasn't supposed to")
- }
- if count > 0 && error_codes.len() > 0 {
- let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
- error_codes.retain(|err| !out.contains(err));
- }
- }
- Ok(()) if compile_fail => {
- panic!("test compiled while it wasn't supposed to")
- }
- _ => {}
- }
+ let compile_result = match res {
+ Ok(Ok(())) | Ok(Err(CompileIncomplete::Stopped)) => Ok(()),
+ Err(_) | Ok(Err(CompileIncomplete::Errored(_))) => Err(())
+ };
+
+ match (compile_result, compile_fail) {
+ (Ok(()), true) => {
+ panic!("test compiled while it wasn't supposed to")
}
- Err(_) => {
- if !compile_fail {
- panic!("couldn't compile the test");
- }
+ (Ok(()), false) => {}
+ (Err(()), true) => {
if error_codes.len() > 0 {
let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
error_codes.retain(|err| !out.contains(err));
}
}
+ (Err(()), false) => {
+ panic!("couldn't compile the test")
+ }
}
if error_codes.len() > 0 {
let (result, _) = rustc_driver::run_compiler(
&args, &mut JitCalls, Some(box JitLoader), None);
if let Err(n) = result {
- panic!("Error {}", n);
+ panic!("Error {:?}", n);
}
}
= note: expected type `()`
found type `bool`
-error: aborting due to previous error(s)
+error: aborting due to previous error
= note: expected type `()`
found type `bool`
-error: aborting due to previous error(s)
+error: aborting due to previous error
= note: expected type `()`
found type `bool`
-error: aborting due to previous error(s)
+error: aborting due to previous error
= note: expected type `std::string::String`
found type `()`
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
= note: expected type `i32`
found type `()`
-error: aborting due to previous error(s)
+error: aborting due to previous error
= note: expected type `std::string::String`
found type `()`
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
= note: expected type `()`
found type `a::Enum`
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
17 | let x = foo(5)(2);
| ^^^^^^^^^
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
= note: expected type `()`
found type `Bob`
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
= note: expected type `()`
found type `[closure@$DIR/issue-3563.rs:13:9: 13:20 self:_]`
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
= note: expected type `()`
found type `&_`
-error: aborting due to previous error(s)
+error: aborting due to previous error
help: possibly return type missing here?
| fn bar() -> usize {
-error: aborting due to previous error(s)
+error: aborting due to previous error
15 | num += 1;
| ^^^
-error: aborting due to previous error(s)
+error: aborting due to previous error
15 | vec
| ^^^
-error: aborting due to previous error(s)
+error: aborting due to previous error
= note: expected type `std::result::Result<u8, u64>`
found type `()`
-error: aborting due to previous error
+error: aborting due to 2 previous errors
|
= note: method `xxx` has no receiver
-error: aborting due to previous error
+error: aborting due to 9 previous errors
|
= note: the trait cannot require that `Self : Sized`
-error: aborting due to previous error
+error: aborting due to 3 previous errors
= note: the following trait defines an item `foo`, perhaps you need to implement it:
candidate #1: `Foo`
-error: aborting due to previous error(s)
+error: aborting due to previous error
candidate #2: `core::slice::SliceExt`
candidate #3: `core::str::StrExt`
-error: aborting due to previous error(s)
+error: aborting due to previous error
131 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3();
| ^^^^^^^
-error: aborting due to previous error(s)
+error: aborting due to 24 previous errors
|
= note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
-error: aborting due to previous error(s)
+error: aborting due to 4 previous errors
= note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:15:18: 15:35 x:&std::cell::Cell<i32>]`
= note: required by `std::panic::catch_unwind`
-error: aborting due to previous error(s)
+error: aborting due to previous error
help: if you want to compare the casted value then write:
| println!("{}", (a as usize) < 4);
-error: aborting due to previous error(s)
+error: aborting due to 2 previous errors
note: ...which then requires computing layout of `<S as Mirror>::It`...
= note: ...which then again requires computing layout of `S`, completing the cycle.
-error: aborting due to previous error(s)
+error: aborting due to previous error
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ a;
+ "".lorem;
+ "".ipsum;
+}
--- /dev/null
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/issue-33525.rs:12:5
+ |
+12 | a;
+ | ^ not found in this scope
+
+error[E0609]: no field `lorem` on type `&'static str`
+ --> $DIR/issue-33525.rs:13:8
+ |
+13 | "".lorem;
+ | ^^^^^
+
+error[E0609]: no field `ipsum` on type `&'static str`
+ --> $DIR/issue-33525.rs:14:8
+ |
+14 | "".ipsum;
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
16 | let test_x = [0; issue_38875_b::FOO];
| ^^^^^^^^^^^^^^^^^^
-error: aborting due to previous error(s)
+error: aborting due to previous error
12 | if x > y { x } else { y }
| ^ lifetime `'a` required
-error: aborting due to previous error(s)
+error: aborting due to previous error
12 | if x > y { x } else { y }
| ^ lifetime `'a` required
-error: aborting due to previous error(s)
+error: aborting due to previous error
14 | if x > y { x } else { y }
| ^ lifetime `'a` required
-error: aborting due to previous error(s)
+error: aborting due to previous error
18 | if true { &self.field } else { x }
| ^ lifetime `'a` required
-error: aborting due to previous error(s)
+error: aborting due to previous error
23 | | }
| |_____^
-error: aborting due to previous error(s)
+error: aborting due to previous error
20 | | }
| |___^
-error: aborting due to previous error(s)
+error: aborting due to previous error
20 | | }
| |_____^
-error: aborting due to previous error(s)
+error: aborting due to previous error
16 | y.push(x);
| ^ lifetime `'a` required
-error: aborting due to previous error(s)
+error: aborting due to previous error
19 | #[allow(unused, unused_variables, bad_style)]
| ^^^^^^^^^ overruled by previous forbid
-error: aborting due to previous error(s)
+error: aborting due to 3 previous errors
|
= note: required by `foo`
-error: aborting due to 2 previous errors
+error: aborting due to previous error
= note: expected type `&{integer}`
found type `{integer}`
-error: aborting due to previous error
+error: aborting due to 2 previous errors
|
= help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
| |
| expected closure that takes 2 arguments
-error: aborting due to 7 previous errors
+error: aborting due to 4 previous errors
= note: expected type `()`
found type `{integer}`
-error: aborting due to previous error(s)
+error: aborting due to previous error
| requires `for<'r> std::ops::FnMut<(&'r &str,)>`
| expected &str, found str
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
|
= note: required by `call_it`
-error: aborting due to 2 previous errors
+error: aborting due to previous error
= note: `Type` from trait: `type Type;`
= note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
-error: aborting due to previous error
+error: aborting due to 2 previous errors
= note: expected type `()`
found type `std::result::Result<bool, std::io::Error>`
-error: aborting due to previous error
+error: aborting due to 5 previous errors
18 | fn shadow_in_method<T>(&self) {}
| ^ shadows another type parameter
-error: aborting due to previous error(s)
+error: aborting due to 3 previous errors
|
= note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
19 | bar(1, 2, 3);
| ^^^^^^^ expected 2 parameters
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
= note: source type: i32 (32 bits)
= note: target type: Foo (0 bits)
-error: aborting due to previous error(s)
+error: aborting due to 4 previous errors
= note: source type: std::option::Option<fn()> (64 bits)
= note: target type: u32 (32 bits)
-error: aborting due to previous error(s)
+error: aborting due to 11 previous errors
= note: source type: std::option::Option<T> (size can vary because of T)
= note: target type: i32 (32 bits)
-error: aborting due to previous error(s)
+error: aborting due to 6 previous errors
= note: expected type `bool`
found type `()`
-error: aborting due to previous error(s)
+error: aborting due to 5 previous errors