Skip to content

Commit

Permalink
Only closure analysis should run after fallback.
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
leoyvens committed Jan 27, 2018
1 parent cd4de4c commit f8c1404
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/cast.rs
Expand Up @@ -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);
Expand Down
36 changes: 16 additions & 20 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -858,9 +858,19 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fcx
};

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);
fcx.check_casts();
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
fcx.resolve_generator_interiors(def_id);
fcx.select_all_obligations_or_error();

Expand Down Expand Up @@ -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};

Expand All @@ -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);
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/interior-mutability/interior-mutability.stderr
@@ -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
Expand Down

0 comments on commit f8c1404

Please sign in to comment.