Skip to content

extern type cannot support size_of_val and align_of_val #49708

Open
@joshtriplett

Description

@joshtriplett
Member

Based on discussion on #43467 and in @rust-lang/lang meetings, an opaque extern type type cannot support size_of_val or align_of_val. We believe that we should panic or abort in this case. We also believe that we should have a compile-time lint that detects this whenever possible, since at some level the compiler should know at compile time if code invokes size_of_val or align_of_val on an extern type.

I've opened this separate issue to document that decision, and will propose FCP on it to give time for final comments.

Activity

joshtriplett

joshtriplett commented on Apr 5, 2018

@joshtriplett
MemberAuthor

@rfcbot fcp merge

rfcbot

rfcbot commented on Apr 5, 2018

@rfcbot
Collaborator

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

added
proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
on Apr 5, 2018
kennytm

kennytm commented on Apr 5, 2018

@kennytm
Member

we should have a compile-time lint that detects this whenever possible

will the lint be emitted before or after monomorphization?

P.S. cc rust-lang/rfcs#2310

eddyb

eddyb commented on Apr 5, 2018

@eddyb
Member

I'm specifically in favor of "before", only emitting anything after monomorphization under some general umbrella of "this code will always panic at runtime" warnings.

joshtriplett

joshtriplett commented on Apr 5, 2018

@joshtriplett
MemberAuthor

It would be nice to handle generic functions that get monomorphized with an extern type, though. That will come up.

hanna-kruppe

hanna-kruppe commented on Apr 5, 2018

@hanna-kruppe
Contributor

The RFC text (and the discussion even more so, IIRC) mention the possibility of adding a new trait for encoding this constraint. I assume this has been dropped because that trait would have to be included in bounds by default like Sized?

Ericson2314

Ericson2314 commented on Apr 6, 2018

@Ericson2314
Contributor

@rkruppe yes sadly.... rust-lang/rfcs#2310 was opened as backup plan. See the end of #43467.

comex

comex commented on Apr 6, 2018

@comex
Contributor

I'm a bit confused why this is in rust-lang/rust instead of rust-lang/rfcs. (I have rust-lang/rfcs set as watched, so I get email copies of all issues and PRs there, but not here.)

joshtriplett

joshtriplett commented on Apr 6, 2018

@joshtriplett
MemberAuthor

Because it's a bug about extern type behavior.

nikomatsakis

nikomatsakis commented on Apr 10, 2018

@nikomatsakis
Contributor

@comex

I'm a bit confused why this is in rust-lang/rust instead of rust-lang/rfcs. (I have rust-lang/rfcs set as watched, so I get email copies of all issues and PRs there, but not here.)

Because this is not a new RFC, it's nailing down a specific unresolved question around extern types (though we should have linked from the tracking issue to here -- fixed). This is pretty standard practice.

jethrogb

jethrogb commented on Apr 10, 2018

@jethrogb
Contributor

Why lint when you can have type safety? Two convincing comments from the other discussion thread:

@mikeyhew #43467 (comment)

OK, I just want to say that I am very strongly of the opinion that Rust should use built-in traits like DynSized to express the difference in capabilities between extern types and the dynamically-sized types that currently exist in Rust (i.e. trait objects and slices). All of the alternatives that I have seen – panicking, returning Option from size_of_val, post-monomorphisation lints – are less powerful, and the issues with ?-traits that people keep bringing up need to be tested and not just speculated about. We need to at least try doing things the builtin-traits way and see what it's like, and see what the ergonomic impact is like, and see if we can reduce it, before settling for something inferior.

Maybe I'm overreacting, I just got the sense from reading some of the comments in this thread that something might be done in order to get extern types out the door, that might put us in a backward-compatibility trap later on. Now that I have more time to work on Rust, I'm planning on writing an eRFC to add DST-specific builtin traits like DynSized and SizeFromMeta, so we can start experimenting with them and Custom DST.

@Ericson2314 #43467 (comment)

  1. I don't think "always use the smallest tool for the job" applies here. The decreased power of lints is directly worse for uses. C.f. non-null lints v.s. Option in other languages. Lints are easily lost amid other warnings, and the fact is only some users will care. This means while individual code bases might obey them, the ecosystem as a whole can not be trusted to uphold the invariants the lints try to maintain. This a real loss for fostering an ecosystem of DynSize abstractions, or whatever the niche feature is, as for such niche things, being able to sync up few and scattered programmers and form a community is all the more important.

  2. Ecosystem-wide enforcement is also good for the "regular users don't need to care" goal. If some library happens to use truly unsized types, and the consumer is unaware, they could face some nasty unexpected packages. With ?DynSize they do get bothered with a compile time error they didn't expect, but that is much less nasty to deal with with than a run-time bug. If they don't want to learn ?DynSized, they can go use a different library; better to have the opportunity to do that up front than after you're tied to the library too deeply because it took a while to excise the {size,align}_of_val panic.

And my own perspective: there are various places where I'd like to be generic over things that the language doesn't allow. That goes hand in hand with the type system. For example, you can't be generic over lengths when using arrays or calling conventions when using function pointers. Let's not add more features in that could reasonably be described correctly in the type system but aren't.

joshtriplett

joshtriplett commented on Apr 10, 2018

@joshtriplett
MemberAuthor

@jethrogb

Why lint when you can have type safety?

If the lint is deny-by-default (which I think it should be), it'd effectively act the same as a type error. The second comment you quote seems based on the idea that it'd be a warning and not an error.

So the only difference is whether to provide a more general trait-based mechanism or to handle the specific case at hand. I haven't seen any fundamental opposition to the idea of introducing those traits in the future if we have a more general case that needs them, but if we want those traits for some future features that we haven't yet introduced to the language, let's design those traits alongside those future language features.

68 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

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-langRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @briansmith@comex@whitequark@eddyb@kennytm

        Issue actions

          `extern type` cannot support `size_of_val` and `align_of_val` · Issue #49708 · rust-lang/rust