Skip to content

ty::type_contents is too imprecise in some cases (e.g. when called from trans) #22815

@pnkfelix

Description

@pnkfelix

spawned off of #22536

@nikomatsakis tells me that trans has been migrating away from its uses of ty::type_contents (or perhaps he meant that rustc in general is migrating away from using it). But there are still places that rely on it to drive particular bits of logic.

This is problematic because ty::type_contents is designed to produce a set of properties that could hold for the given type, depending on what is substituted for its type parameters; this is in stark contrast to trans, which deals directly with a monomorphized (and normalized type), where all of the relevant information needed for codegen is readily available.

  • One might think that there is apparently no problem here at all: surely a monomorphized and normalized type has no free type parameters, and thus the question of substitutions is irrelevant?
  • Unfortunately, the way that ty::type_contents is written, it is relevant, because when you compute the type contents of a struct instance like BufferHandle<Res>, the logic of ty::type_contents recursively processes its fields (after substitution), namely the type <Res as Resources>::Buffer. But at this point, type contents just says "That's a projection; anything could be substituted in for that", and produces the most conservative result (a bitset holding all ones for the type-contents). And then that conservative result pollutes the type-contents for the whole BufferHandle<Res> overall.
  • The specific line here regarding the "That's a projection; ..." is here in ty::ty_contents.

I am going to try to fix the actual unsoundness that results from the problems above by avoiding relying on ty::type_contents as anything but an conservative approxmation within trans.

This ticket is to log the cases (in e.g. trans, but potentially also elsewhere) where there still are calls to ty:type_contents, so that we can go back and replace them with something better. (E.g., perhaps a new version of type contents has the inputs it needs to normalize types as it descends through their structure, which ty::type_contents does not currently have.)

My hope is that the cases listed on this ticket do not reflect cases where we have unsound behavior, but merely cases where we can in some cases produce lower quality code than we would otherwise.

  • Update: This description was originally written in the context of a use of ty::type_contents from trans, but pnkfelix hypothesized based on Send/Sync transitive analysis lost in stored associated types #22828 that the same problem affects other parts of the compiler true, resulting not merely in lower quality code, but also ... "expressiveness exceptions." (Better term, anyone?)

Footnote: In the concrete example of #22536, the particular issue is that the decision about whether to zero the original memory after copying-or-moving a value from one place to another is based on looking up the "needs_drop" bit in the type contents. Since the type contents is all-ones, we are meant to conclude "I guess this value might have an associated destructor." Of course, this is very wrong in the case of trans, where given "this might have an associated destructor", it is very wrong to conclude "I must need to zero the original memory where I got the value." We can (and I will) fix the particular issue of #22536 on its own. But I want to file this ticket first so that I have an issue number to put into comments near the uses of ty:type_contents that remain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-type-systemArea: Type systemC-cleanupCategory: PRs that clean code up or issues documenting cleanup.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions