Skip to content

Commit b7ab58e

Browse files
authored
Rollup merge of rust-lang#146597 - modhanami:add-struct-tail-recursion-limit-span, r=oli-obk
Add span for struct tail recursion limit error Fixes rust-lang#135629 Changes 1. Add span to RecursionLimitReached 2. Add ObligationCause parameter to struct_tail_raw 4. Update call sites to pass nearby ObligationCause or create one 5. Update affected .stderr
2 parents fd852f4 + 6912631 commit b7ab58e

File tree

19 files changed

+111
-65
lines changed

19 files changed

+111
-65
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
230230
location: impl NormalizeLocation,
231231
) -> Ty<'tcx> {
232232
let tcx = self.tcx();
233+
let body = self.body;
234+
235+
let cause = ObligationCause::misc(
236+
location.to_locations().span(body),
237+
body.source.def_id().expect_local(),
238+
);
239+
233240
if self.infcx.next_trait_solver() {
234-
let body = self.body;
235241
let param_env = self.infcx.param_env;
236242
// FIXME: Make this into a real type op?
237243
self.fully_perform_op(
@@ -241,10 +247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
241247
|ocx| {
242248
let structurally_normalize = |ty| {
243249
ocx.structurally_normalize_ty(
244-
&ObligationCause::misc(
245-
location.to_locations().span(body),
246-
body.source.def_id().expect_local(),
247-
),
250+
&cause,
248251
param_env,
249252
ty,
250253
)
@@ -253,6 +256,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
253256

254257
let tail = tcx.struct_tail_raw(
255258
ty,
259+
&cause,
256260
structurally_normalize,
257261
|| {},
258262
);
@@ -265,7 +269,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
265269
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
266270
} else {
267271
let mut normalize = |ty| self.normalize(ty, location);
268-
let tail = tcx.struct_tail_raw(ty, &mut normalize, || {});
272+
let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {});
269273
normalize(tail)
270274
}
271275
}

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
22
use rustc_data_structures::stack::ensure_sufficient_stack;
33
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError};
4+
use rustc_middle::traits::ObligationCause;
45
use rustc_middle::ty::layout::{LayoutCx, TyAndLayout};
56
use rustc_middle::ty::{self, Ty, TyCtxt};
67
use rustc_middle::{bug, mir};
@@ -196,6 +197,7 @@ fn reconstruct_place_meta<'tcx>(
196197
// Traverse the type, and update `last_valtree` as we go.
197198
let tail = tcx.struct_tail_raw(
198199
layout.ty,
200+
&ObligationCause::dummy(),
199201
|ty| ty,
200202
|| {
201203
let branches = last_valtree.unwrap_branch();

compiler/rustc_hir_typeck/src/expectation.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_middle::traits::ObligationCause;
12
use rustc_middle::ty::{self, Ty};
23
use rustc_span::Span;
34

@@ -74,8 +75,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
7475
/// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
7576
/// for examples of where this comes up,.
7677
pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
78+
let span = match ty.kind() {
79+
ty::Adt(adt_def, _) => fcx.tcx.def_span(adt_def.did()),
80+
_ => fcx.tcx.def_span(fcx.body_id),
81+
};
82+
let cause = ObligationCause::misc(span, fcx.body_id);
83+
7784
// FIXME: This is not right, even in the old solver...
78-
match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}).kind() {
85+
match fcx.tcx.struct_tail_raw(ty, &cause, |ty| ty, || {}).kind() {
7986
ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
8087
_ => ExpectHasType(ty),
8188
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
424424
if !ty.references_error() {
425425
let tail = self.tcx.struct_tail_raw(
426426
ty,
427+
&self.misc(span),
427428
|ty| {
428429
if self.next_trait_solver() {
429430
self.try_structurally_resolve_type(span, ty)

compiler/rustc_middle/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pub enum TypeMismatchReason {
7171
#[diag(middle_recursion_limit_reached)]
7272
#[help]
7373
pub(crate) struct RecursionLimitReached<'tcx> {
74+
#[primary_span]
75+
pub span: Span,
7476
pub ty: Ty<'tcx>,
7577
pub suggested_limit: rustc_hir::limit::Limit,
7678
}

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use {rustc_abi as abi, rustc_hir as hir};
2222

2323
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
2424
use crate::query::TyCtxtAt;
25+
use crate::traits::ObligationCause;
2526
use crate::ty::normalize_erasing_regions::NormalizationError;
2627
use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};
2728

@@ -384,6 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
384385

385386
let tail = tcx.struct_tail_raw(
386387
pointee,
388+
&ObligationCause::dummy(),
387389
|ty| match tcx.try_normalize_erasing_regions(typing_env, ty) {
388390
Ok(ty) => ty,
389391
Err(e) => Ty::new_error_with_message(

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use ty::util::IntTypeExt;
2323

2424
use super::GenericParamDefKind;
2525
use crate::infer::canonical::Canonical;
26+
use crate::traits::ObligationCause;
2627
use crate::ty::InferTy::*;
2728
use crate::ty::{
2829
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
@@ -1638,7 +1639,7 @@ impl<'tcx> Ty<'tcx> {
16381639
tcx: TyCtxt<'tcx>,
16391640
normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
16401641
) -> Result<Ty<'tcx>, Ty<'tcx>> {
1641-
let tail = tcx.struct_tail_raw(self, normalize, || {});
1642+
let tail = tcx.struct_tail_raw(self, &ObligationCause::dummy(), normalize, || {});
16421643
match tail.kind() {
16431644
// Sized types
16441645
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))

compiler/rustc_middle/src/ty/util.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use super::TypingEnv;
2424
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
2525
use crate::mir;
2626
use crate::query::Providers;
27+
use crate::traits::ObligationCause;
2728
use crate::ty::layout::{FloatExt, IntegerExt};
2829
use crate::ty::{
2930
self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
@@ -216,7 +217,12 @@ impl<'tcx> TyCtxt<'tcx> {
216217
typing_env: ty::TypingEnv<'tcx>,
217218
) -> Ty<'tcx> {
218219
let tcx = self;
219-
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {})
220+
tcx.struct_tail_raw(
221+
ty,
222+
&ObligationCause::dummy(),
223+
|ty| tcx.normalize_erasing_regions(typing_env, ty),
224+
|| {},
225+
)
220226
}
221227

222228
/// Returns true if a type has metadata.
@@ -248,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
248254
pub fn struct_tail_raw(
249255
self,
250256
mut ty: Ty<'tcx>,
257+
cause: &ObligationCause<'tcx>,
251258
mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
252259
// This is currently used to allow us to walk a ValTree
253260
// in lockstep with the type in order to get the ValTree branch that
@@ -261,9 +268,11 @@ impl<'tcx> TyCtxt<'tcx> {
261268
Limit(0) => Limit(2),
262269
limit => limit * 2,
263270
};
264-
let reported = self
265-
.dcx()
266-
.emit_err(crate::error::RecursionLimitReached { ty, suggested_limit });
271+
let reported = self.dcx().emit_err(crate::error::RecursionLimitReached {
272+
span: cause.span,
273+
ty,
274+
suggested_limit,
275+
});
267276
return Ty::new_error(self, reported);
268277
}
269278
match *ty.kind() {

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10571057
Some(LangItem::PointeeTrait) => {
10581058
let tail = selcx.tcx().struct_tail_raw(
10591059
self_ty,
1060+
&obligation.cause,
10601061
|ty| {
10611062
// We throw away any obligations we get from this, since we normalize
10621063
// and confirm these obligations once again during confirmation

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hashes::Hash64;
1010
use rustc_index::IndexVec;
1111
use rustc_middle::bug;
1212
use rustc_middle::query::Providers;
13+
use rustc_middle::traits::ObligationCause;
1314
use rustc_middle::ty::layout::{
1415
FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout,
1516
};
@@ -390,30 +391,31 @@ fn layout_of_uncached<'tcx>(
390391

391392
let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
392393
let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]);
393-
let metadata_ty =
394-
match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) {
395-
Ok(metadata_ty) => metadata_ty,
396-
Err(mut err) => {
397-
// Usually `<Ty as Pointee>::Metadata` can't be normalized because
398-
// its struct tail cannot be normalized either, so try to get a
399-
// more descriptive layout error here, which will lead to less confusing
400-
// diagnostics.
401-
//
402-
// We use the raw struct tail function here to get the first tail
403-
// that is an alias, which is likely the cause of the normalization
404-
// error.
405-
match tcx.try_normalize_erasing_regions(
406-
cx.typing_env,
407-
tcx.struct_tail_raw(pointee, |ty| ty, || {}),
408-
) {
409-
Ok(_) => {}
410-
Err(better_err) => {
411-
err = better_err;
412-
}
394+
let metadata_ty = match tcx
395+
.try_normalize_erasing_regions(cx.typing_env, pointee_metadata)
396+
{
397+
Ok(metadata_ty) => metadata_ty,
398+
Err(mut err) => {
399+
// Usually `<Ty as Pointee>::Metadata` can't be normalized because
400+
// its struct tail cannot be normalized either, so try to get a
401+
// more descriptive layout error here, which will lead to less confusing
402+
// diagnostics.
403+
//
404+
// We use the raw struct tail function here to get the first tail
405+
// that is an alias, which is likely the cause of the normalization
406+
// error.
407+
match tcx.try_normalize_erasing_regions(
408+
cx.typing_env,
409+
tcx.struct_tail_raw(pointee, &ObligationCause::dummy(), |ty| ty, || {}),
410+
) {
411+
Ok(_) => {}
412+
Err(better_err) => {
413+
err = better_err;
413414
}
414-
return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
415415
}
416-
};
416+
return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
417+
}
418+
};
417419

418420
let metadata_layout = cx.layout_of(metadata_ty)?;
419421
// If the metadata is a 1-zst, then the pointer is thin.

0 commit comments

Comments
 (0)