Skip to content
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

Swap the 2 variants of Option<T> #49499

Closed
wants to merge 1 commit into from
Closed

Conversation

nox
Copy link
Contributor

@nox nox commented Mar 30, 2018

That allows us to have a better path from Result<T, E> to Option<T> in the general case, without niche-filling optimisations.

@rust-lang/wg-codegen

It should be noted that if you also have #49479 and #49420 (not sure this one matters but it was in my branch so full disclosure I guess), the methods for Result<T, UnitStuff> and Option<T> end up being shared for T values that don't trigger the niche-filling optimisation.

#![crate_type = "lib"]
#![feature(try_trait)]

pub fn foo(x: Option<i32>) -> Result<i32, std::option::NoneError> {
    match x {
        Some(v) => Ok(v),
        None => Err(std::option::NoneError),
    }
}

pub fn bar(x: Option<i32>) -> Option<i32> {
    match foo(x) {
        Ok(v) => Some(v),
        Err(_) => None,
    }
}
; ModuleID = 'foo0-8787f43e282added376259c1adb08b80.rs'
source_filename = "foo0-8787f43e282added376259c1adb08b80.rs"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin"

; foo::bar
; Function Attrs: norecurse nounwind readnone uwtable
define { i32, i32 } @_ZN3foo3bar17h61d61d9e41681936E(i32 %x.0, i32 %x.1) unnamed_addr #0 {
start:
  %switch.i = icmp ne i32 %x.0, 0
  %. = zext i1 %switch.i to i32
  %0 = insertvalue { i32, i32 } undef, i32 %., 0
  %1 = insertvalue { i32, i32 } %0, i32 %x.1, 1
  ret { i32, i32 } %1
}

; foo::foo
; Function Attrs: norecurse nounwind readnone uwtable
define { i32, i32 } @_ZN3foo3foo17h9a3b40b224e16c75E(i32, i32) unnamed_addr #0 {
; call foo::bar
  %3 = tail call { i32, i32 } @_ZN3foo3bar17h61d61d9e41681936E(i32 %0, i32 %1) #0
  ret { i32, i32 } %3
}

attributes #0 = { norecurse nounwind readnone uwtable "no-frame-pointer-elim"="true" "probe-stack"="__rust_probestack" }

@eddyb
Copy link
Member

eddyb commented Mar 30, 2018

cc @alexcrichton Can we do this without anyone observing it?

@@ -981,6 +981,102 @@ impl<T> From<T> for Option<T> {
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Copy link
Contributor

Choose a reason for hiding this comment

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

All methods below essentially have the same code, maybe dedup them with a macro?

/// Some value `T`
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
/// No value
Copy link
Contributor

Choose a reason for hiding this comment

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

Document (in a comment) the reason for this order and the manual impls below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should it a doc comment, or just a comment in the source?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added some comments and made them reference each other.

@Manishearth Manishearth added A-codegen Area: Code generation WG-llvm Working group: LLVM backend code generation labels Mar 30, 2018

// Note that this is not a lang item per se, but it has a hidden dependency on
// `Iterator`, which is one. The compiler assumes that the `next` method of
// `Iterator` is an enumeration with one type parameter and two variants,
// which basically means it must be `Option`.

/// The `Option` type. See [the module level documentation](index.html) for more.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
Copy link
Member

Choose a reason for hiding this comment

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

Hash might still observe the order?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hash offers no stability guarantees.

@petrochenkov
Copy link
Contributor

Is None::<&u8> still a null pointer on the other side of FFI after this change?

@nox
Copy link
Contributor Author

nox commented Mar 30, 2018

@petrochenkov Option<&'a u8> triggers the niche-filling optimisations and doesn't store any discriminant in memory explicitly.

@TimNN
Copy link
Contributor

TimNN commented Mar 30, 2018

Your PR failed on Travis. Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
Resolving deltas: 100% (613110/613110), completed with 4855 local objects.
---
[00:01:20] configure: rust.quiet-tests     := True
---
[00:41:51] .........................................................................i..........................
[00:41:57] ................i...................................................................................
---
[00:42:33] ............................................................................................i.......
[00:42:39] ................................................................i...................................
---
[00:43:36] .............................................i......................................................
---
[00:47:34] .............................i......................................................................
[00:47:48] ..............................................................i.....................................
[00:48:04] ...............................................i....................................................
[00:48:24] ....................................................................................................
[00:48:47] ....................................................................................................
[00:49:09] ....................................................................................................
[00:49:34] .i................................................................................................i.
[00:50:01] ...............................................................................test [run-pass] run-pass/mir_heavy_promoted.rs has been running for over 60 seconds
[00:50:11] .....................
[00:50:42] ....................................................................................................
[00:51:20] ...............................................................ii...................................
[00:52:04] ..........................i....................................................i.ii.test [run-pass] run-pass/saturating-float-casts.rs has been running for over 60 seconds
[00:52:10] ................
[00:52:51] .......................................................................................iiiiiii......
---
[00:54:51] ....................................i...............................................................
[00:54:59] ....................................................................................................
[00:55:06] ..................i............................................................ii.iii...............
[00:55:14] ....................................................................................................
[00:55:22] ........i..............................i............................................................
[00:55:29] ....................................................................................................
[00:55:36] .....................i..............................................................................
[00:55:45] .............................F......................................................................
[00:55:55] ....................................................................................................
[00:56:05] ....................................................................................................
[00:56:16] ....................................................................................................
[00:56:30] ....................................................................................................
[00:56:40] ..............i.....................................................................................
[00:56:49] .................i..ii..............................................................................
[00:56:59] ....................................................................................................
[00:57:10] ....................................................................................................
[00:57:19] ....................................................................................i...............
[00:57:30] ..............................i.....................................................................
---
[00:58:06] error: /checkout/src/test/compile-fail/issue-2111.rs:12: unexpected error: '12:9: 12:14: non-exhaustive patterns: `(Some(_), Some(_))` not covered [E0004]'
[00:58:06]
[00:58:06] error: /checkout/src/test/compile-fail/issue-2111.rs:12: expected error not found: non-exhaustive patterns: `(None, None)` not covered
[00:58:06]
[00:58:06] error: 1 unexpected errors found, 1 expected errors not found
[00:58:06] status: exit code: 101
[00:58:06] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/issue-2111.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/issue-2111.stage2-x86_64-unknown-linux-gnu" "-Crpath" "-O" "-Zmiri" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/issue-2111.stage2-x86_64-unknown-linux-gnu.aux" "-A" "unused"
[00:58:06] unexpected errors (from JSON output): [
[00:58:06]     Error {
[00:58:06]         line_num: 12,
[00:58:06]         kind: Some(
[00:58:06]             Error
[00:58:06]         ),
[00:58:06]         msg: "12:9: 12:14: non-exhaustive patterns: `(Some(_), Some(_))` not covered [E0004]"
---
[00:58:06]         msg: "non-exhaustive patterns: `(None, None)` not covered"
[00:58:06]     }
[00:58:06] ]
[00:58:06]
[00:58:06] thread '[compile-fail] compile-fail/issue-2111.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1253:13
---
[00:58:06] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/compile-fail" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "compile-fail" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zmiri -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zmiri -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:58:06] expected success, got: exit code: 101
[00:58:06]
[00:58:06]
[00:58:06] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:58:06] Build completed unsuccessfully in 0:17:08
[00:58:06] make: *** [check] Error 1
[00:58:06] Makefile:58: recipe for target 'check' failed
---
$ cat obj/tmp/sccache.log
---
$ ls -lat $HOME/Library/Logs/DiagnosticReports/
ls: cannot access /home/travis/Library/Logs/DiagnosticReports/: No such file or directory
travis_time:end:059dcc36:start=1522406761749283942,finish=1522406761757544277,duration=8260335
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:2a43187a
$ find $HOME/Library/Logs/DiagnosticReports -type f -name '*.crash' -not -name '*.stage2-*.crash' -not -name 'com.apple.CoreSimulator.CoreSimulatorService-*.crash' -exec printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" {} \; -exec head -750 {} \; -exec echo travis_fold":"end:crashlog \; || true
find: `/home/travis/Library/Logs/DiagnosticReports': No such file or directory
travis_time:end:2a43187a:start=1522406761765322842,finish=1522406761773339232,duration=8016390
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:307069a2
$ dmesg | grep -i kill
[   10.523156] init: failsafe main process (1096) killed by TERM signal

If this was not helpful or you have suggestes for improvements, please ping or otherwise contact @TimNN.

@nox
Copy link
Contributor Author

nox commented Mar 30, 2018

The failing test on Travis was due to rustc finding a different witness about the non-exhaustiveness, because both (None, None) and (Some(_), Some(_)) are not covered by the match expression.

@nox
Copy link
Contributor Author

nox commented Mar 30, 2018

One question is, should we swap this one or Result<T, E>?

@TimNN
Copy link
Contributor

TimNN commented Mar 30, 2018

Your PR failed on Travis. Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
Resolving deltas: 100% (613114/613114), completed with 4853 local objects.
---
[00:00:52] configure: rust.quiet-tests     := True
---
[00:43:39] .........................................................................i..........................
[00:43:45] ................i...................................................................................
---
[00:44:22] ............................................................................................i.......
[00:44:29] ................................................................i...................................
---
[00:45:26] .............................................i......................................................
---
[00:49:27] .............................i......................................................................
[00:49:42] ..............................................................i.....................................
[00:49:58] ...............................................i....................................................
[00:50:18] ....................................................................................................
[00:50:41] ....................................................................................................
[00:51:02] ....................................................................................................
[00:51:28] .i................................................................................................i.
[00:51:54] ............................................................................test [run-pass] run-pass/mir_heavy_promoted.rs has been running for over 60 seconds
[00:52:06] ........................
[00:52:38] ....................................................................................................
[00:53:15] ...............................................................ii...................................
[00:53:59] ..........................i....................................................itest [run-pass] run-pass/saturating-float-casts.rs has been running for over 60 seconds
[00:54:06] .ii.................
[00:54:48] .......................................................................................iiiiiii......
---
[00:56:48] ....................................i...............................................................
[00:56:56] ....................................................................................................
[00:57:04] ..................i............................................................ii.iii...............
[00:57:11] ....................................................................................................
[00:57:19] ........i..............................i............................................................
[00:57:27] ....................................................................................................
[00:57:34] .....................i..............................................................................
[00:57:42] ....................................................................................................
[00:57:53] ....................................................................................................
[00:58:03] ....................................................................................................
[00:58:15] ....................................................................................................
[00:58:28] ....................................................................................................
[00:58:38] ..............i.....................................................................................
[00:58:47] .................i..ii..............................................................................
[00:58:58] ....................................................................................................
[00:59:08] ....................................................................................................
[00:59:18] ....................................................................................i...............
[00:59:29] ..............................i.....................................................................
---
[01:00:07] ...........................i........................................................................
[01:00:08] ....................................................................i...............................
[01:00:09] ................i.......................................................
---
[01:00:25] ...........i........................
---
[01:00:39] ERROR 2018-03-30T12:48:38Z: compiletest::runtest: None
[01:00:52] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:478:22
[01:00:52] ...........................F......................
[01:00:52] failures:
[01:00:52]
[01:00:52] ---- [mir-opt] mir-opt/match_false_edges.rs stdout ----
[01:00:52]  thread '[mir-opt] mir-opt/match_false_edges.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[01:00:52] Current block: None
[01:00:52] Actual Line: "        switchInt(move _6) -> [0isize: bb4, 1isize: bb6, otherwise: bb8];"
[01:00:52] Expected Line: "     switchInt(move _6) -> [0isize: bb6, 1isize: bb4, otherwise: bb8];"
[01:00:52] Expected:
[01:00:52] ... (elided)
[01:00:52]  bb0: {
[01:00:52] ... (elided)
[01:00:52]      _2 = std::option::Option<i32>::Some(const 42i32,);
[01:00:52]      _3 = discriminant(_2);
[01:00:52]      _6 = discriminant(_2);
[01:00:52]      switchInt(move _6) -> [0isize: bb6, 1isize: bb4, otherwise: bb8];
[01:00:52]  }
[01:00:52]  bb1: {
[01:00:52]      resume;
[01:00:52]  }
[01:00:52]  bb2: {  // arm1
[01:00:52]      StorageLive(_8);
[01:00:52]      _8 =2] fn full_tested_match() -> (){
[01:00:52]     let mut _0: ();
[01:00:52]     scope 1 {
[01:00:52]         let _4: i32;
[01:00:52]     }
[01:00:52]     scope 2 {
[01:00:52]         let _5: i32;
[01:00:52]     }
[01:00:52]     let mut _1: (i32, i32);
[01:00:52]     let mut _2: std::option::Option<i32>;
[01:00:52]     let mut _3: isize;
[01:00:52]     let mut _6: isize;
[01:00:52]     let mut _7: bool;
[01:00:52]     let mut _8: i32;
[01:00:52]     let mut _9: i32;
[01:00:52]     bb0: {
[01:00:52]         StorageLive(_1);
[01:00:52]         StorageLive(_2);
[01:00:52]         _2 = std::option::Option<i32>::Some(const 42i32,);
[01:00:52]         _3 = discriminant(_2);
[01:00:52]         _6 = discriminant(_2);
[01:00:52]         switchInt(move _6) -> [0isize: bb4, 1isize: bb6, otherwise: bb8];
[01:00:52]     }
[01:00:52]     bb1: {
[01:00:52]         resume;
[01:00:52]     }
[01:00:52]     bb2: {
[01:00:52]         StorageLive(_8);
[01:00:52]         _8 = _4;
[01:00:52]         _1 = (const 1i32, move _8);
[01:00:52]         StorageDead(_8);
[01:00:52]         goto -> bb13;
[01:00:52]     }
[01:00:52]     bb3: {
[01:00:52]         _1 = (const 3i32, const 3i32);
[01:00:52]         goto -> bb13;
[01:00:52]     }
[01:00:52]     bb4: {
[01:00:52]         falseEdges -> [real: bb9, imaginary: bb5];
[01:00:52]     }
[01:00:52]     bb5: {
[01:00:52]         falseEdges -> [real: bb12, imaginary: bb6];
[01:00:52]     }
[01:00:52]     bb6: {          [01:00:52] failures:
[01:00:52]     [mir-opt] mir-opt/match_false_edges.rs
[01:00:52]
[01:00:52] test result: FAILED. 49 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
[01:00:52]
[01:00:52]
[01:00:52]
[01:00:52] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/mir-opt" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/mir-opt" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "mir-opt" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zmiri -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zmiri -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:00:52] expected success, got: exit code: 101
[01:00:52]
[01:00:52]
[01:00:52] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:00:52] Build completed unsuccessfully in 0:18:09
[01:00:52] Makefile:58: recipe for target 'check' failed
[01:00:52] make: *** [check] Error 1

If this was not helpful or you have suggestes for improvements, please ping or otherwise contact @TimNN.

That allows us to have a better path from Result<T, E> to Option<T>
in the general case, without niche-filling optimisations.
@shepmaster shepmaster added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 30, 2018
{
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize;
Copy link
Member

Choose a reason for hiding this comment

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

Couldn't this use is_none() or is_some()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I guess I could use is_none, I'll check that it still produces the same code as for
Result<T, ()>.

@glandium
Copy link
Contributor

This feels like a terrible idea. This moves statics initialized to None from .bss to .data.

@glandium
Copy link
Contributor

glandium commented Mar 31, 2018

e.g. static mut FOO : Option<LargeStruct> = None turns from taking no space in binaries to taking sizeof(LargeStruct) + sizeof(discriminant).

@scottmcm
Copy link
Member

@glandium Maybe that's a good way to answer #49499 (comment), since I assume Results in statics are rarer?

@nox
Copy link
Contributor Author

nox commented Mar 31, 2018 via email

@oli-obk
Copy link
Contributor

oli-obk commented Mar 31, 2018

I just want to note that static mut is always in data. We should still change Result instead, because I can see use cases for None consts or immutable statics

@Manishearth
Copy link
Member

Manishearth commented Apr 1, 2018

I kinda feel that relying on variant order is a bit fragile -- how do folks feel about a #[rustc_explicit_discriminant] unstable attribute which we use on both Option and Result to keep their discriminants the same?

@scottmcm
Copy link
Member

scottmcm commented Apr 1, 2018

I'm not sure I understand what the attribute would do, @Manishearth. Would it be like rust-lang/rfcs#2363?

(Personally, I wish #[derive(PartialOrd)] on an enum made the different variants incomparable, so that the order of the variants would never be observable, but that ship's long since sailed.)

@nox
Copy link
Contributor Author

nox commented Apr 1, 2018

I kinda feel that relying on variant order is a bit fragile -- how do folks feel about a #[rustc_explicit_discriminant] unstable attribute which we use on both Option and Result to keep their discriminants the same?

This is what rust-lang/rfcs#2363 is for as Scott said, but I wanted to add that I don't want to block a codegen improvement on landing that RFC. We can very well rewrite the definition of both the Result<T, E> and Option<T> enums once the explicit discriminants land.

Note that you would also need the second hook of 56f2875, so that enums with explicit discriminants don't get opted out of niche-filling optimisations.

@glandium
Copy link
Contributor

glandium commented Apr 1, 2018

How would you keep things like Option<char> optimized in such a way that None is not 0 which allows Option<char> to have the same size as char, if you add an explicit discriminant? Specialization?

@eddyb
Copy link
Member

eddyb commented Apr 1, 2018

Note that none of the null / niche / invalid value optimizations care about variant order and they have never cared for as far back as I can remember, years before 1.0. None being "0" has never been part of it AFAIK.

@Manishearth
Copy link
Member

@scottmcm Yes, it is rust-lang/rfcs#2363 exactly, though as a lightweight attribute instead of a syntax change.

@nox As long as it's unstable and only used internally it's not blocked on the RFC. This is also why I was suggesting an attribute -- it's easier to implement, and easier to remove.

@nox
Copy link
Contributor Author

nox commented Apr 1, 2018

@nox As long as it's unstable and only used internally it's not blocked on the RFC. This is also why I was suggesting an attribute -- it's easier to implement, and easier to remove.

It's not easier to implement a new attribute than it is to swap 2 variants in an enum, especially if that attribute is a technical debt to be removed when my RFC lands.

That being said I'm tempted to just close this one and reopen one for Result<T, E>.

@Manishearth
Copy link
Member

It's not easier to implement a new attribute than it is to swap 2 variants in an enum,

I'm not saying it is, it's easier to implement than the RFC itself.

especially if that attribute is a technical debt to be removed when my RFC lands.

If your RFC lands you would probably be able to reuse the implementation, and replace the attribute with a hard syntax change.

@Manishearth
Copy link
Member

To be clear: I don't want to block this on that; but I do feel that in the long term we want something less fragile here, and I feel that implementing that RFC as an attribute (or implementing it entirely, either way), but keeping it behind a feature flag, is the best way to go forward. Either in this PR or as a followup issue.

There is more precedent for implementing lang features as attributes for stdlib optimizations.

@nox
Copy link
Contributor Author

nox commented Apr 5, 2018

I've thought a bit more about it, and implementing the niche-filling optimisation on enums with explicit discriminants is more complex than I thought it would be, so I think we should still try to just reverse the 2 variants of one of the two enums Option<T> or Result<T, E>, and the latter makes more sense given the past discussions on that PR.

/me goes back to filing WebGL issues, please don't nerdsnipe him ( ._.).

@pietroalbini
Copy link
Member

Ping from triage! What's the status on this PR?

@nox
Copy link
Contributor Author

nox commented Apr 9, 2018

I'll reopen it later as a Result<T, E> swap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. WG-llvm Working group: LLVM backend code generation
Projects
None yet
Development

Successfully merging this pull request may close these issues.