Skip to content

Method call resolution behavioral changes on custom DSTs in Rust 1.70 -> 1.71 #114928

Closed
@ZhennanWu

Description

@ZhennanWu

I tried this code:

use std::any::TypeId;
use std::any::Any;
use std::hint::black_box;
struct A<T:?Sized+'static> {
    a: i32,
    b: T
}

impl<T:?Sized+'static> A<T> {
    fn bb(&self) -> TypeId {
        self.b.type_id()
    }
}

pub fn main() {
    let mut a0 = A{a: 8, b: 9 as i32};
    let mut a: &mut A<dyn Any> = &mut a0;
    println!("{:?}",a.bb());
    println!("{:?}",a.b.type_id());
    println!("{:?}",std::any::TypeId::of::<i32>());
}

I expected to see this happen: The three printed TypeIds should be identical, as with the behavior in Rust <=1.70

Instead, this happened:

Program returned: 0
TypeId { t: 2368704253749761200 }
TypeId { t: 5817408772836814867 }
TypeId { t: 5817408772836814867 }

Meta

https://godbolt.org/z/8vvr37Ynf switch between rust versions.

I could not find reference in the 1.71 RELEASES that could explain such behavioral changes.

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Aug 17, 2023
added
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Aug 17, 2023
added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Aug 17, 2023
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Aug 17, 2023
apiraino

apiraino commented on Aug 17, 2023

@apiraino
Contributor

if my bisection is correct, this surfaced in commit 5546cb6

cc @saethlin (makes sense?)

saethlin

saethlin commented on Aug 17, 2023

@saethlin
Member

I do not believe that is the correct PR to point at. Bisecting anything related to MIR opts can be tricky because you need to stabilize the MIR opt pipeline against changes like in that PR which don't actually implement any new behavior, they just change the meaning of MIR opt levels.

Try bisecting with -Zmir-opt-level=3? The above PR just changes the opt level 3 inliner behavior to be the default.

compiler-errors

compiler-errors commented on Aug 17, 2023

@compiler-errors
Member

Reproduces since before 2021-01-01 with -Zmir-opt-level=3

compiler-errors

compiler-errors commented on Aug 17, 2023

@compiler-errors
Member

This has to do with the fact that this impl: https://doc.rust-lang.org/std/any/trait.Any.html#impl-Any-for-T ... applies even when T = dyn Any.

Therefore in a polymorphic function like bb, we're eagerly inlining type_id from that impl even though during monomorphization we'd prefer the <dyn Any as Any>::type_id built-in candidate instead.

This seems problematic.

apiraino

apiraino commented on Aug 18, 2023

@apiraino
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-high

added
P-highHigh priority
and removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Aug 18, 2023

6 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-mir-opt-inliningArea: MIR inliningC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @compiler-errors@apiraino@saethlin@ZhennanWu@rustbot

      Issue actions

        Method call resolution behavioral changes on custom DSTs in Rust 1.70 -> 1.71 · Issue #114928 · rust-lang/rust