diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 500af5fc772f5..14bc19dffd5d0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -57,6 +57,8 @@ pub struct Session { pub crate_metadata: RefCell>, pub features: RefCell, + pub delayed_span_bug: RefCell>, + /// The maximum recursion limit for potentially infinitely recursive /// operations such as auto-dereference and monomorphization. pub recursion_limit: Cell, @@ -114,7 +116,15 @@ impl Session { self.diagnostic().handler().has_errors() } pub fn abort_if_errors(&self) { - self.diagnostic().handler().abort_if_errors() + self.diagnostic().handler().abort_if_errors(); + + let delayed_bug = self.delayed_span_bug.borrow(); + match *delayed_bug { + Some((span, ref errmsg)) => { + self.diagnostic().span_bug(span, errmsg); + }, + _ => {} + } } pub fn span_warn(&self, sp: Span, msg: &str) { if self.can_print_warnings { @@ -171,6 +181,11 @@ impl Session { None => self.bug(msg), } } + /// Delay a span_bug() call until abort_if_errors() + pub fn delay_span_bug(&self, sp: Span, msg: &str) { + let mut delayed = self.delayed_span_bug.borrow_mut(); + *delayed = Some((sp, msg.to_string())); + } pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.diagnostic().span_bug(sp, msg) } @@ -402,6 +417,7 @@ pub fn build_session_(sopts: config::Options, plugin_llvm_passes: RefCell::new(Vec::new()), crate_types: RefCell::new(Vec::new()), crate_metadata: RefCell::new(Vec::new()), + delayed_span_bug: RefCell::new(None), features: RefCell::new(feature_gate::Features::new()), recursion_limit: Cell::new(64), can_print_warnings: can_print_warnings diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 9554e6ad8aad3..3c8ad36138524 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -541,11 +541,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { } Err(..) => { let tcx = rcx.fcx.tcx(); - if tcx.sess.has_errors() { - // cannot run dropck; okay b/c in error state anyway. - } else { - tcx.sess.span_bug(expr.span, "cat_expr_unadjusted Errd"); - } + tcx.sess.delay_span_bug(expr.span, "cat_expr_unadjusted Errd"); } } } @@ -562,11 +558,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { } Err(..) => { let tcx = rcx.fcx.tcx(); - if tcx.sess.has_errors() { - // cannot run dropck; okay b/c in error state anyway. - } else { - tcx.sess.span_bug(expr.span, "cat_expr Errd"); - } + tcx.sess.delay_span_bug(expr.span, "cat_expr Errd"); } } diff --git a/src/test/compile-fail/issue-22897.rs b/src/test/compile-fail/issue-22897.rs new file mode 100644 index 0000000000000..c6bbf2d4abcc0 --- /dev/null +++ b/src/test/compile-fail/issue-22897.rs @@ -0,0 +1,19 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { } + +// Before these errors would ICE as "cat_expr Errd" because the errors +// were unknown when the bug was triggered. + +fn unconstrained_type() { + []; + //~^ ERROR cannot determine a type for this expression: unconstrained type +} diff --git a/src/test/compile-fail/issue-23041.rs b/src/test/compile-fail/issue-23041.rs new file mode 100644 index 0000000000000..68895759c5c2a --- /dev/null +++ b/src/test/compile-fail/issue-23041.rs @@ -0,0 +1,18 @@ +// Copyright 2015 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. + +use std::any::Any; +fn main() +{ + fn bar(x:i32) ->i32 { 3*x }; + let b:Box = Box::new(bar as fn(_)->_); + b.downcast_ref::_>(); + //~^ ERROR cannot determine a type for this expression: unconstrained type +} diff --git a/src/test/compile-fail/issue-23966.rs b/src/test/compile-fail/issue-23966.rs new file mode 100644 index 0000000000000..18b5136866521 --- /dev/null +++ b/src/test/compile-fail/issue-23966.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + "".chars().fold(|_, _| (), ()); + //~^ ERROR cannot determine a type for this expression: unconstrained type +} diff --git a/src/test/compile-fail/issue-24013.rs b/src/test/compile-fail/issue-24013.rs new file mode 100644 index 0000000000000..0adad8a88cbc9 --- /dev/null +++ b/src/test/compile-fail/issue-24013.rs @@ -0,0 +1,17 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + use std::mem::{transmute, swap}; + let a = 1; + let b = 2; + unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; + //~^ ERROR cannot determine a type for this expression: unconstrained type +}