Skip to content

Commit

Permalink
Auto merge of #60125 - estebank:continue-evaluating, r=oli-obk
Browse files Browse the repository at this point in the history
Don't stop evaluating due to errors before borrow checking

r? @oli-obk

Fix #60005. Follow up to #59903. Blocked on #53708, fixing the ICE in `src/test/ui/consts/match_ice.rs`.
  • Loading branch information
bors committed Apr 23, 2019
2 parents 0f11354 + 87ef96d commit 31f5d69
Show file tree
Hide file tree
Showing 55 changed files with 449 additions and 125 deletions.
10 changes: 3 additions & 7 deletions src/librustc/traits/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

use crate::dep_graph::{DepKind, DepTrackingMapConfig};
use std::marker::PhantomData;
use syntax_pos::DUMMY_SP;
use crate::infer::InferCtxt;
use syntax_pos::Span;
use crate::traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext,
TraitEngine, Vtable};
use crate::ty::{self, Ty, TyCtxt};
Expand Down Expand Up @@ -69,7 +67,7 @@ pub fn codegen_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>,
debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate);
fulfill_cx.register_predicate_obligation(&infcx, predicate);
});
let vtable = infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &vtable);
let vtable = infcx.drain_fulfillment_cx_or_panic(&mut fulfill_cx, &vtable);

info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
vtable
Expand Down Expand Up @@ -141,7 +139,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// unified, and hence we need to process those obligations to get
/// the complete picture of the type.
fn drain_fulfillment_cx_or_panic<T>(&self,
span: Span,
fulfill_cx: &mut FulfillmentContext<'tcx>,
result: &T)
-> T::Lifted
Expand All @@ -153,15 +150,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// contains unbound type parameters. It could be a slight
// optimization to stop iterating early.
if let Err(errors) = fulfill_cx.select_all_or_error(self) {
span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking",
errors);
bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors);
}

let result = self.resolve_type_vars_if_possible(result);
let result = self.tcx.erase_regions(&result);

self.tcx.lift_to_global(&result).unwrap_or_else(||
span_bug!(span, "Uninferred types/regions in `{:?}`", result)
bug!("Uninferred types/regions in `{:?}`", result)
)
}
}
2 changes: 1 addition & 1 deletion src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl BoundRegion {
/// N.B., if you change this, you'll probably want to change the corresponding
/// AST structure in `libsyntax/ast.rs` as well.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable, HashStable)]
RustcEncodable, RustcDecodable, HashStable, Debug)]
pub enum TyKind<'tcx> {
/// The primitive boolean type. Written as `bool`.
Bool,
Expand Down
7 changes: 0 additions & 7 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,13 +936,6 @@ fn analysis<'tcx>(
});
});

// Abort so we don't try to construct MIR with liveness errors.
// We also won't want to continue with errors from rvalue promotion
// We only do so if the only error found so far *isn't* a missing `fn main()`
if !(entry_point.is_none() && sess.err_count() == 1) {
tcx.sess.abort_if_errors();
}

time(sess, "borrow checking", || {
if tcx.use_ast_borrowck() {
borrowck::check_crate(tcx);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_mir/hair/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> {
// the constant's pointee type
crty: Ty<'tcx>,
) -> ConstValue<'tcx> {
debug!("fold_const_value_deref {:?} {:?} {:?}", val, rty, crty);
match (val, &crty.sty, &rty.sty) {
// the easy case, deref a reference
(ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => ConstValue::ByRef(
Expand Down Expand Up @@ -238,6 +239,7 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> {

impl<'a, 'tcx> PatternFolder<'tcx> for LiteralExpander<'a, 'tcx> {
fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> {
debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.sty, pat.kind);
match (&pat.ty.sty, &*pat.kind) {
(
&ty::Ref(_, rty, _),
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_mir/hair/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,9 @@ fn check_legality_of_move_bindings(
E0009,
"cannot bind by-move and by-ref in the same pattern",
);
err.span_label(by_ref_span.unwrap(), "both by-ref and by-move used");
if let Some(by_ref_span) = by_ref_span {
err.span_label(by_ref_span, "both by-ref and by-move used");
}
for span in span_vec.iter(){
err.span_label(*span, "by-move pattern here");
}
Expand Down
25 changes: 21 additions & 4 deletions src/librustc_mir/hair/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,10 +974,27 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
PatternKind::Wild
}
ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
let msg = format!("to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
self.tcx.def_path_str(adt_def.did),
self.tcx.def_path_str(adt_def.did));
let path = self.tcx.def_path_str(adt_def.did);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
path,
path,
);
self.tcx.sess.span_err(span, &msg);
PatternKind::Wild
}
ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _)
if !self.tcx.has_attr(adt_def.did, "structural_match") => {
// HACK(estebank): Side-step ICE #53708, but anything other than erroring here
// would be wrong. Returnging `PatternKind::Wild` is not technically correct.
let path = self.tcx.def_path_str(adt_def.did);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
path,
path,
);
self.tcx.sess.span_err(span, &msg);
PatternKind::Wild
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1502,9 +1502,11 @@ impl MirPass for QualifyAndPromoteConstants {
tcx.sess,
span,
E0723,
"{} (see issue #57563)",
"{}",
err,
);
diag.note("for more information, see issue \
https://github.com/rust-lang/rust/issues/57563");
diag.help(
"add #![feature(const_fn)] to the crate attributes to enable",
);
Expand Down
8 changes: 7 additions & 1 deletion src/test/ui/borrowck/borrowck-mutate-in-guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ fn foo() -> isize {
match x {
Enum::A(_) if { x = Enum::B(false); false } => 1,
//~^ ERROR cannot assign in a pattern guard
//~| WARN cannot assign `x` in match guard
//~| WARN this error has been downgraded to a warning for backwards compatibility
//~| WARN this represents potential undefined behavior in your code and this warning will
Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
//~^ ERROR cannot mutably borrow in a pattern guard
//~^^ ERROR cannot assign in a pattern guard
//~| ERROR cannot assign in a pattern guard
//~| WARN cannot mutably borrow `x` in match guard
//~| WARN this error has been downgraded to a warning for backwards compatibility
//~| WARN this represents potential undefined behavior in your code and this warning will
Enum::A(p) => *p,
Enum::B(_) => 2,
}
Expand Down
29 changes: 26 additions & 3 deletions src/test/ui/borrowck/borrowck-mutate-in-guard.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,43 @@ LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
| ^^^^^^^^^^^^^^^^^^ assignment in pattern guard

error[E0301]: cannot mutably borrow in a pattern guard
--> $DIR/borrowck-mutate-in-guard.rs:12:38
--> $DIR/borrowck-mutate-in-guard.rs:15:38
|
LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
| ^ borrowed mutably in pattern guard
|
= help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable

error[E0302]: cannot assign in a pattern guard
--> $DIR/borrowck-mutate-in-guard.rs:12:41
--> $DIR/borrowck-mutate-in-guard.rs:15:41
|
LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
| ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard

warning[E0510]: cannot assign `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:10:25
|
LL | match x {
| - value is immutable in match guard
LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
| ^^^^^^^^^^^^^^^^^^ cannot assign
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

warning[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:15:33
|
LL | match x {
| - value is immutable in match guard
...
LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
| ^^^^^^ cannot mutably borrow
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0301, E0302.
Some errors have detailed explanations: E0301, E0302, E0510.
For more information about an error, try `rustc --explain E0301`.
8 changes: 7 additions & 1 deletion src/test/ui/consts/const_let_refutable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
fn main() {}

const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
a + b
a + b //~ ERROR can only call other `const fn` within a `const fn`
//~^ WARN use of possibly uninitialized variable: `a`
//~| WARN this error has been downgraded to a warning for backwards compatibility
//~| WARN this represents potential undefined behavior in your code and this warning will
//~| WARN use of possibly uninitialized variable: `b`
//~| WARN this error has been downgraded to a warning for backwards compatibility
//~| WARN this represents potential undefined behavior in your code and this warning will
}
32 changes: 30 additions & 2 deletions src/test/ui/consts/const_let_refutable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,34 @@ error[E0005]: refutable pattern in function argument: `&[]` not covered
LL | const fn slice([a, b]: &[i32]) -> i32 {
| ^^^^^^ pattern `&[]` not covered

error: aborting due to previous error
error[E0723]: can only call other `const fn` within a `const fn`, but `const std::ops::Add::add` is not stable as `const fn`
--> $DIR/const_let_refutable.rs:4:5
|
LL | a + b
| ^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

warning[E0381]: use of possibly uninitialized variable: `a`
--> $DIR/const_let_refutable.rs:4:5
|
LL | a + b
| ^ use of possibly uninitialized `a`
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

warning[E0381]: use of possibly uninitialized variable: `b`
--> $DIR/const_let_refutable.rs:4:9
|
LL | a + b
| ^ use of possibly uninitialized `b`
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0005`.
Some errors have detailed explanations: E0005, E0381, E0723.
For more information about an error, try `rustc --explain E0005`.
12 changes: 10 additions & 2 deletions src/test/ui/consts/match_ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

struct S;

#[derive(PartialEq, Eq)]
struct T;

fn main() {
const C: &S = &S;
match C { //~ ERROR non-exhaustive
C => {} // this is a common bug around constants and references in patterns
match C {
C => {}
//~^ ERROR to use a constant of type `S` in a pattern, `S` must be annotated with
}
const K: &T = &T;
match K { //~ ERROR non-exhaustive patterns: `&T` not covered
K => {}
}
}
16 changes: 11 additions & 5 deletions src/test/ui/consts/match_ice.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
error[E0004]: non-exhaustive patterns: `&S` not covered
--> $DIR/match_ice.rs:7:11
error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/match_ice.rs:11:9
|
LL | match C {
| ^ pattern `&S` not covered
LL | C => {}
| ^

error[E0004]: non-exhaustive patterns: `&T` not covered
--> $DIR/match_ice.rs:15:11
|
LL | match K {
| ^ pattern `&T` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: aborting due to previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0004`.
3 changes: 2 additions & 1 deletion src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error[E0723]: heap allocations are not allowed in const fn (see issue #57563)
error[E0723]: heap allocations are not allowed in const fn
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

Expand Down
15 changes: 10 additions & 5 deletions src/test/ui/consts/min_const_fn/cast_errors.stderr
Original file line number Diff line number Diff line change
@@ -1,41 +1,46 @@
error[E0723]: unsizing casts are not allowed in const fn (see issue #57563)
error[E0723]: unsizing casts are not allowed in const fn
--> $DIR/cast_errors.rs:3:41
|
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
| ^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error[E0723]: function pointers in const fn are unstable (see issue #57563)
error[E0723]: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:5:23
|
LL | const fn closure() -> fn() { || {} }
| ^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error[E0723]: function pointers in const fn are unstable (see issue #57563)
error[E0723]: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:8:5
|
LL | (|| {}) as fn();
| ^^^^^^^^^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error[E0723]: function pointers in const fn are unstable (see issue #57563)
error[E0723]: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:11:28
|
LL | const fn reify(f: fn()) -> unsafe fn() { f }
| ^^^^^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error[E0723]: function pointers in const fn are unstable (see issue #57563)
error[E0723]: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:13:21
|
LL | const fn reify2() { main as unsafe fn(); }
| ^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error: aborting due to 5 previous errors
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error[E0723]: function pointers in const fn are unstable (see issue #57563)
error[E0723]: function pointers in const fn are unstable
--> $DIR/cmp_fn_pointers.rs:1:14
|
LL | const fn cmp(x: fn(), y: fn()) -> bool {
| ^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error: aborting due to previous error
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/consts/min_const_fn/loop_ice.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error[E0723]: loops are not allowed in const fn (see issue #57563)
error[E0723]: loops are not allowed in const fn
--> $DIR/loop_ice.rs:2:5
|
LL | loop {}
| ^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add #![feature(const_fn)] to the crate attributes to enable

error: aborting due to previous error
Expand Down
Loading

0 comments on commit 31f5d69

Please sign in to comment.