mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Properly infer types with type casts
This commit is contained in:
parent
75ac37f317
commit
074488b290
5 changed files with 112 additions and 28 deletions
|
@ -13,6 +13,15 @@
|
|||
//! to certain types. To record this, we use the union-find implementation from
|
||||
//! the `ena` crate, which is extracted from rustc.
|
||||
|
||||
mod cast;
|
||||
pub(crate) mod closure;
|
||||
mod coerce;
|
||||
mod expr;
|
||||
mod mutability;
|
||||
mod pat;
|
||||
mod path;
|
||||
pub(crate) mod unify;
|
||||
|
||||
use std::{convert::identity, ops::Index};
|
||||
|
||||
use chalk_ir::{
|
||||
|
@ -60,15 +69,8 @@ pub use coerce::could_coerce;
|
|||
#[allow(unreachable_pub)]
|
||||
pub use unify::could_unify;
|
||||
|
||||
pub(crate) use self::closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
|
||||
|
||||
pub(crate) mod unify;
|
||||
mod path;
|
||||
mod expr;
|
||||
mod pat;
|
||||
mod coerce;
|
||||
pub(crate) mod closure;
|
||||
mod mutability;
|
||||
use cast::CastCheck;
|
||||
pub(crate) use closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
|
||||
|
||||
/// The entry point of type inference.
|
||||
pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
|
||||
|
@ -508,6 +510,8 @@ pub(crate) struct InferenceContext<'a> {
|
|||
diverges: Diverges,
|
||||
breakables: Vec<BreakableContext>,
|
||||
|
||||
deferred_cast_checks: Vec<CastCheck>,
|
||||
|
||||
// fields related to closure capture
|
||||
current_captures: Vec<CapturedItemWithoutTy>,
|
||||
current_closure: Option<ClosureId>,
|
||||
|
@ -582,7 +586,8 @@ impl<'a> InferenceContext<'a> {
|
|||
resolver,
|
||||
diverges: Diverges::Maybe,
|
||||
breakables: Vec::new(),
|
||||
current_captures: vec![],
|
||||
deferred_cast_checks: Vec::new(),
|
||||
current_captures: Vec::new(),
|
||||
current_closure: None,
|
||||
deferred_closures: FxHashMap::default(),
|
||||
closure_dependencies: FxHashMap::default(),
|
||||
|
@ -594,7 +599,7 @@ impl<'a> InferenceContext<'a> {
|
|||
// used this function for another workaround, mention it here. If you really need this function and believe that
|
||||
// there is no problem in it being `pub(crate)`, remove this comment.
|
||||
pub(crate) fn resolve_all(self) -> InferenceResult {
|
||||
let InferenceContext { mut table, mut result, .. } = self;
|
||||
let InferenceContext { mut table, mut result, deferred_cast_checks, .. } = self;
|
||||
// Destructure every single field so whenever new fields are added to `InferenceResult` we
|
||||
// don't forget to handle them here.
|
||||
let InferenceResult {
|
||||
|
@ -622,6 +627,13 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
table.fallback_if_possible();
|
||||
|
||||
// Comment from rustc:
|
||||
// Even though coercion casts provide type hints, we check casts after fallback for
|
||||
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
|
||||
for cast in deferred_cast_checks {
|
||||
cast.check(&mut table);
|
||||
}
|
||||
|
||||
// FIXME resolve obligations as well (use Guidance if necessary)
|
||||
table.resolve_obligations_as_possible();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue