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:
parent
cd4de4cece
commit
f8c140465f
3 changed files with 24 additions and 28 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue