Skip to content

Commit c1b4824

Browse files
nikomatsakisMark-Simulacrum
authored andcommitted
factor fallback code into its own module
1 parent 7960030 commit c1b4824

File tree

2 files changed

+54
-44
lines changed

2 files changed

+54
-44
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use crate::check::FallbackMode;
2+
use crate::check::FnCtxt;
3+
4+
impl<'tcx> FnCtxt<'_, 'tcx> {
5+
pub(super) fn type_inference_fallback(&self) {
6+
// All type checking constraints were added, try to fallback unsolved variables.
7+
self.select_obligations_where_possible(false, |_| {});
8+
let mut fallback_has_occurred = false;
9+
10+
// We do fallback in two passes, to try to generate
11+
// better error messages.
12+
// The first time, we do *not* replace opaque types.
13+
for ty in &self.unsolved_variables() {
14+
debug!("unsolved_variable = {:?}", ty);
15+
fallback_has_occurred |= self.fallback_if_possible(ty, FallbackMode::NoOpaque);
16+
}
17+
// We now see if we can make progress. This might
18+
// cause us to unify inference variables for opaque types,
19+
// since we may have unified some other type variables
20+
// during the first phase of fallback.
21+
// This means that we only replace inference variables with their underlying
22+
// opaque types as a last resort.
23+
//
24+
// In code like this:
25+
//
26+
// ```rust
27+
// type MyType = impl Copy;
28+
// fn produce() -> MyType { true }
29+
// fn bad_produce() -> MyType { panic!() }
30+
// ```
31+
//
32+
// we want to unify the opaque inference variable in `bad_produce`
33+
// with the diverging fallback for `panic!` (e.g. `()` or `!`).
34+
// This will produce a nice error message about conflicting concrete
35+
// types for `MyType`.
36+
//
37+
// If we had tried to fallback the opaque inference variable to `MyType`,
38+
// we will generate a confusing type-check error that does not explicitly
39+
// refer to opaque types.
40+
self.select_obligations_where_possible(fallback_has_occurred, |_| {});
41+
42+
// We now run fallback again, but this time we allow it to replace
43+
// unconstrained opaque type variables, in addition to performing
44+
// other kinds of fallback.
45+
for ty in &self.unsolved_variables() {
46+
fallback_has_occurred |= self.fallback_if_possible(ty, FallbackMode::All);
47+
}
48+
49+
// See if we can make any more progress.
50+
self.select_obligations_where_possible(fallback_has_occurred, |_| {});
51+
}
52+
}

compiler/rustc_typeck/src/check/mod.rs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ mod diverges;
7575
pub mod dropck;
7676
mod expectation;
7777
mod expr;
78+
mod fallback;
7879
mod fn_ctxt;
7980
mod gather_locals;
8081
mod generator_interior;
@@ -445,50 +446,7 @@ fn typeck_with_fallback<'tcx>(
445446
fcx
446447
};
447448

448-
// All type checking constraints were added, try to fallback unsolved variables.
449-
fcx.select_obligations_where_possible(false, |_| {});
450-
let mut fallback_has_occurred = false;
451-
452-
// We do fallback in two passes, to try to generate
453-
// better error messages.
454-
// The first time, we do *not* replace opaque types.
455-
for ty in &fcx.unsolved_variables() {
456-
fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
457-
}
458-
// We now see if we can make progress. This might
459-
// cause us to unify inference variables for opaque types,
460-
// since we may have unified some other type variables
461-
// during the first phase of fallback.
462-
// This means that we only replace inference variables with their underlying
463-
// opaque types as a last resort.
464-
//
465-
// In code like this:
466-
//
467-
// ```rust
468-
// type MyType = impl Copy;
469-
// fn produce() -> MyType { true }
470-
// fn bad_produce() -> MyType { panic!() }
471-
// ```
472-
//
473-
// we want to unify the opaque inference variable in `bad_produce`
474-
// with the diverging fallback for `panic!` (e.g. `()` or `!`).
475-
// This will produce a nice error message about conflicting concrete
476-
// types for `MyType`.
477-
//
478-
// If we had tried to fallback the opaque inference variable to `MyType`,
479-
// we will generate a confusing type-check error that does not explicitly
480-
// refer to opaque types.
481-
fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
482-
483-
// We now run fallback again, but this time we allow it to replace
484-
// unconstrained opaque type variables, in addition to performing
485-
// other kinds of fallback.
486-
for ty in &fcx.unsolved_variables() {
487-
fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
488-
}
489-
490-
// See if we can make any more progress.
491-
fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
449+
fcx.type_inference_fallback();
492450

493451
// Even though coercion casts provide type hints, we check casts after fallback for
494452
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.

0 commit comments

Comments
 (0)