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.rs35
1 files changed, 23 insertions, 12 deletions
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 962fc752a5..55e02a6933 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -52,7 +52,7 @@ use smallvec::SmallVec;
use tracing::{debug, instrument};
use crate::{
- Adjust, Adjustment, AutoBorrow, ParamEnvAndCrate, PointerCast, TargetFeatures,
+ Adjust, Adjustment, AutoBorrow, ParamEnvAndCrate, PointerCast, Span, TargetFeatures,
autoderef::Autoderef,
db::{HirDatabase, InternedClosure, InternedClosureId},
infer::{
@@ -316,7 +316,8 @@ where
if b.is_infer() {
// Two unresolved type variables: create a `Coerce` predicate.
- let target_ty = if self.use_lub { self.infcx().next_ty_var() } else { b };
+ let target_ty =
+ if self.use_lub { self.infcx().next_ty_var(self.cause.span()) } else { b };
let mut obligations = PredicateObligations::with_capacity(2);
for &source_ty in &[a, b] {
@@ -463,7 +464,7 @@ where
} else {
if r_borrow_var.is_none() {
// create var lazily, at most once
- let r = self.infcx().next_region_var();
+ let r = self.infcx().next_region_var(self.cause.span());
r_borrow_var = Some(r); // [4] above
}
r_borrow_var.unwrap()
@@ -624,7 +625,7 @@ where
(TyKind::Ref(_, ty_a, mutbl_a), TyKind::Ref(_, _, mutbl_b)) => {
coerce_mutbls(mutbl_a, mutbl_b)?;
- let r_borrow = self.infcx().next_region_var();
+ let r_borrow = self.infcx().next_region_var(self.cause.span());
// We don't allow two-phase borrows here, at least for initial
// implementation. If it happens that this coercion is a function argument,
@@ -658,7 +659,7 @@ where
// the `CoerceUnsized` target type and the expected type.
// We only have the latter, so we use an inference variable
// for the former and let type inference do the rest.
- let coerce_target = self.infcx().next_ty_var();
+ let coerce_target = self.infcx().next_ty_var(self.cause.span());
let mut coercion = self.unify_and(
coerce_target,
@@ -688,6 +689,7 @@ where
errored: false,
unsize_did,
coerce_unsized_did,
+ span: self.cause.span(),
},
)
.is_break()
@@ -899,7 +901,7 @@ impl<'db> InferenceContext<'_, 'db> {
target = self.table.try_structurally_resolve_type(target);
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
- let cause = ObligationCause::new();
+ let cause = ObligationCause::with_span(expr.into());
let coerce_never = self.expr_guaranteed_to_constitute_read_for_never(expr, expr_is_read);
let mut coerce = Coerce {
delegate: InferenceCoercionDelegate(self),
@@ -974,8 +976,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::with_span(new.into()),
+ table.param_env,
+ prev_ty,
+ new_ty,
+ )?;
if ocx.try_evaluate_obligations().is_empty() {
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
} else {
@@ -1023,7 +1029,7 @@ impl<'db> InferenceContext<'_, 'db> {
let sig = self
.table
.infer_ctxt
- .at(&ObligationCause::new(), self.table.param_env)
+ .at(&ObligationCause::with_span(new.into()), self.table.param_env)
.lub(a_sig, b_sig)
.map(|ok| self.table.register_infer_ok(ok))?;
@@ -1069,7 +1075,7 @@ impl<'db> InferenceContext<'_, 'db> {
// operate on values and not places, so a never coercion is valid.
let mut coerce = Coerce {
delegate: InferenceCoercionDelegate(self),
- cause: ObligationCause::new(),
+ cause: ObligationCause::with_span(new.into()),
allow_two_phase: AllowTwoPhase::No,
coerce_never: true,
use_lub: true,
@@ -1105,7 +1111,7 @@ impl<'db> InferenceContext<'_, 'db> {
.commit_if_ok(|table| {
table
.infer_ctxt
- .at(&ObligationCause::new(), table.param_env)
+ .at(&ObligationCause::with_span(new.into()), table.param_env)
.lub(prev_ty, new_ty)
})
.unwrap_err())
@@ -1451,7 +1457,7 @@ fn coerce<'db>(
) -> Result<(Vec<Adjustment>, Ty<'db>), TypeError<DbInterner<'db>>> {
let interner = DbInterner::new_with(db, env.krate);
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
- let ((ty1_with_vars, ty2_with_vars), vars) = infcx.instantiate_canonical(tys);
+ let ((ty1_with_vars, ty2_with_vars), vars) = infcx.instantiate_canonical(Span::Dummy, tys);
let cause = ObligationCause::new();
// FIXME: Target features.
@@ -1611,11 +1617,16 @@ struct CoerceVisitor<'a, D> {
errored: bool,
unsize_did: TraitId,
coerce_unsized_did: TraitId,
+ span: Span,
}
impl<'a, 'db, D: CoerceDelegate<'db>> ProofTreeVisitor<'db> for CoerceVisitor<'a, D> {
type Result = ControlFlow<()>;
+ fn span(&self) -> Span {
+ self.span
+ }
+
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'db>) -> Self::Result {
let Some(pred) = goal.goal().predicate.as_trait_clause() else {
return ControlFlow::Continue(());