Migrating back from the hackmd
- Centril to comment on floating point to integer casts can cause undefined behaviour #10184
- recommended option from the POV of the summary maker and why :)
- what options have been evaluated and what were the rezupsults
- what options exist that have not been evaluated and what are the pros/cons
- Not done yet.
- No progress
Niko to reach out to Aaron Hill about experimenting with the other approach to never type fallback- Niko to reach out to wg-grammar around writing up a “what is status” thing
- Niko to write and propose postponing rust-lang/rfcs#2545 (comment)
- Niko to prep a write-up for auto-trait-lifetime interactions
- Niko to post blog post about the April schedule and create invites
Niko to write comment onmove str to libcoregiving lang team stamp of approval- Centril left comment.
Niko to write comment on anonymous constants in #70042- Centril left comment.
Drew up an April schedule:
- April 13 — Try blocks, try traits, functions that try, oh my!
- April 20 — Edition planning
- April 27 — Type aliases
List of potential topics for May:
- ~~how to deal with type aliases and bounds~~
- ~~e.g.~~ [~~Perform WF-check on `type`s with no type parameters #69741~~](https://github.com/rust-lang/rust/issues/69741)
- lang team procedures
- Unsafe code guidelines — how to make progress
- “Copy out of references” — focus on use cases and inter-related problems
- `let foo: &Option<u32>; match foo { Some(x) => bar(x), None => ... }`
- `fn bar(x: u32)`
- `x` has type `&u32` which is annoying
- Are there examples / use cases where the fix is more complex than inserting an `&` into a pattern?
inline assembly (Amanieu, Josh)
- conflict that we need to resolve: project group creation RFC
- Current status:
- Centril has open concern
- Niko posted comment with responses to the points within
- Requesting lang-team members to actively second Centril’s concerns if they are shared (or if you feel they are not fully understood)
- Requesting comments in the summary doc containing those responses to help highlight incompleteness or inaccuracies
- RFC to rename
llvm_asm!
toasm!
merged, PR landing soon - Closed and re-opened the
asm!
RFC to summarize prior thread- New RFC is rust-lang/rfcs#2873
- Collecting feedback that was not included in the RFC
- Implementation of proposed
asm!
macro is done
safe transmute (Ryan, Josh)
- May try to start with a simplified proposal
- Start with smallest set of things we can ask the language to do
- e.g. maybe some kind of trait for “any bit pattern is acceptable”
- can maybe build on the mechanisms we have for “these types allow zero” that is used to make
mem::zeroed
panic- question: is this a precise test, or is it conservative, and is it conservative in the right way?
- currently it doesn’t panic on some types (e.g., bool) for back-compat concerns
- more of a general inspiration
- question: is this a precise test, or is it conservative, and is it conservative in the right way?
- conversations happening in #project-safe-transmute on Zulip
- 2020-04-02: Josh believes (but hasn’t had time to check) that current plans are working towards a “much reduced” proposal, will update
const evaluation (ecstatic-morse)
- Should be more active in the next few weeks!
- Currently finishing up better structural equality checks in match patterns (#67343)
- Figuring out what to prioritize next:
- Support
const
trait methods in the trait solver? - Stabilize
if
/match
in constants? - MIR optimization?
- Support
ffi-unwind (BatmanAod)
- had meeting, people writing up their current position
- initial blog post available
- subsequent discussion concluded that “option 1” is strictly worse than “option 2”
- key question to resolve:
- should we have a “C unwind” or permit unwinding in the current “C” ABI?
- did not end up gathering performance data since current proposal does not have implications
- existing comments summarizing people’s positions:
- Niko’s comment in favor of “C unwind”
- Portable, idiomatic Rust will still want to catch C++ exceptions
- Explicitly acknowledging when you are relying on foreign exceptions lets us avoid UB for panic=abort and seems to emphasize that this is an important thing to be aware of
- Forward compatible to go forward
- Centril in favor of “C unwind”:
- It means we have more latitude to change the panic implementation for Rust as we would have to add shims for fewer functions, which is a key reason why unwinding to FFI was UB in the first place.
- It seems quite problematic that
-C panic=abort
can make programs suddenly have UB. - Reasoning about higher order functions via function pointers is no longer possible.
- It is a smaller change from the status quo.
- Felix didn’t write a comment but favors “C unwind”
- Forwards compatible to go forward
- Adam Folzer prefers extern “C”
- Niko’s comment in favor of “C unwind”
- Scope of RFC
- Potentially exclude the behavior of foreign exceptions — they can remain UB
- or we can try to come up with an answer
- Potentially exclude the behavior of foreign exceptions — they can remain UB
- Pending nominated PR #70212
- if
catch_unwind
catches a foreign exception, it returns aBox<ForeignException>
- actual return value:
Box<dyn Any>
?
- actual return value:
- when you try to rethrow that box, it gets rethrown as a Rust panic
- because we can’t capture all the details of a C++ exception without adding a dependency on the C++ runtime
- potential corner cases:
- cross-DLL exceptions on Windows can behave strangely if you wind up depending on two copies of libunwind (you would need to depend on a shared instance of libgcc)
- whatever happens, catch_unwind must have one of these behaviors to make rayon/take_mut/etc sound:
- exception is caught
- program aborts
- or it is UB somehow
- note that PR doesn’t update any documentation
- we should make a point to explicitly state that the behavior is unstable and to cite the ffi-unwind project group
- existing docs are pretty vague in any case
- if
- Niko notes that, if we opted not to try to support foreign exceptions propagating across Rust code, that might effect his opinion about extern “C unwind”
- 2020-04-02: Working towards RFC
- 2020-04-09: BatmanAod opened a PR with draft of RFC
"dyn Trait" stuff (nikomatsakis)
-
No progress
-
Relevant issue: rust-lang/rust#57893
-
Relevant PR: rust-lang/rust#66037
-
What the PR implemented:
- Making
dyn Trait
notdyn safe
if:- there is a dyn overlapping impl and
- the trait has associated non-functions
- that do not have where
Self: Sized
(not implemented)
- that do not have where
- Making
-
Crater impact virtually negligible, but the 1 item we did identify is interesting
- has to do with the
[TryStream](https://docs.rs/futures/0.3.1/futures/stream/trait.TryStream.html)
trait, which is used roughly like this: trait StreamX { type Item;
}
trait TryStreamX: StreamX { type Ok; type Error; }
impl<S, T, E> TryStreamX for S where S: ?Sized + StreamX<Item = Result<T, E>> { type Ok = T; type Error = E; }
- has to do with the
-
the crate in question has a
dyn TryStream
which is an error now- Why? The concern is that
S
in the above impl might (in the future) becomedyn TryStreamX<Ok = A, Error = B> + StreamX<Item = Result<C, D>>
- in which case
type Ok
would beA
from the default impl butC
from the impl above
- Why? The concern is that
-
I’m not sure if there is some path forward apart from breaking
dyn TryStream
, which is a bit of a shame- note that a trait alias is really what we want here
-
other alternative that I haven’t tried to implement yet, but which I discussed before
- in a dyn-overlapping impl, all associated items must be
default
- and compiler (for backwards compatibility) will add the
default
implicitly- (but user would not be permitted to specialize with their own impls, as boats noted)
- this is to reflect that the compiler introduces its own impl
- and compiler (for backwards compatibility) will add the
- but impact on
TryStream
would be pretty severe here, I think- you wouldn’t be able to take
T: Stream<Item = Result<...>>
- you would not be able to do
T::Ok
- you wouldn’t be able to take
- in a dyn-overlapping impl, all associated items must be
-
impact of existing PR
- you cannot use
dyn TryStream
but you can dofn foo<T: TryStream<..>>()>
- you could write
dyn Stream<Item = ..>
- you cannot use
-
really this code wants to be a trait alias
- This would require trait aliases to support associated types, but that seems feasible
- Trait alias semantics: “A Stream of Result<T, E> can be called a TryStream, where the associated types Ok and Error refer to T and E respectively”
-
next step:
- revisit the soundness hole and see if we can “weaponize” the
TryStream
example in a similar way - revisit the write-up covering the various options before us:
- i.e., this change is modifying what dyn safety means, has very slight impact
- concerns about the fact that “whether trait X is dyn safe depends on its impls”
- other options might be introducing
default
, but this has potentially broader impact
- i.e., this change is modifying what dyn safety means, has very slight impact
- revisit the soundness hole and see if we can “weaponize” the
grammar (qmx)
- Centril + petrochenkov have been working on parser architecture
- simplified and unified item grammar for example in different contexts
- Outline module loading will soon be driven by expansion, allowing:
#[cfg(FALSE)]
mod foo {
mod bar; //
foo/bar.rs
doesn't exist, but no error regardless. }
- maybe stalled out?
- can we maybe write up a description of how far we got, what the problems were
- 2020-04-02: Some discussion, some work started up again
- Updating grammar definition to reflect the actual grammar that’s implemented in rustc
never_type **(**
!`) stabilization (nikomatsakis)
- PR #68350 remains open but we are losing faith in the approach that was initially suggested
- Problem is that a function like
fn make_foo<T>() → Result<(), T> { Ok(()) }
is fundamentally fine- but if the
T
happened to “fall back” to!
, we would issue a warning here
- Aaron1011 proposed a more aggressive lint that works across functions
- Niko has stated he’d prefer a more modular (intraprocedural) analysis
- 2020-03-31: Niko left detailed comment with an alternative proposal
**#[instruction_set]**
attribute for per-function instruction set changes
- pnkfelix to act as liaison and explore
- current status: investigation of some of the questions we raised below
None this week
Compile regression "cannot infer an appropriate lifetime for lifetime parameter" #70917
-
Centril left a comment, removed T-Lang label.
-
We/Niko thinks this is a bug
-
assess impact with crater
-
broke proptest (can issue point release)
-
broke structopt
-
Can special case
- We can do warning period or permantently if we want to (region inference; WF).
-
Niko thinks not unsound
- From RFC 1214, if you have a type
Foo<X>:
'``y
, thenX:
'``y
for all componentsX
impl<``'``a> SomeTrait for Foo<``'``a> { type Bar =
'``a }
impl<``'``a> SomeTrait for typeof(capture_lifetime<``'``a>)
- From RFC 1214, if you have a type
-
the code in question is here
-
in type checker? // We always require that the type provided as the value for // a type parameter outlives the moment of instantiation. let substs = self.tables.borrow().node_substs(expr.hir_id); self.add_wf_bounds(substs, expr);
fn assert_static<T: 'static>(_: T) {}
fn capture_type() {} fn capture_lifetime<'a: 'a>() {}
// Errors on stable & nightly. fn test_type<'a>() { assert_static(capture_type::<&'a ()>); }
// Errors only on nightly. fn test_lifetime<'a>() { assert_static(capture_lifetime::<'a>); }
@nikomatsakis Are we supposed to ignore only lifetime parameters in
ty::FnDef
s? If the reasoning is that the only thing you can do with aty::FnDef
is call it, why aren't all generics ignored?
- no major updates, see [internals thread](https://internals.rust-lang.org/t/the-pin-unsoundness-and-coerceunsized/11593)
[**Lifetime bounds in auto trait impls prevent trait from being implemented on generators #64552**](https://github.com/rust-lang/rust/issues/64552)
- P-high but not a soundness problem, *mostly* an impl issue, though it is somewhat blocked on having a nice way to describe region solving
- Maybe Niko should prep a writeup or something
struct Foo<'a, 'b: 'a> { }
- Skipped, no writeup
[~~**Coherence can be bypassed by an indirect impl for a trait object**~~](https://github.com/rust-lang/rust/issues/57893) **#57893**
- (see above)
## [Nominated PRs](https://github.com/rust-lang/rust/pulls?q=is%3Aopen+is%3Apr+label%3AI-nominated+label%3AT-lang)
[~~**Move `str` to libcore.**~~](https://github.com/rust-lang/rust/pull/70911) ~~**#70911**~~
| I was reminded we tried to do this before and didn't go through with it for some reason, after seeing [rust-lang/unsafe-code-guidelines#78](https://github.com/rust-lang/unsafe-code-guidelines/issues/78) (the impact on this PR on that question isn't significant, FWIW).<br>One thing I didn't do is change how `str` is resolved: it's still a builtin type for `rustc_resolve`, which *only after* name resolution is turned into the right type, using the `"str"` lang item.<br>(Presumably if `core::str` had `crate mod sealed { pub struct Str([u8]); }` then `core::prelude` could do `pub use crate::str::sealed::Str as str;`, but I haven't tried it - IMO a requirement is that users can't observe `core::str::str` or `core::str::Str`. cc [@petrochenkov](https://github.com/petrochenkov))<br>While this does seem to work with enough tweaks, I don't have the bandwidth to push this through.<br>So I suppose this could be considered insta-abandonware ♻️. |
- Are there user-visible changes?
- eddyb: if the interfaces are all the same, should be fine
- Niko: what’s the motivation?
- Removing special cases, but we still require special cases for name resolution
- Some diagnostics are somewhat better, some worse (maybe can be fixed)
- But at almost every other place that referenced `str` before, some kind of `if` is currently required in the compiler, at least in the first implementation
- centril: not obvious that it’s an improvement
- but as long as we’re not “locked in” one way or the other, seems fine
- eddyb: petrochenkov mentioned that there was an attempt and they’d like to see it done
[~~**Update**~~](https://github.com/rust-lang/rust/pull/70705) `[~~**mem::Discriminant**~~](https://github.com/rust-lang/rust/pull/70705)` ~~**#70705**~~
- Redefine `mem::Discriminant` to not wrap a `u64` but wrap a “type-dependent value”:
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
- This means that 128-bit discriminants work
- User-visible through size-of, align-of, and hashing, but not other ways as far as we know
- Conclusion: “seems ok”
[~~**Use explicit promotion for constants in repeat expressions**~~](https://github.com/rust-lang/rust/pull/70042) ~~**#70042**~~
- Should we go with the plan as proposed ----v ?
- Do we need FCP?
- Just experiment on nightly?
- Do we need FCP?
Oliver says: rust-lang/rust#70042 (comment):
> This PR changes our behaviour in repeat expressions, turning the repeat element into a full (anonymous) constant if the type is `!Copy` and the repeat count is larger than 1. This means that you can write things like `[Vec::new(); 42]` and don't have to create an intermediate constant yourself. Before this PR you had to write
const FOO: Vec<i32> = Vec::new();
[FOO; 42]
> because the repeat element was using the rules for promoteds instead of those for constants.
> @scottmcm worries that
> It seems like it would be bad if adding `Copy` to the type returned from `foo` could change what happens in things like `[foo(); 4]`.
> source: [#49147 (comment)](https://github.com/rust-lang/rust/issues/49147#issuecomment-551244843)
> Additionally on the tracking issue @RalfJung worried ([#49147 (comment)](https://github.com/rust-lang/rust/issues/49147#issuecomment-521640072)) that it may be suprising to users as to what code is accepted and what isn't, since the `Copy` or `const` rule is a first in Rust afaik
> This change is forward compatible with [#49147 (comment)](https://github.com/rust-lang/rust/issues/49147#issuecomment-392256983) which suggests to permit `[Ok::<i32, String>(x); N]`, even though the expression is neither `Copy` nor const evaluable, but it's basically a value constructor taking only `Copy` values.
- Niko:
- what about starting with explicit const promotion, like
[const { Vec::new()
}``; 22]
, as we’ve talked about?- I’m obviously 👍; see some previous conversation in https://internals.rust-lang.org/t/quick-thought-const-blocks/7803?u=scottmcm
- then the above — if we still want it — becomes a kind of “sugar” that we can add later to simplify common cases?
- (Syntactic note, I’d prefer
[const Vec::new(); 22]
with same extent as||
— Niko)- This is the same kind of effect as
unsafe
— it’s a scoped one that’s not dischargable later — so it’s not obvious that we should have a different syntax for it.
- This is the same kind of effect as
- I’m nervous about expanding promotion further, even for cases we’re pretty sure about.
- Add a checkbox to rust-lang/rust#49147 to see if too much pain with compromise
- Niko will leave comment about ^---
- Centril did
- Procedural steps:
- We can introduce this experimentally but we should have a tracking issue, would want to have an RFC before we finalize
- what about starting with explicit const promotion, like
Limit maximum alignment in #[repr(align)] to 4K #70193
-
Discuss new input given in today’s meeting.
-
Context: lots of O/S, toolchains, etc, don’t really support global variables with large alignments
-
On linux at least, the limit is
PAGE``_``SIZE
, Windows seems to impose 8K if you use the right options, or 4K given the options you use -
Is this target dependent? (Should we make the rules target dependent?)
- It is certainly a function of linker + target
-
Embedded architectures maybe have more esoteric limits?
-
Definitely unsound to promise a higher alignment than we can deliver
-
Any use cases for large alignments?
- Amanieu: Not really but this is why we’re doing the crater run
-
PR gives an immediate error if the alignment is too large
-
Options:
- if you try to give an alignment greater than some target dependent value, give an error
-
Other option:
- allow large alignments, but not for statics, but this is more complex
- niko: seems not worth it
-
scott: Right now we don’t limit size of arrays but rather total size of type, this feels similar. Not a “virtual machine error” to request a type that large, but your platform doesn’t support it. Not sure if this is meaningful but…
- centril: that’s how I think of it as well
-
scott: At some point we might have const generics setting alignment, and would we know enough to set a bound in that case?
- centril: we can always remove the restriction, so we’re not losing options
- e.g., would this be monomorphizaton time error if alignment can reference generics
-
Amanieu: found a case where somebody wanted an alignment of 32K for some ARM-embedded thing: #42960
the only cases I know of required natural alignment for large arrays are for embedded devices, which don't have that much memory anyway -- while 2^15 is 32kB which stays under the “existing” limit rust-lang/rust#42960 (comment)
-
2020-04-02: Update that crater results are in with 7 total regressions and 3 root regressions
- “In light of these results, maybe we should go with plan B: only disallow statics with an alignment over the page size. We would also need to disable constant promotion in the compiler if the type of the value being promoted exceeds the target's maximum alignment.”
-
Josh: Would prefer not to limit beyond the limits of the target, but we should flag alignments that exceed the limits of the target.
-
Amanieu: If we want to allow types that have alignments over 4K, but we wish to prevent creating global variables of those types, that will require a “post-monomorphization” check because of promoted constants (which are effectively global variables).
- Niko: promoted constants is a bit unfortunate, since the compiler is the one that opted to make the static in the first place
- Amanieu: yes, but required since promoted constants can have static lifetime
- Niko: promoted constants is a bit unfortunate, since the compiler is the one that opted to make the static in the first place
-
Options:
- Disallow alignment on the types themselves (triggers regressions)
- Allow them on types but disallow in static constants
- local variables can also cause problems, but that’s an LLVM bug
-
centril: the limit would actually be per-target, right?
-
centril: 3 crates doesn’t seem that significant compared to a post-monomorphization bug
-
Josh: alignment is rare, large alignment rarer still. Leaving aside that I would expect embedded projects to be under-represented in crater, I would also say that this is a case where “what fraction of the people using the feature just got broken” — potentially significant. I would say this is a warning sign we should pay attention to
-
Niko: the use cases seem fairly valid? I’d like to have another way to address them
- Amanieu: Since the global allocation API is stable, there is now another option. A lot of this code was written before that.
-
Centril: For the embedded targets, is there something specific about statics..
- Amanieu: Embedded targets don’t have a problem because they’re using static linking and not dynamic linking.
- Centril: So they could raise the alignment as high as they want on those targets.
- Amanieu: Right.
- Amanieu: Embedded targets don’t have a problem because they’re using static linking and not dynamic linking.
-
Amanieu: The problem is PIC and operating system loaders that don’t respect alignment constraints
- Centril: so there doesn’t seem to be a problem with the embedded use cases
-
Niko: middle ground might be a warning period and encouraging folks to migrate to newer APIs?
- Amanieu: the crates are fairly recent and were last updated “months ago”
-
Amanieu: there might be a 3rd option:
- Allow you to specify alignment on the types, but don’t allow you to create instances of these types — ah, but that is still “post monomorphization”.
-
Niko: It seems to me that this is analogous to “type too large”
- Centril: but that never happens in practice
-
Mark: I do feel that this is the “sort of thing” that might make sense post monomorphization. e.g. you could imagine linkers failing because they can’t satisfy the requirements (instead of just ignoring them).
- Most people that specify this sort of type would probably be “ok” with it claiming to work in cargo check on other platforms.
-
Options:
- Disallow alignment on the types themselves (triggers regressions)
- Pro: simpler overall
- Con: triggers known regressions in existing code
- absolute number of regressions is small
- but as a fraction of users, maybe significant
- Centril doesn’t agree it is significant as a fraction of users.
- in embedded cases, however, the limit for platforms would likely be high, so they’d not be impacted
- Allow them on types but disallow in static constants
- Pro: as narrowly tailored as possible to the existing problem
- Con: triggers post monormorphization errors
- Disallow alignment on the types themselves (triggers regressions)
-
What does it take to fix?
- greenthread-future: use global-alloc API
- other crates: remove or cfg-gate the structs with higher alignment, hopefully unused by their clients
-
Action items:
post summary of this discussion and considerationsping embedded working group and crate authors to get their input
-
Update: crate author wrote comment regarding maligned
- role of the crate is to
- helping to manage DSP with a camera
- allow structs to be generic over their alignment
- role of the crate is to
-
Is this a hint?
- Feeling is “no”, you’re doing this because unsafe code needs it for some reason
- If we can’t enforce it, we should say so
-
On the other hand, what is the recourse if someone can enforce it on their platform?
- Alignment is per-target, so it could be raised for platforms, or folks can tweak their targets
-
Where is it easier to do?
- Definitely easier to do on the type level — we’d just be checking when you define the alignment
-
Can we put this in the place where we check for size overflows?
- Wouldn’t that be the worst of both worlds? You’re enforcing across all types but also late, not early.
- eddyb: I rationalize the size overflow check that it’s almost like “running out of memory at runtime”, that doesn’t fit with alignment
-
Niko: We can probably go ahead and enforce at the type level but I’d prefer we do it at start of the cycle to give people time to adapt.
- I’d be in favor of a warning cycle with instructions for how folks should adapt their code.
-
Josh: One interesting question is that the limits do depend on whether you’re doing static or dynamic linking, should that be taken into account?
- Does the limit need to be the larger of whatever is static vs dynamic? (That’s the most permissive, but not sound)
- But the more conservative of the two rules prevents folks from doing things they could’ve done.
- But then you’re not fixing the bug
- And the assumption is that folks who do want this behavior
- can either use an extended malloc for heap cases
- or on some platform where it doesn’t matter
- maybe something something linker script, custom target?
-
Potential consensus:
- Warning period and enforcing at the type level
- Warning text should point to an issue where we want to collect feedback.
- Write-up that says “here are the known use cases and what to do instead”
- we can review this to make sure we’re satisfied
- Warning period and enforcing at the type level
-
but Josh is concerned if we don’t have a reasonable way to achieve all the use cases people need (esp. embedded platforms or unusual linking scenarios)
Perform WF-check on type
s with no type parameters#69741
-
Original set of PRs by eddyb, https://github.com/rust-lang/rust/pulls?q=is%3Aclosed+is%3Apr+author%3Aeddyb+is%3Aunmerged+type+alias+
struct TypeThatRequiresOrd<K: Ord> { }
type Foo = TypeThatRequiresOrd // no error // where TypeThatRequiresOrd: ; // <-- This type is WF.
// you need a bound if you want to write the
I::Item
shortcircuit type Foo<I: Iterator> = Foo<I::Item>; type Foo = Foo<::Item>;type Foo<K> = TypeThatRequiresOrd<K>
— no error, historicaltype Foo = TypeThatRequiresOrd<f32>
— error?- crater run in progress; more data next week.
- Data is in: rust-lang/rust#69741 (comment)
- 📊 41 regressed and 1 fixed (95178 total)
[INFO] [stderr] error[E0038]: the trait
order::BitOrder
cannot be made into an object - ^-- not a problem when we change
WF(dyn Trait)
object_safe_for_dispatch
- 📊 41 regressed and 1 fixed (95178 total)
[INFO] [stderr] error[E0038]: the trait
- Data is in: rust-lang/rust#69741 (comment)
- not entirely clear what end-goal we want, some prior discussion in a github issue Niko couldn’t find 🙂
- things that are weird:
- we do not check at the point of definition, somewhat analogous with e.g. struct definitions, but could be rationalized by implied bounds to avoid breaking changes
- we do not enforce the bounds that were put there
- fixing this would be a break, but it’s unclear (to me) what impact that would have
- would be a bit harder to do with current compiler architecture, but maybe we had a way to do it, I can’t remember —niko
- action items:
- design meeting scheduled April 27
proc_macro: Stabilize Span::resolved_at
and Span::located_at
#69041
- fcp merge comment — check your boxes
Tracking issue for RFC 2091: Implicit caller location #47809
- There’s a stabilization report.
- Should we ship?
- When should we ship?
- Remaining issues?
"-Funused" is overwritten by later "-Aunused" #70819
- We did not get to this — but we also don’t need to.
Interestingly, doing the same via flags in the source code also does not work as expected -- the
allow
overwrites theforbid
!
#![forbid(unused)]
#![allow(unused)]
fn square(num: i32) -> i32 { num * num }
This is also a regression, but not a recent one: with Rust 1.20, the code gets rejected as expected; with Rust 1.21 and later it gets accepted. It is also in direct contradiction with the documentation which says
Resolving Ok
-wrapping for try
blocks #70941
- Everyone in favor of
Ok
wrapping fortry { … }
blocks? If so, please check your box.
Implement conversion traits for usize/isize together with a portability lint #70460 Resurrect old PR Implement conversion traits for usize/isize together with a portability lint #37423
- We don’t currently include conversions like “u32 to usize” because of possibility of 16-bit platforms, but this is pretty rare and arguably a corner case that we might want to permit by default (unless you opt in)
- This is exactly what the portability lint RFC proposes: warning lints about portability to 16-bit platforms are allow-by-default.
Should enum discriminants have generics in scope? #70453
*(NB: before a PR like* [*#70825*](https://github.com/rust-lang/rust/pull/70825) *lands, any example in here should be tested with* `*#![feature(const_generics)]*`*, which enables the pre-lazy-normalization “fix” for* [*#43408*](https://github.com/rust-lang/rust/issues/43408)*)*
The current situation is that generic parameters are supported by name resolution, letting you write `enum`s like this (which should error one way or another, but currently ICEs due to inconsistent assumptions in compiler, but that’s not as relevant):
#[repr(usize)]
enum Foo<T> {
Zero = 0,
SizeOf = std::mem::size_of::<T>(),
}
Our options going forward are:
1. we teach name resolution to hide `enum` generic parameters from the discriminant expression
- this effectively enshrines that we don't want the parameterization to happen
- I'm not sure this can be backwards-compatible with 2.
2. we keep the current name resolution support but error if we can't evaluate to concrete values
- the concrete values are necessary to check, at the definition site, that discriminants don't overlap
- there are special-cases (only the first variant having an explicit discriminant, while the rest keep counting up) where we could check w/o knowing the values
- long-term we could let more examples compile via explicit `!=` bounds
- note that expressions that use generics [can still evaluate to concrete values](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=ba0ae8e0eb712b342a61a776ac52c62f)
- PR [#70825](https://github.com/rust-lang/rust/pull/70825) was opened for this alternative
If we choose 2, this `enum` would compile (and `arbitrary_enum_discriminant` may be stabilized soon, so it could end up stable quickly):
#![feature(arbitrary_enum_discriminant)]
#[repr(usize)]
enum MyWeirdOption<T> {
None = 0,
Some(T) = std::mem::size_of::<*mut T>(),
}
- Let’s do FCP.
- Proposed by Centril
[**Arc::drop has a (potentially) dangling shared ref #55005**](https://github.com/rust-lang/rust/issues/55005)
- had a [design meeting](https://github.com/rust-lang/lang-team/blob/master/design-meeting-minutes/2020-02-10-References-and-dereferenceable.md) but didn’t reach a firm conclusion
- **next step:** somebody needs to write up the implications of that meeting for this issue in a clear way
- a possible next step: adding support for `*const self` methods so that we can have a `fetch_sub` on `AtomicUsize` that takes `*const self`
- would have to deal with conflicts of inherent methods
- could either deprecate existing `fetch_sub` or *try* to modify them in place
- or we could make free-functions instead of methods
- raw pointer variants would have to be unsafe, which is also unpleasant
- what we really want is something that is valid on entry but not on exit
- which we don’t have, unless we modify the guarantees of `&`
- might be possible to have a wrapper type that’s a pointer internally but safe to construct from a reference — which we could also have methods on, to avoid the raw pointer method conversation
- maybe a different (but perhaps more meaningful) related issue: https://github.com/rust-lang/rust/issues/60639
- certainly more practically useful than the *const self in Atomics
[**floating point to integer cast can cause undefined behaviour #10184**](https://github.com/rust-lang/rust/issues/10184)
- [last time we talked](https://github.com/rust-lang/rust/issues/10184#issuecomment-559538629), we concluded that it made sense to
- adopt saturated semantics as the default
- maybe offer a `-Z` flag to opt out for a time
- there has been plenty of discussion in the meantime
- how do we go forward here?
- a summary might be an amazing contribution --niko
- Centril will leave comment (see action items)
- waiting on libs team to stabilize [the unsafe methods](https://github.com/rust-lang/rust/issues/67058) that allow you to do the casts (making it UB if they are wrong)
- PR open for stabilization: https://github.com/rust-lang/rust/pull/70487
## [Nominated RFCs](https://github.com/rust-lang/rfcs/pulls?q=is%3Aopen+is%3Apr+label%3AI-nominated+label%3AT-lang)
- [~~RFC: Add a new `#[instruction_set(...)]` attribute for supporting per-function instruction set changes~~](https://github.com/rust-lang/rfcs/pull/2867) ~~#2867~~
- some questions about “what kinds of guarantees”
- if this is very narrowly targeted, is that a problem? I feel ok about that. —Niko
- feels like it could be a “implementation defined” sort of feature that rustc supports
- would it be a kind of hint? can a compiler ignore it if it’s a pain to support?
- motivation from RFC seems to be about code-size and optimization
- might be a pain for a cranelift backend, even if it’s easy for LLVM
- pnkfelix: might have ABI implications
- Niko: I’d be ok with “cranelift backend doesn’t support this, you get an error” if it can’t be a hint
- centril: me not so much
- pnkfelix might take a look and act as a liaison
- RFC for unsafe blocks in unsafe fn [#2585](https://github.com/rust-lang/rfcs/pull/2585)
- lints being discussed are allow by default
- RFC should be needed for changing people’s expected code patterns
- consensus:
- suggest changing the RFC to change lint defaults at the edition boundary to encourage this
- this permits `#[allow]` in narrow places to overcome ergonomic hit
- we can consider moving to hard error in next edition if we care
- not block or consider changes to keywords at this time
- not obvious that `trusted` is the right new keyword to add anyway
- you might want it for today’s `unsafe fn foo() { /* body permits unsafe code */ }` for example
- some changes arose about how precisely to configure the lints
- we don’t want folks to have to disable checking for “all unused unsafe blocks”
- one option:
- we can convert `unused_unsafe` into a lint group
- one lint covers the other stuff
- one lint covers “unsafe blocks in unsafe functions that enclose unsafe operations”
- basically, let’s defer these details to implementor etc, but the goal is what we said before
- some interesting questions are whether we want to change before of code that contains `#![warn(unused_unsafe)]` already etc
- Mark will elaborate on the RFC, etc.
- Seems like we should:
- cancel the existing FCP and close the PR, since it doesn’t do what we want to do, and the thread is complex
- encourage a new PR that takes the approach of
- allow-by-default lint
- separate out the swap defaults for a future RFC
- Niko has reservations but was convinced it’ll be easier to make the case if we have experience with the lint and a precise thing to judge
## [rfcbot pending list](https://rfcbot.rs/)
- items to discuss this meeting:
- RFC Elide Array Size stalled since [Dec 2018](https://github.com/rust-lang/rfcs/pull/2545#issuecomment-449133335)
- various pending concerns:
- general-value-inference ([#2545 (comment)](https://github.com/rust-lang/rfcs/pull/2545#issuecomment-449146388)) — centril
- rfc-is-vague-or-maybe-niko-is-just-lazy ([#2545 (comment)](https://github.com/rust-lang/rfcs/pull/2545#issuecomment-449134514)) — niko
- state-contextual-constraints-up-front ([#2545 (comment)](https://github.com/rust-lang/rfcs/pull/2545#issuecomment-477941629)) — felix
- move to postpone?
- goal:
- want to write something like this
- `static X: [u32; _] = [1, 2, 3, 4, 5];`
- would be a change in precedent against “global type inference”
- already have made step in this direction with `impl Trait`
- one possibility:
- say that we will permit `_` in “some places in the types of statics/constants”
- we can say e.g. any value position, to limit interaction with `i32` and `!` fallback
- but we do require that there is a DAG so that the type of each static/constant can be fully inferred before those who reference it are type-checked
- this would permit future expansion in theory to permit `_` in other places if we wanted it
- Niko’s thought:
- we should close as postponed and state that we might prefer a proposal like that :)
- The `_` is in its own infcx so it would need some work to get `_ == 2`
let x: [u8; _] = [0, 1];
- Calling methods on generic parameters of const fns #2632 ([fcp comment](https://github.com/rust-lang/rfcs/pull/2632#issuecomment-481395097))
- As far as I know we are permitting experimentation and implementation to go through here
- Can we merge the RFC in an experimental state? How can we best reflect this status?
- merge: [**Introduce the ASM project group (rust-lang/rfcs#2836)**](https://github.com/rust-lang/rfcs/issues/2836#issuecomment-565269781)
- [Centril](https://rfcbot.rs/fcp/Centril)