Skip to content

Refactor fallibility of conversions from IR to Rust types #581

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

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Mar 14, 2017

The old ToRustTy and ItemToRustTy conversion traits were problematic in that they assumed infallibity. That assumption is problematic because we are often dealing with C++ constructs for which Rust has no equivalent and we don't have a usable layout from which to generate an opaque blob in its stead. But, a usable layout is often "up the stack" if only we had a way to get up there.

For example, Rust does not currently have an equivalent of const value template parameters, and libclang will not give us a layout for template definitions with const value template parameters. However, libclang will give us the layout for an instantiation of such a template definition.

First, this commit separates the concepts of generating an equivalent Rust type from generating an opaque blob of the same size and alignment as an IR thing. This consolidates and DRYs up a ton of code involved in falling back to an opaque blob (and doing our best to get a Layout for the blob) when we can't generate an equivalent Rust type for some IR thing.

Second, it separates fallible and infallible conversions, and provides a nice little framework for when to choose which. This gives us one single place where we do this whole dance:

if could not generate equivalent Rust type:
    if we have a layout:
        return opaque blob based on layout
    else:
        return opaque blob based on a wish and a prayer

The ToRustTy trait is replaced by the TryToOpaque, ToOpaque, TryToRustTyOrOpaque, and ToRustTyOrOpaque traits. The ItemToRustTy helper was just a way to avoid ToRustTy's Self::Extra parameter when it was not needed, and is simply removed without a replacement. We suck it up and pass &() at call sites now. We could introduce ItemTryToOpaque, ItemToOpaque, etc... traits, but the cost of the added boiler plate would outweigh the benefits of not passing &() at call sites, IMHO.

In addition to being a nice code cleanup, this also fixes #573.

r? @emilio

@highfive
Copy link

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

primitive_ty(ctx, "isize")
}
_ => return None,
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: remove this leftover from rebasing away a bad cargo fmt.

@fitzgen
Copy link
Member Author

fitzgen commented Mar 15, 2017

Also, I should add the original test case from #573 (comment) to our test suite.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with the documented variants and the cleaned up rustfmt code.

Thanks!

/// Errors that can occur during code generation.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
NoLayoutForOpaqueBlob,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document the variants, please :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing :)


/// Errors that can occur during code generation.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like an overly generic name for a really specific error kind. I don't have a clearly better name in mind though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is namespaced, however. I hope that it can become the error type for all fallible codegen operations.

@fitzgen fitzgen force-pushed the issue-573-even-more-spidermonkey-layout-test-failures branch from 30267de to b312c9c Compare March 15, 2017 17:31
@fitzgen
Copy link
Member Author

fitzgen commented Mar 15, 2017

@bors-servo r=emilio

@bors-servo
Copy link

📌 Commit b312c9c has been approved by emilio

@bors-servo
Copy link

🔒 Merge conflict

@bors-servo
Copy link

☔ The latest upstream changes (presumably #583) made this pull request unmergeable. Please resolve the merge conflicts.

The old ToRustTy and ItemToRustTy conversion traits were problematic
in that they assumed infallibity. That assumption is problematic
because we are often dealing with C++ constructs for which Rust has no
equivalent *and* we don't have a usable layout from which to generate
an opaque blob in its stead. But, a usable layout is often "up the
stack" if only we had a way to get up there.

For example, Rust does not currently have an equivalent of const value
template parameters, and libclang will not give us a layout for
template definitions with const value template parameters. However,
libclang will give us the layout for an instantiation of such a
template definition.

First, this commit separates the concepts of generating an equivalent
Rust type from generating an opaque blob of the same size and
alignment as an IR thing. This consolidates and DRYs up a *ton* of
code involved in falling back to an opaque blob (and doing our best to
get a Layout for the blob) when we can't generate an equivalent Rust
type for some IR thing.

Second, it separates fallible and infallible conversions, and provides
a nice little framework for when to choose which. This gives us one
single place where we do this whole dance:

    if could not generate equivalent Rust type:
        if we have a layout:
            return opaque blob based on layout
        else:
            return opaque blob based on a wish and a prayer

The ToRustTy trait is replaced by the TryToOpaque, ToOpaque,
TryToRustTyOrOpaque, and ToRustTyOrOpaque traits. The ItemToRustTy
helper was just a way to avoid ToRustTy's Self::Extra parameter when
it was not needed, and is simply removed without a replacement. We
suck it up and pass `&()` at call sites now. We *could* introduce
ItemTryToOpaque, ItemToOpaque, etc... traits, but the cost of the
added boiler plate would outweigh the benefits of not passing `&()` at
call sites, IMHO.

In addition to being a nice code cleanup, this also fixes rust-lang#573.
@fitzgen fitzgen force-pushed the issue-573-even-more-spidermonkey-layout-test-failures branch from b312c9c to 92c1a25 Compare March 15, 2017 17:50
@fitzgen
Copy link
Member Author

fitzgen commented Mar 15, 2017

@bors-servo r=emilio

@bors-servo
Copy link

📌 Commit 92c1a25 has been approved by emilio

@bors-servo
Copy link

⌛ Testing commit 92c1a25 with merge 4bc1336...

bors-servo pushed a commit that referenced this pull request Mar 15, 2017
…test-failures, r=emilio

Refactor fallibility of conversions from IR to Rust types

The old `ToRustTy` and `ItemToRustTy` conversion traits were problematic in that they assumed infallibity. That assumption is problematic because we are often dealing with C++ constructs for which Rust has no equivalent *and* we don't have a usable layout from which to generate an opaque blob in its stead. But, a usable layout is often "up the stack" if only we had a way to get up there.

For example, Rust does not currently have an equivalent of const value template parameters, and libclang will not give us a layout for template definitions with const value template parameters. However, libclang will give us the layout for an instantiation of such a template definition.

First, this commit separates the concepts of generating an equivalent Rust type from generating an opaque blob of the same size and alignment as an IR thing. This consolidates and DRYs up a *ton* of code involved in falling back to an opaque blob (and doing our best to get a `Layout` for the blob) when we can't generate an equivalent Rust type for some IR thing.

Second, it separates fallible and infallible conversions, and provides a nice little framework for when to choose which. This gives us one single place where we do this whole dance:

    if could not generate equivalent Rust type:
        if we have a layout:
            return opaque blob based on layout
        else:
            return opaque blob based on a wish and a prayer

The `ToRustTy` trait is replaced by the `TryToOpaque`, `ToOpaque`, `TryToRustTyOrOpaque`, and `ToRustTyOrOpaque` traits. The `ItemToRustTy` helper was just a way to avoid `ToRustTy`'s `Self::Extra` parameter when it was not needed, and is simply removed without a replacement. We suck it up and pass `&()` at call sites now. We *could* introduce `ItemTryToOpaque`, `ItemToOpaque`, etc... traits, but the cost of the added boiler plate would outweigh the benefits of not passing `&()` at call sites, IMHO.

In addition to being a nice code cleanup, this also fixes #573.

r? @emilio
@bors-servo
Copy link

☀️ Test successful - status-travis
Approved by: emilio
Pushing 4bc1336 to master...

@bors-servo bors-servo merged commit 92c1a25 into rust-lang:master Mar 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Even more failing layout tests with SpiderMonkey bindings
4 participants