Skip to content
9 changes: 3 additions & 6 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
};

let tail = tcx.struct_tail_raw(
ty,
structurally_normalize,
|| {},
);
let tail = tcx.struct_tail_raw(ty, structurally_normalize, || {}, ObligationCause::dummy());


Ok(tail)
},
Expand All @@ -222,7 +219,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
} else {
let mut normalize = |ty| self.normalize(ty, location);
let tail = tcx.struct_tail_raw(ty, &mut normalize, || {});
let tail = tcx.struct_tail_raw(ty, &mut normalize, || {}, ObligationCause::dummy());
normalize(tail)
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::eval_queries::{mk_eval_cx_to_read_const_val, op_to_const};
use super::machine::CompileTimeInterpCx;
use super::{VALTREE_MAX_NODES, ValTreeCreationError, ValTreeCreationResult};
use crate::const_eval::CanAccessMutGlobal;
use rustc_infer::traits::ObligationCause;
use crate::errors::MaxNumNodesInConstErr;
use crate::interpret::{
ImmTy, Immediate, InternKind, MPlaceTy, MemPlaceMeta, MemoryKind, PlaceTy, Projectable, Scalar,
Expand Down Expand Up @@ -203,7 +204,9 @@ fn reconstruct_place_meta<'tcx>(
last_valtree = *branches.last().unwrap();
debug!(?branches, ?last_valtree);
},
ObligationCause::dummy()
);

// Sanity-check that we got a tail we support.
match tail.kind() {
ty::Slice(..) | ty::Str => {}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ use tracing::{debug, instrument};
use ty::TypingMode;
use {rustc_attr_parsing as attr, rustc_hir as hir};

use crate::traits::ObligationCause;

use super::compare_impl_item::check_type_bounds;
use super::*;

Expand Down Expand Up @@ -969,6 +971,7 @@ fn check_impl_items_against_trait<'tcx>(
})
},
|| (),
ObligationCause::dummy()
)
.kind()
{
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_hir_typeck/src/expectation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use rustc_span::Span;
use super::Expectation::*;
use super::FnCtxt;

use rustc_infer::traits::ObligationCause;

/// When type-checking an expression, we propagate downward
/// whatever type hint we are able in the form of an `Expectation`.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -75,7 +77,8 @@ impl<'a, 'tcx> Expectation<'tcx> {
/// for examples of where this comes up,.
pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
// FIXME: This is not right, even in the old solver...
match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}).kind() {
match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}, ObligationCause::dummy()).kind()
{
ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
_ => ExpectHasType(ty),
}
Expand Down
19 changes: 8 additions & 11 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use rustc_trait_selection::traits::{
};
use tracing::{debug, instrument};

use rustc_infer::traits::ObligationCause;
use crate::callee::{self, DeferredCallResolution};
use crate::errors::{self, CtorIsPrivate};
use crate::method::{self, MethodCallee};
Expand Down Expand Up @@ -429,17 +430,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub(crate) fn require_type_has_static_alignment(&self, ty: Ty<'tcx>, span: Span) {
if !ty.references_error() {
let tail = self.tcx.struct_tail_raw(
ty,
|ty| {
if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty)
} else {
self.normalize(span, ty)
}
},
|| {},
);
let tail = self.tcx.struct_tail_raw(ty, |ty| {
if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty)
} else {
self.normalize(span, ty)
}
}, || {}, ObligationCause::dummy());
// Sized types have static alignment, and so do slices.
if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) {
// Nothing else is required here.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ pub enum TypeMismatchReason {
#[diag(middle_recursion_limit_reached)]
#[help]
pub(crate) struct RecursionLimitReached<'tcx> {
#[primary_span]
pub span: Span,
pub ty: Ty<'tcx>,
pub suggested_limit: rustc_session::Limit,
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc_target::spec::{
use tracing::debug;
use {rustc_abi as abi, rustc_hir as hir};

use crate::traits::ObligationCause;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::TyCtxtAt;
use crate::ty::normalize_erasing_regions::NormalizationError;
Expand Down Expand Up @@ -398,6 +399,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
),
},
|| {},
ObligationCause::dummy(),
);

match tail.kind() {
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use ty::util::{AsyncDropGlueMorphology, IntTypeExt};

use super::GenericParamDefKind;
use crate::infer::canonical::Canonical;
use crate::traits::ObligationCause;
use crate::ty::InferTy::*;
use crate::ty::{
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
Expand Down Expand Up @@ -1702,7 +1703,12 @@ impl<'tcx> Ty<'tcx> {
tcx: TyCtxt<'tcx>,
normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
) -> Result<Ty<'tcx>, Ty<'tcx>> {
let tail = tcx.struct_tail_raw(self, normalize, || {});
let tail = tcx.struct_tail_raw(
self,
normalize,
|| {},
ObligationCause::dummy(),
);
match tail.kind() {
// Sized types
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
Expand Down
30 changes: 20 additions & 10 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use tracing::{debug, instrument};

use super::TypingEnv;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::traits::ObligationCause;
use crate::mir;
use crate::query::Providers;
use crate::ty::fold::fold_regions;
Expand Down Expand Up @@ -217,7 +218,12 @@ impl<'tcx> TyCtxt<'tcx> {
typing_env: ty::TypingEnv<'tcx>,
) -> Ty<'tcx> {
let tcx = self;
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {})
tcx.struct_tail_raw(
ty,
|ty| tcx.normalize_erasing_regions(typing_env, ty),
|| {}, // ✅ Closure goes **before** ObligationCause
ObligationCause::dummy(), // ✅ ObligationCause is **last**
)
}

/// Returns true if a type has metadata.
Expand Down Expand Up @@ -250,23 +256,27 @@ impl<'tcx> TyCtxt<'tcx> {
self,
mut ty: Ty<'tcx>,
mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
// This is currently used to allow us to walk a ValTree
// in lockstep with the type in order to get the ValTree branch that
// corresponds to an unsized field.
mut f: impl FnMut() -> (),
obligation_cause: ObligationCause<'tcx>,
) -> Ty<'tcx> {
let recursion_limit = self.recursion_limit();

for iteration in 0.. {
if !recursion_limit.value_within_limit(iteration) {
let suggested_limit = match recursion_limit {
Limit(0) => Limit(2),
limit => limit * 2,
};
let reported = self
.dcx()
.emit_err(crate::error::RecursionLimitReached { ty, suggested_limit });

let reported = self.dcx().emit_err(crate::error::RecursionLimitReached {
ty,
suggested_limit,
span: obligation_cause.span,
});

return Ty::new_error(self, reported);
}

match *ty.kind() {
ty::Adt(def, args) => {
if !def.is_struct() {
Expand Down Expand Up @@ -302,14 +312,14 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

_ => {
break;
}
_ => break,
}
}

ty
}


/// Same as applying `struct_tail` on `source` and `target`, but only
/// keeps going as long as the two types are instances of the same
/// structure definitions.
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,20 +1106,20 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
let tail = selcx.tcx().struct_tail_raw(
self_ty,
|ty| {
// We throw away any obligations we get from this, since we normalize
// and confirm these obligations once again during confirmation
normalize_with_depth(
selcx,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
ty,
)
.value
.value
},
|| {},
|| {}, // ✅ Move closure before ObligationCause
obligation.cause.clone(), // ✅ ObligationCause must be last
);


match tail.kind() {
ty::Bool
| ty::Char
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc_span::{Symbol, sym};
use tracing::{debug, instrument};
use {rustc_abi as abi, rustc_hir as hir};

use rustc_infer::traits::ObligationCause;
use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};

mod invariant;
Expand Down Expand Up @@ -318,7 +319,7 @@ fn layout_of_uncached<'tcx>(
// error.
match tcx.try_normalize_erasing_regions(
cx.typing_env,
tcx.struct_tail_raw(pointee, |ty| ty, || {}),
tcx.struct_tail_raw(pointee, |ty| ty, || {}, ObligationCause::dummy()),
) {
Ok(_) => {}
Err(better_err) => {
Expand Down
Loading