Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix struct_tail_raw argument order and ObligationCause usage #138456

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

JumpiiX
Copy link

@JumpiiX JumpiiX commented Mar 13, 2025

Fixes #135629

This PR updates struct_tail_raw to correctly order its parameters by moving the closure before ObligationCause. This resolves type mismatch errors and ensures that all call sites pass the correct number of arguments.

Changes:

  • Reordered parameters in struct_tail_raw
  • Updated all call sites to match the new signature
  • Ensured that ObligationCause is correctly used where required
  • Fixed related type mismatch issues

@rustbot
Copy link
Collaborator

rustbot commented Mar 13, 2025

r? @cjgillot

rustbot has assigned @cjgillot.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 13, 2025
@rustbot
Copy link
Collaborator

rustbot commented Mar 13, 2025

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

@rust-log-analyzer
Copy link
Collaborator

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
  make \
---

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#12 3.044 Building wheels for collected packages: reuse
#12 3.045   Building wheel for reuse (pyproject.toml): started
#12 3.257   Building wheel for reuse (pyproject.toml): finished with status 'done'
#12 3.258   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132720 sha256=0c2fd2aaf7b0bf8d6e131220aff14712a774c2ca462f3204d25460cbcf610b63
#12 3.258   Stored in directory: /tmp/pip-ephem-wheel-cache-hd2_3k8z/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#12 3.260 Successfully built reuse
#12 3.260 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#12 3.656 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#12 3.656 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 4.188 Collecting virtualenv
#12 4.258   Downloading virtualenv-20.29.3-py3-none-any.whl (4.3 MB)
#12 4.363      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3/4.3 MB 42.5 MB/s eta 0:00:00
#12 4.404 Collecting distlib<1,>=0.3.7
#12 4.419   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#12 4.426      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 90.2 MB/s eta 0:00:00
#12 4.460 Collecting platformdirs<5,>=3.9.1
#12 4.474   Downloading platformdirs-4.3.6-py3-none-any.whl (18 kB)
#12 4.512 Collecting filelock<4,>=3.12.2
#12 4.526   Downloading filelock-3.17.0-py3-none-any.whl (16 kB)
#12 4.608 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#12 4.789 Successfully installed distlib-0.3.9 filelock-3.17.0 platformdirs-4.3.6 virtualenv-20.29.3
#12 4.789 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 DONE 4.9s

#13 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#13 DONE 0.0s
---
DirectMap4k:      122816 kB
DirectMap2M:     5120000 kB
DirectMap1G:    13631488 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
   Compiling tidy v0.1.0 (/checkout/src/tools/tidy)
    Finished `release` profile [optimized] target(s) in 36.86s
##[endgroup]
fmt check
Diff in /checkout/compiler/rustc_middle/src/ty/sty.rs:1703:
         tcx: TyCtxt<'tcx>,
         normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
     ) -> Result<Ty<'tcx>, Ty<'tcx>> {
-        let tail = tcx.struct_tail_raw(
-            self,
-            normalize,
-            || {},
-            ObligationCause::dummy(),
-        );
+        let tail = tcx.struct_tail_raw(self, normalize, || {}, ObligationCause::dummy());
         match tail.kind() {
             // Sized types
             ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
Diff in /checkout/compiler/rustc_middle/src/ty/layout.rs:22:
 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::traits::ObligationCause;
 use crate::ty::normalize_erasing_regions::NormalizationError;
 use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};
 
Diff in /checkout/compiler/rustc_hir_analysis/src/check/check.rs:34:
 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::*;
+use crate::traits::ObligationCause;
 
 pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
     if !tcx.sess.target.is_abi_supported(abi) {
Diff in /checkout/compiler/rustc_hir_analysis/src/check/check.rs:971:
                 })
             },
             || (),
-            ObligationCause::dummy()
+            ObligationCause::dummy(),
---
+use crate::traits::ObligationCause;
 use crate::ty::fold::fold_regions;
 use crate::ty::layout::{FloatExt, IntegerExt};
 use crate::ty::{
Diff in /checkout/compiler/rustc_middle/src/ty/util.rs:221:
         tcx.struct_tail_raw(
             ty,
             |ty| tcx.normalize_erasing_regions(typing_env, ty),
-            || {}, // ✅ Closure goes **before** ObligationCause
+            || {},                    // ✅ Closure goes **before** ObligationCause
             ObligationCause::dummy(), // ✅ ObligationCause is **last**
         )
     }
Diff in /checkout/compiler/rustc_middle/src/ty/util.rs:318:
 
         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
Diff in /checkout/compiler/rustc_const_eval/src/const_eval/valtrees.rs:1:
 use rustc_abi::{BackendRepr, VariantIdx};
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo};
 use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Ty, TyCtxt};
Diff in /checkout/compiler/rustc_const_eval/src/const_eval/valtrees.rs:11:
 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,
Diff in /checkout/compiler/rustc_const_eval/src/const_eval/valtrees.rs:204:
             last_valtree = *branches.last().unwrap();
             debug!(?branches, ?last_valtree);
         },
-        ObligationCause::dummy()
+        ObligationCause::dummy(),
     );
 
---
                             )
-                                .value
+                            .value
                         },
-                        || {}, // ✅ Move closure before ObligationCause
+                        || {},                    // ✅ Move closure before ObligationCause
                         obligation.cause.clone(), // ✅ ObligationCause must be last
                     );
-
 
                     match tail.kind() {
                         ty::Bool
---
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{
Diff in /checkout/compiler/rustc_ty_utils/src/layout.rs:22:
 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;
Diff in /checkout/compiler/rustc_ty_utils/src/layout.rs:305:
 
             let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
                 let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]);
-                let metadata_ty =
-                    match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) {
-                        Ok(metadata_ty) => metadata_ty,
-                        Err(mut err) => {
-                            // Usually `<Ty as Pointee>::Metadata` can't be normalized because
-                            // its struct tail cannot be normalized either, so try to get a
-                            // more descriptive layout error here, which will lead to less confusing
-                            // diagnostics.
-                            //
-                            // We use the raw struct tail function here to get the first tail
-                            // that is an alias, which is likely the cause of the normalization
-                            // error.
-                            match tcx.try_normalize_erasing_regions(
-                                cx.typing_env,
-                                tcx.struct_tail_raw(pointee, |ty| ty, || {}, ObligationCause::dummy()),
-                            ) {
-                                Ok(_) => {}
-                                Err(better_err) => {
-                                    err = better_err;
-                                }
+                let metadata_ty = match tcx
+                    .try_normalize_erasing_regions(cx.typing_env, pointee_metadata)
+                {
+                    Ok(metadata_ty) => metadata_ty,
+                    Err(mut err) => {
+                        // Usually `<Ty as Pointee>::Metadata` can't be normalized because
+                        // its struct tail cannot be normalized either, so try to get a
+                        // more descriptive layout error here, which will lead to less confusing
+                        // diagnostics.
+                        //
+                        // We use the raw struct tail function here to get the first tail
+                        // that is an alias, which is likely the cause of the normalization
+                        // error.
+                        match tcx.try_normalize_erasing_regions(
+                            cx.typing_env,
+                            tcx.struct_tail_raw(pointee, |ty| ty, || {}, ObligationCause::dummy()),
+                        ) {
+                            Ok(_) => {}
+                            Err(better_err) => {
+                                err = better_err;
                             }
-                            return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
                         }
-                    };
+                        return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
+                    }
+                };
 
                 let metadata_layout = cx.layout_of(metadata_ty)?;
                 // If the metadata is a 1-zst, then the pointer is thin.
Diff in /checkout/compiler/rustc_hir_typeck/src/expectation.rs:1:
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
 
Diff in /checkout/compiler/rustc_hir_typeck/src/expectation.rs:4:
 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)]
Diff in /checkout/compiler/rustc_hir_typeck/src/expectation.rs:77:
     /// 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, || {}, ObligationCause::dummy()).kind()
-        {
+        match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}, ObligationCause::dummy()).kind() {
             ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
             _ => ExpectHasType(ty),
         }
Diff in /checkout/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:19:
 };
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
+use rustc_infer::traits::ObligationCause;
 use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::fold::TypeFoldable;
Diff in /checkout/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:38:
 };
 use tracing::{debug, instrument};
 
-use rustc_infer::traits::ObligationCause;
 use crate::callee::{self, DeferredCallResolution};
 use crate::errors::{self, CtorIsPrivate};
 use crate::method::{self, MethodCallee};
Diff in /checkout/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:430:
 
     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)
-                }
-            }, || {}, ObligationCause::dummy());
+            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.
fmt: checked 5903 files
Build completed unsuccessfully in 0:01:18
  local time: Thu Mar 13 15:33:19 UTC 2025
  network time: Thu, 13 Mar 2025 15:33:19 GMT

@compiler-errors
Copy link
Member

compiler-errors commented Mar 13, 2025

This is a lot of churn stylistically for a singular change, because of the fact that this is added as the last argument rather than allowing the closures to be the final arguments which affects the formatting. Please add this argument as the 2nd argument.

Please also add a test in tests/ui that demonstrates that this actually fixes the issue you linked.

Finally, this is 11 commits for 11 files worth of change. Please squash this into one commit. Thanks

@compiler-errors
Copy link
Member

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Give recursion limit errors a span
5 participants