Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/coerce.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/coerce.rs | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index 7930d8b0ed..62ce00a2e3 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -144,7 +144,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> { fn unify_raw(&mut self, a: Ty<'db>, b: Ty<'db>) -> InferResult<'db, Ty<'db>> { debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub); self.commit_if_ok(|this| { - let at = this.infer_ctxt().at(&this.cause, this.table.param_env); + let at = this.infer_ctxt().at(&this.cause, this.table.trait_env.env); let res = if this.use_lub { at.lub(b, a) @@ -210,9 +210,8 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> { // Coercing from `!` to any type is allowed: if a.is_never() { // If we're coercing into an inference var, mark it as possibly diverging. - // FIXME: rustc does this differently. - if let TyKind::Infer(rustc_type_ir::TyVar(b)) = b.kind() { - self.table.set_diverging(b.as_u32().into(), chalk_ir::TyVariableKind::General); + if b.is_infer() { + self.table.set_diverging(b); } if self.coerce_never { @@ -330,7 +329,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> { obligations.push(Obligation::new( self.interner(), self.cause.clone(), - self.table.param_env, + self.table.trait_env.env, Binder::dummy(PredicateKind::Coerce(CoercePredicate { a: source_ty, b: target_ty, @@ -718,7 +717,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> { let mut queue: SmallVec<[PredicateObligation<'db>; 4]> = smallvec![Obligation::new( self.interner(), cause, - self.table.param_env, + self.table.trait_env.env, TraitRef::new( self.interner(), coerce_unsized_did.into(), @@ -1114,8 +1113,12 @@ impl<'db> InferenceContext<'db> { match self.table.commit_if_ok(|table| { // We need to eagerly handle nested obligations due to lazy norm. let mut ocx = ObligationCtxt::new(&table.infer_ctxt); - let value = - ocx.lub(&ObligationCause::new(), table.param_env, prev_ty, new_ty)?; + let value = ocx.lub( + &ObligationCause::new(), + table.trait_env.env, + prev_ty, + new_ty, + )?; if ocx.select_where_possible().is_empty() { Ok(InferOk { value, obligations: ocx.into_pending_obligations() }) } else { @@ -1158,7 +1161,7 @@ impl<'db> InferenceContext<'db> { let sig = self .table .infer_ctxt - .at(&ObligationCause::new(), self.table.param_env) + .at(&ObligationCause::new(), self.table.trait_env.env) .lub(a_sig, b_sig) .map(|ok| self.table.register_infer_ok(ok))?; @@ -1248,7 +1251,7 @@ impl<'db> InferenceContext<'db> { .commit_if_ok(|table| { table .infer_ctxt - .at(&ObligationCause::new(), table.param_env) + .at(&ObligationCause::new(), table.trait_env.env) .lub(prev_ty, new_ty) }) .unwrap_err()) @@ -1498,7 +1501,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { assert!(expression_ty.is_unit(), "if let hack without unit type"); icx.table .infer_ctxt - .at(cause, icx.table.param_env) + .at(cause, icx.table.trait_env.env) .eq( // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs DefineOpaqueTypes::Yes, @@ -1564,9 +1567,9 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { } } -pub fn could_coerce( - db: &dyn HirDatabase, - env: Arc<TraitEnvironment>, +pub fn could_coerce<'db>( + db: &'db dyn HirDatabase, + env: Arc<TraitEnvironment<'db>>, tys: &crate::Canonical<(crate::Ty, crate::Ty)>, ) -> bool { coerce(db, env, tys).is_ok() @@ -1574,7 +1577,7 @@ pub fn could_coerce( fn coerce<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment>, + env: Arc<TraitEnvironment<'db>>, tys: &crate::Canonical<(crate::Ty, crate::Ty)>, ) -> Result<(Vec<Adjustment>, crate::Ty), TypeError<DbInterner<'db>>> { let mut table = InferenceTable::new(db, env); @@ -1609,16 +1612,21 @@ fn coerce<'db>( chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner), } == Some(iv)) }; - let fallback = |iv, kind, default, binder| match kind { - chalk_ir::VariableKind::Ty(_ty_kind) => find_var(iv) - .map_or(default, |i| crate::BoundVar::new(binder, i).to_ty(Interner).cast(Interner)), - chalk_ir::VariableKind::Lifetime => find_var(iv).map_or(default, |i| { - crate::BoundVar::new(binder, i).to_lifetime(Interner).cast(Interner) - }), - chalk_ir::VariableKind::Const(ty) => find_var(iv).map_or(default, |i| { - crate::BoundVar::new(binder, i).to_const(Interner, ty).cast(Interner) - }), + let fallback = |iv, kind, binder| match kind { + chalk_ir::VariableKind::Ty(_ty_kind) => find_var(iv).map_or_else( + || chalk_ir::TyKind::Error.intern(Interner).cast(Interner), + |i| crate::BoundVar::new(binder, i).to_ty(Interner).cast(Interner), + ), + chalk_ir::VariableKind::Lifetime => find_var(iv).map_or_else( + || crate::LifetimeData::Error.intern(Interner).cast(Interner), + |i| crate::BoundVar::new(binder, i).to_lifetime(Interner).cast(Interner), + ), + chalk_ir::VariableKind::Const(ty) => find_var(iv).map_or_else( + || crate::unknown_const(ty.clone()).cast(Interner), + |i| crate::BoundVar::new(binder, i).to_const(Interner, ty.clone()).cast(Interner), + ), }; // FIXME also map the types in the adjustments + // FIXME: We don't fallback correctly since this is done on `InferenceContext` and we only have `InferenceTable`. Ok((adjustments, table.resolve_with_fallback(ty.to_chalk(table.interner), &fallback))) } |