Skip to content

Commit 3c67cef

Browse files
Ensure we give spans for obligations everywhere
1 parent a4cced6 commit 3c67cef

24 files changed

Lines changed: 322 additions & 289 deletions

File tree

crates/hir-ty/src/autoderef.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn autoderef<'db>(
4040
let interner = DbInterner::new_with(db, env.krate);
4141
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
4242
let (ty, _) = infcx.instantiate_canonical(Span::Dummy, &ty);
43-
let autoderef = Autoderef::new(&infcx, env.param_env, ty);
43+
let autoderef = Autoderef::new(&infcx, env.param_env, ty, Span::Dummy);
4444
let mut v = Vec::new();
4545
for (ty, _steps) in autoderef {
4646
// `ty` may contain unresolved inference variables. Since there's no chance they would be
@@ -155,6 +155,7 @@ pub(crate) struct GeneralAutoderef<'db, Ctx, Steps = Vec<(Ty<'db>, AutoderefKind
155155
// Configurations:
156156
include_raw_pointers: bool,
157157
use_receiver_trait: bool,
158+
span: Span,
158159
}
159160

160161
pub(crate) type Autoderef<'a, 'db, Steps = Vec<(Ty<'db>, AutoderefKind)>> =
@@ -200,7 +201,7 @@ where
200201
// autoderef expect this type to have been structurally normalized.
201202
if let TyKind::Alias(..) = ty.kind() {
202203
let (normalized_ty, obligations) =
203-
structurally_normalize_ty(self.infcx(), self.param_env(), ty)?;
204+
structurally_normalize_ty(self.infcx(), self.param_env(), ty, self.span)?;
204205
self.state.obligations.extend(obligations);
205206
(AutoderefKind::Builtin, normalized_ty)
206207
} else {
@@ -232,8 +233,9 @@ impl<'a, 'db> Autoderef<'a, 'db> {
232233
infcx: &'a InferCtxt<'db>,
233234
param_env: ParamEnv<'db>,
234235
base_ty: Ty<'db>,
236+
span: Span,
235237
) -> Self {
236-
Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty)
238+
Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty, span)
237239
}
238240
}
239241

@@ -242,8 +244,9 @@ impl<'a, 'b, 'db> InferenceContextAutoderef<'a, 'b, 'db> {
242244
pub(crate) fn new_from_inference_context(
243245
ctx: &'a mut InferenceContext<'b, 'db>,
244246
base_ty: Ty<'db>,
247+
span: Span,
245248
) -> Self {
246-
Self::new_impl(InferenceContextAutoderefCtx(ctx), base_ty)
249+
Self::new_impl(InferenceContextAutoderefCtx(ctx), base_ty, span)
247250
}
248251

249252
#[inline]
@@ -258,8 +261,9 @@ impl<'a, 'db> Autoderef<'a, 'db, usize> {
258261
infcx: &'a InferCtxt<'db>,
259262
param_env: ParamEnv<'db>,
260263
base_ty: Ty<'db>,
264+
span: Span,
261265
) -> Self {
262-
Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty)
266+
Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty, span)
263267
}
264268
}
265269

@@ -269,7 +273,7 @@ where
269273
Steps: TrackAutoderefSteps<'db>,
270274
{
271275
#[inline]
272-
fn new_impl(ctx: Ctx, base_ty: Ty<'db>) -> Self {
276+
fn new_impl(ctx: Ctx, base_ty: Ty<'db>, span: Span) -> Self {
273277
GeneralAutoderef {
274278
state: AutoderefSnapshot {
275279
steps: Steps::default(),
@@ -282,6 +286,7 @@ where
282286
traits: None,
283287
include_raw_pointers: false,
284288
use_receiver_trait: false,
289+
span,
285290
}
286291
}
287292

@@ -338,7 +343,7 @@ where
338343

339344
let trait_ref = TraitRef::new(interner, trait_.into(), [ty]);
340345
let obligation =
341-
Obligation::new(interner, ObligationCause::new(), self.param_env(), trait_ref);
346+
Obligation::new(interner, ObligationCause::new(self.span), self.param_env(), trait_ref);
342347
// We detect whether the self type implements `Deref` before trying to
343348
// structurally normalize. We use `predicate_may_hold_opaque_types_jank`
344349
// to support not-yet-defined opaque types. It will succeed for `impl Deref`
@@ -352,6 +357,7 @@ where
352357
self.infcx(),
353358
self.param_env(),
354359
Ty::new_projection(interner, trait_target.into(), [ty]),
360+
self.span,
355361
)?;
356362
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
357363
self.state.obligations.extend(obligations);
@@ -403,9 +409,11 @@ fn structurally_normalize_ty<'db>(
403409
infcx: &InferCtxt<'db>,
404410
param_env: ParamEnv<'db>,
405411
ty: Ty<'db>,
412+
span: Span,
406413
) -> Option<(Ty<'db>, PredicateObligations<'db>)> {
407414
let mut ocx = ObligationCtxt::new(infcx);
408-
let Ok(normalized_ty) = ocx.structurally_normalize_ty(&ObligationCause::misc(), param_env, ty)
415+
let Ok(normalized_ty) =
416+
ocx.structurally_normalize_ty(&ObligationCause::new(span), param_env, ty)
409417
else {
410418
// We shouldn't have errors here in the old solver, except for
411419
// evaluate/fulfill mismatches, but that's not a reason for an ICE.

crates/hir-ty/src/display.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ fn render_const_scalar<'db>(
738738
) -> Result {
739739
let param_env = ParamEnv::empty();
740740
let infcx = f.interner.infer_ctxt().build(TypingMode::PostAnalysis);
741-
let ty = infcx.at(&ObligationCause::new(), param_env).deeply_normalize(ty).unwrap_or(ty);
741+
let ty = infcx.at(&ObligationCause::dummy(), param_env).deeply_normalize(ty).unwrap_or(ty);
742742
render_const_scalar_inner(f, b, memory_map, ty, param_env)
743743
}
744744

@@ -1023,7 +1023,7 @@ fn render_const_scalar_from_valtree<'db>(
10231023
) -> Result {
10241024
let param_env = ParamEnv::empty();
10251025
let infcx = f.interner.infer_ctxt().build(TypingMode::PostAnalysis);
1026-
let ty = infcx.at(&ObligationCause::new(), param_env).deeply_normalize(ty).unwrap_or(ty);
1026+
let ty = infcx.at(&ObligationCause::dummy(), param_env).deeply_normalize(ty).unwrap_or(ty);
10271027
render_const_scalar_from_valtree_inner(f, ty, valtree, param_env)
10281028
}
10291029

crates/hir-ty/src/infer.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
19261926
}
19271927

19281928
pub(crate) fn structurally_resolve_type(&mut self, node: ExprOrPatId, ty: Ty<'db>) -> Ty<'db> {
1929-
let result = self.table.try_structurally_resolve_type(ty);
1929+
let result = self.table.try_structurally_resolve_type(node.into(), ty);
19301930
if result.is_ty_var() { self.type_must_be_known_at_this_point(node, ty) } else { result }
19311931
}
19321932

@@ -1936,14 +1936,18 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
19361936
expected: Ty<'db>,
19371937
actual: Ty<'db>,
19381938
) -> Result<(), ()> {
1939-
let result = self.demand_eqtype_fixme_no_diag(expected, actual);
1939+
let result = self
1940+
.table
1941+
.at(&ObligationCause::new(id))
1942+
.eq(expected, actual)
1943+
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
19401944
if result.is_err() {
19411945
self.result
19421946
.type_mismatches
19431947
.get_or_insert_default()
19441948
.insert(id, TypeMismatch { expected: expected.store(), actual: actual.store() });
19451949
}
1946-
result
1950+
result.map_err(drop)
19471951
}
19481952

19491953
fn demand_eqtype_fixme_no_diag(
@@ -1953,7 +1957,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
19531957
) -> Result<(), ()> {
19541958
let result = self
19551959
.table
1956-
.at(&ObligationCause::new())
1960+
.at(&ObligationCause::dummy())
19571961
.eq(expected, actual)
19581962
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
19591963
result.map_err(drop)
@@ -1967,7 +1971,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
19671971
) -> Result<(), ()> {
19681972
let result = self
19691973
.table
1970-
.at(&ObligationCause::new())
1974+
.at(&ObligationCause::new(id))
19711975
.sup(expected, actual)
19721976
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
19731977
if result.is_err() {
@@ -2008,11 +2012,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
20082012
self.types.types.error
20092013
}
20102014

2011-
pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>) {
2015+
pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>, span: Span) {
20122016
if !ty.references_non_lt_error()
20132017
&& let Some(sized_trait) = self.lang_items.Sized
20142018
{
2015-
self.table.register_bound(ty, sized_trait, ObligationCause::new());
2019+
self.table.register_bound(ty, sized_trait, ObligationCause::new(span));
20162020
}
20172021
}
20182022

@@ -2077,7 +2081,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
20772081
args,
20782082
),
20792083
);
2080-
ty = self.table.try_structurally_resolve_type(alias);
2084+
ty = self.table.try_structurally_resolve_type(node.into(), alias);
20812085
segments = segments.skip(1);
20822086
}
20832087

@@ -2177,7 +2181,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
21772181
never!("resolver should always resolve lang item paths");
21782182
return (self.err_ty(), None);
21792183
};
2180-
return self.resolve_variant_on_alias(ty, None, mod_path);
2184+
return self.resolve_variant_on_alias(node, ty, None, mod_path);
21812185
};
21822186

21832187
let mut remaining_segments = path.segments().skip(remaining_idx);
@@ -2290,7 +2294,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
22902294
let ty = self.db.ty(it.into()).instantiate(interner, args);
22912295
let ty = self.insert_type_vars(ty, Span::Dummy);
22922296

2293-
self.resolve_variant_on_alias(ty, unresolved, mod_path)
2297+
self.resolve_variant_on_alias(node, ty, unresolved, mod_path)
22942298
}
22952299
TypeNs::AdtSelfType(_) => {
22962300
// FIXME this could happen in array size expressions, once we're checking them
@@ -2322,12 +2326,13 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
23222326

23232327
fn resolve_variant_on_alias(
23242328
&mut self,
2329+
node: ExprOrPatId,
23252330
ty: Ty<'db>,
23262331
unresolved: Option<usize>,
23272332
path: &ModPath,
23282333
) -> (Ty<'db>, Option<VariantId>) {
23292334
let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
2330-
let ty = self.table.try_structurally_resolve_type(ty);
2335+
let ty = self.table.try_structurally_resolve_type(node.into(), ty);
23312336
match remaining {
23322337
None => {
23332338
let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
@@ -2540,10 +2545,14 @@ impl<'db> Expectation<'db> {
25402545
/// an expected type. Otherwise, we might write parts of the type
25412546
/// when checking the 'then' block which are incompatible with the
25422547
/// 'else' branch.
2543-
fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'db>) -> Expectation<'db> {
2548+
fn adjust_for_branches(
2549+
&self,
2550+
table: &mut unify::InferenceTable<'db>,
2551+
span: Span,
2552+
) -> Expectation<'db> {
25442553
match *self {
25452554
Expectation::HasType(ety) => {
2546-
let ety = table.try_structurally_resolve_type(ety);
2555+
let ety = table.try_structurally_resolve_type(span, ety);
25472556
if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
25482557
}
25492558
Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),

crates/hir-ty/src/infer/autoderef.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::iter;
55
use rustc_ast_ir::Mutability;
66

77
use crate::{
8-
Adjust, Adjustment, OverloadedDeref,
8+
Adjust, Adjustment, OverloadedDeref, Span,
99
autoderef::{Autoderef, AutoderefCtx, AutoderefKind, GeneralAutoderef},
1010
infer::unify::InferenceTable,
1111
next_solver::{
@@ -15,12 +15,16 @@ use crate::{
1515
};
1616

1717
impl<'db> InferenceTable<'db> {
18-
pub(crate) fn autoderef(&self, base_ty: Ty<'db>) -> Autoderef<'_, 'db, usize> {
19-
Autoderef::new(&self.infer_ctxt, self.param_env, base_ty)
18+
pub(crate) fn autoderef(&self, base_ty: Ty<'db>, span: Span) -> Autoderef<'_, 'db, usize> {
19+
Autoderef::new(&self.infer_ctxt, self.param_env, base_ty, span)
2020
}
2121

22-
pub(crate) fn autoderef_with_tracking(&self, base_ty: Ty<'db>) -> Autoderef<'_, 'db> {
23-
Autoderef::new_with_tracking(&self.infer_ctxt, self.param_env, base_ty)
22+
pub(crate) fn autoderef_with_tracking(
23+
&self,
24+
base_ty: Ty<'db>,
25+
span: Span,
26+
) -> Autoderef<'_, 'db> {
27+
Autoderef::new_with_tracking(&self.infer_ctxt, self.param_env, base_ty, span)
2428
}
2529
}
2630

crates/hir-ty/src/infer/callee.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ impl<'db> InferenceContext<'_, 'db> {
4545
) -> Ty<'db> {
4646
let original_callee_ty = self.infer_expr_no_expect(callee_expr, ExprIsRead::Yes);
4747

48-
let expr_ty = self.table.try_structurally_resolve_type(original_callee_ty);
48+
let expr_ty =
49+
self.table.try_structurally_resolve_type(callee_expr.into(), original_callee_ty);
4950

50-
let mut autoderef = GeneralAutoderef::new_from_inference_context(self, expr_ty);
51+
let mut autoderef =
52+
GeneralAutoderef::new_from_inference_context(self, expr_ty, callee_expr.into());
5153
let mut result = None;
5254
let mut error_reported = false;
5355
while result.is_none() && autoderef.next().is_some() {
@@ -97,7 +99,7 @@ impl<'db> InferenceContext<'_, 'db> {
9799
};
98100

99101
// we must check that return type of called functions is WF:
100-
self.table.register_wf_obligation(output.into(), ObligationCause::new());
102+
self.table.register_wf_obligation(output.into(), ObligationCause::new(call_expr));
101103

102104
output
103105
}
@@ -110,7 +112,8 @@ impl<'db> InferenceContext<'_, 'db> {
110112
error_reported: &mut bool,
111113
) -> Option<CallStep<'db>> {
112114
let final_ty = autoderef.final_ty();
113-
let adjusted_ty = autoderef.ctx().table.try_structurally_resolve_type(final_ty);
115+
let adjusted_ty =
116+
autoderef.ctx().table.try_structurally_resolve_type(callee_expr.into(), final_ty);
114117

115118
// If the callee is a function pointer or a closure, then we're all set.
116119
match adjusted_ty.kind() {
@@ -244,8 +247,8 @@ impl<'db> InferenceContext<'_, 'db> {
244247
// is implemented, and use this information for diagnostic.
245248
autoderef
246249
.ctx()
247-
.try_overloaded_call_traits(adjusted_ty, Some(arg_exprs))
248-
.or_else(|| autoderef.ctx().try_overloaded_call_traits(adjusted_ty, None))
250+
.try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs))
251+
.or_else(|| autoderef.ctx().try_overloaded_call_traits(call_expr, adjusted_ty, None))
249252
.map(|(autoref, method)| {
250253
let adjustments = autoderef.adjust_steps_as_infer_ok();
251254
let mut adjustments = autoderef.ctx().table.register_infer_ok(adjustments);
@@ -257,6 +260,7 @@ impl<'db> InferenceContext<'_, 'db> {
257260

258261
fn try_overloaded_call_traits(
259262
&mut self,
263+
call_expr: ExprId,
260264
adjusted_ty: Ty<'db>,
261265
opt_arg_exprs: Option<&[ExprId]>,
262266
) -> Option<(Option<Adjustment>, MethodCallee<'db>)> {
@@ -312,7 +316,7 @@ impl<'db> InferenceContext<'_, 'db> {
312316
// one which may apply. So if we treat opaques as inference variables
313317
// `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen.
314318
if let Some(ok) = self.table.lookup_method_for_operator(
315-
ObligationCause::new(),
319+
ObligationCause::new(call_expr),
316320
method_name,
317321
trait_def_id,
318322
adjusted_ty,
@@ -470,8 +474,9 @@ impl<'db> InferenceContext<'_, 'db> {
470474
&& let Some(ty) = fn_sig.inputs().last().copied()
471475
&& let Some(tuple_trait) = self.lang_items.Tuple
472476
{
473-
self.table.register_bound(ty, tuple_trait, ObligationCause::new());
474-
self.require_type_is_sized(ty);
477+
let span = arg_exprs.last().copied().unwrap_or(call_expr);
478+
self.table.register_bound(ty, tuple_trait, ObligationCause::new(span));
479+
self.require_type_is_sized(ty, span.into());
475480
}
476481

477482
fn_sig.output()
@@ -544,7 +549,7 @@ impl<'a, 'db> DeferredCallResolution<'db> {
544549
assert!(ctx.infcx().closure_kind(self.closure_ty).is_some());
545550

546551
// We may now know enough to figure out fn vs fnmut etc.
547-
match ctx.try_overloaded_call_traits(self.closure_ty, None) {
552+
match ctx.try_overloaded_call_traits(self.call_expr, self.closure_ty, None) {
548553
Some((autoref, method_callee)) => {
549554
// One problem is that when we get here, we are going
550555
// to have a newly instantiated function signature

0 commit comments

Comments
 (0)