Skip to content

Commit f8c1404

Browse files
committed
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`.
1 parent cd4de4c commit f8c1404

File tree

3 files changed

+23
-27
lines changed

3 files changed

+23
-27
lines changed

src/librustc_typeck/check/cast.rs

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

src/librustc_typeck/check/mod.rs

+16-20
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,19 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
858858
fcx
859859
};
860860

861+
fcx.check_casts();
862+
863+
// All type checking constraints were added, try to fallback unsolved variables.
864+
fcx.select_obligations_where_possible();
865+
for ty in &fcx.unsolved_variables() {
866+
fcx.fallback_if_possible(ty, Fallback::Full);
867+
}
861868
fcx.select_obligations_where_possible();
869+
870+
// Closure and generater analysis may run after fallback
871+
// because they doen't constrain other type variables.
862872
fcx.closure_analyze(body);
863-
fcx.check_casts();
873+
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
864874
fcx.resolve_generator_interiors(def_id);
865875
fcx.select_all_obligations_or_error();
866876

@@ -2137,9 +2147,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21372147
// Non-numerics get replaced with ! or () (depending on whether
21382148
// feature(never_type) is enabled), unconstrained ints with i32,
21392149
// unconstrained floats with f64.
2140-
// Defaulting inference variables becomes very dubious if we have
2141-
// encountered type-checking errors. In that case, fallback to TyError.
2142-
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
2150+
// Fallback becomes very dubious if we have encountered type-checking errors.
2151+
// In that case, fallback to TyError.
2152+
fn fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
21432153
use rustc::ty::error::UnconstrainedNumeric::Neither;
21442154
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
21452155

@@ -2162,22 +2172,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21622172

21632173
fn select_all_obligations_or_error(&self) {
21642174
debug!("select_all_obligations_or_error");
2165-
2166-
// upvar inference should have ensured that all deferred call
2167-
// resolutions are handled by now.
2168-
assert!(self.deferred_call_resolutions.borrow().is_empty());
2169-
2170-
self.select_obligations_where_possible();
2171-
2172-
for ty in &self.unsolved_variables() {
2173-
self.apply_fallback_if_possible(ty, Fallback::Full);
2174-
}
2175-
2176-
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2177-
2178-
match fulfillment_cx.select_all_or_error(self) {
2179-
Ok(()) => { }
2180-
Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2175+
if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2176+
self.report_fulfillment_errors(&errors, self.inh.body_id);
21812177
}
21822178
}
21832179

src/test/ui/interior-mutability/interior-mutability.stderr

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

1313
error: aborting due to previous error

0 commit comments

Comments
 (0)