Only closure analysis should run after fallback.

Move `check_casts` and `resolve_generator_interiors` to before fallback.

Rename `apply_fallback_if_possible` to `fallback_if_possible`.

Refactor `select_all_obligations_or_error`.
This commit is contained in:
leonardo.yvens 2018-01-27 15:42:23 -02:00
parent cd4de4cece
commit f8c140465f
3 changed files with 24 additions and 28 deletions

View file

@ -399,7 +399,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
// For backwards compatibility we apply numeric fallback here. This means that in:
// `let x = 100; x as u8;`, we infer `x` to `i32` rather than `u8`.
if self.expr_ty.is_ty_infer() {
fcx.apply_fallback_if_possible(self.expr_ty, Fallback::Numeric);
fcx.fallback_if_possible(self.expr_ty, Fallback::Numeric);
self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
}
self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);

View file

@ -858,9 +858,19 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fcx
};
fcx.select_obligations_where_possible();
fcx.closure_analyze(body);
fcx.check_casts();
// All type checking constraints were added, try to fallback unsolved variables.
fcx.select_obligations_where_possible();
for ty in &fcx.unsolved_variables() {
fcx.fallback_if_possible(ty, Fallback::Full);
}
fcx.select_obligations_where_possible();
// Closure and generater analysis may run after fallback
// because they doen't constrain other type variables.
fcx.closure_analyze(body);
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
fcx.resolve_generator_interiors(def_id);
fcx.select_all_obligations_or_error();
@ -2137,9 +2147,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Non-numerics get replaced with ! or () (depending on whether
// feature(never_type) is enabled), unconstrained ints with i32,
// unconstrained floats with f64.
// Defaulting inference variables becomes very dubious if we have
// encountered type-checking errors. In that case, fallback to TyError.
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
// Fallback becomes very dubious if we have encountered type-checking errors.
// In that case, fallback to TyError.
fn fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
use rustc::ty::error::UnconstrainedNumeric::Neither;
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
@ -2162,22 +2172,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn select_all_obligations_or_error(&self) {
debug!("select_all_obligations_or_error");
// upvar inference should have ensured that all deferred call
// resolutions are handled by now.
assert!(self.deferred_call_resolutions.borrow().is_empty());
self.select_obligations_where_possible();
for ty in &self.unsolved_variables() {
self.apply_fallback_if_possible(ty, Fallback::Full);
}
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
match fulfillment_cx.select_all_or_error(self) {
Ok(()) => { }
Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
self.report_fulfillment_errors(&errors, self.inh.body_id);
}
}

View file

@ -1,13 +1,13 @@
error[E0277]: the trait bound `std::cell::UnsafeCell<{integer}>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::Cell<{integer}>`
error[E0277]: the trait bound `std::cell::UnsafeCell<i32>: std::panic::RefUnwindSafe` is not satisfied in `std::cell::Cell<i32>`
--> $DIR/interior-mutability.rs:15:5
|
15 | catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound
| ^^^^^^^^^^^^ the type std::cell::UnsafeCell<{integer}> may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| ^^^^^^^^^^^^ the type std::cell::UnsafeCell<i32> may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `std::cell::Cell<{integer}>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<{integer}>`
= note: required because it appears within the type `std::cell::Cell<{integer}>`
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<{integer}>`
= note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:15:18: 15:35 x:&std::cell::Cell<{integer}>]`
= help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
= note: required because it appears within the type `std::cell::Cell<i32>`
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
= 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