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

Less conservative uninhabitedness check #54125

Open
wants to merge 22 commits into
base: master
from

Conversation

@varkor
Member

varkor commented Sep 11, 2018

Extends the uninhabitedness check to structs, non-empty enums, tuples and arrays.

Pulled out of #47291 and #50262.

Fixes #54586.

r? @nikomatsakis

@rust-highfive

This comment was marked as resolved.

Collaborator

rust-highfive commented Sep 11, 2018

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). 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.
[00:53:30] ....................................................................................................
[00:53:33] ....................................................................................................
[00:53:37] ......................................................i.............................................
[00:53:41] ....................................................................................................
[00:53:44] ..........................................................................F.........................
[00:53:48] ........i............................................................
[00:53:48] failures:
[00:53:48] 
[00:53:48] ---- [ui] ui/uninhabited/uninhabited-matches-feature-gated.rs stdout ----
[00:53:48] ---- [ui] ui/uninhabited/uninhabited-matches-feature-gated.rs stdout ----
[00:53:48] diff of stderr:
[00:53:48] 
[00:53:48] 16 LL |     let _ = match x {}; //~ ERROR non-exhaustive
[00:53:48] 18 
[00:53:48] 18 
[00:53:48] - error[E0004]: non-exhaustive patterns: type (Void,) is non-empty
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - LL |     let _ = match x {}; //~ ERROR non-exhaustive
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - LL |     let _ = match x {}; //~ ERROR non-exhaustive
[00:53:48] - 
[00:53:48] - 
[00:53:48] - error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - LL |     let _ = match x {}; //~ ERROR non-exhaustive
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
[00:53:48] -    |
[00:53:48] -    |
[00:53:48] - LL |     let _ = match x {}; //~ ERROR non-exhaustive
[00:53:48] - 
[00:53:48] - 
[00:53:48] 43 error[E0004]: non-exhaustive patterns: `&[_]` not covered
[00:53:48] 45    |
[00:53:48] 
[00:53:48] 
[00:53:48] 58 LL |     let Ok(x) = x;
[00:53:48] 59    |         ^^^^^ pattern `Err(_)` not covered
[00:53:48] - error: aborting due to 7 previous errors
[00:53:48] + error: aborting due to 5 previous errors
[00:53:48] 62 
[00:53:48] 63 Some errors occurred: E0004, E0005.
[00:53:48] 63 Some errors occurred: E0004, E0005.
[00:53:48] 64 For more information about an error, try `rustc --explain E0004`.
[00:53:48] 
[00:53:48] 
[00:53:48] The actual stderr differed from the expected stderr.
[00:53:48] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/uninhabited/uninhabited-matches-feature-gated/uninhabited-matches-feature-gated.stderr
[00:53:48] To update references, rerun the tests and pass the `--bless` flag
[00:53:48] To only update this specific test, also pass `--test-args uninhabited/uninhabited-matches-feature-gated.rs`
[00:53:48] error: 1 errors occurred comparing output.
[00:53:48] status: exit code: 1
[00:53:48] status: exit code: 1
[00:53:48] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/uninhabited/uninhabited-matches-feature-gated/a" "-Crpath" "-O" "-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/ui/uninhabited/uninhabited-matches-feature-gated/auxiliary" "-A" "unused"
[00:53:48] ------------------------------------------
[00:53:48] 
[00:53:48] ------------------------------------------
[00:53:48] stderr:
[00:53:48] stderr:
[00:53:48] ------------------------------------------
[00:53:48] {"message":"non-exhaustive patterns: `Err(_)` not covered","code":{"code":"E0004","explanation":"\nThis error indicates that the compiler cannot guarantee a matching pattern for\none or more possible inputs to a match expression. Guaranteed matches are\nrequired in order to assign values to match expressions, or alternatively,\ndetermine the flow of execution. Erroneous code example:\n\n```compile_fail,E0004\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered\n    Terminator::TalkToMyHand => {}\n}\n```\n\nIf you encounter this error you must alter your patterns so that every possible\nvalue of the input type is matched. For types with a small number of variants\n(like enums) you should probably cover all cases explicitly. Alternatively, the\nunderscore `_` wildcard pattern can be added after all other patterns to match\n\"anything else\". Example:\n\n```\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    Terminator::HastaLaVistaBaby => {}\n}\n\n// or:\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    _ => {}\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":559,"byte_end":560,"line_start":15,"line_end":15,"column_start":19,"column_end":20,"is_primary":true,"text":[{"text":"    let _ = match x {   //~ ERROR non-exhaustive","highlight_start":19,"highlight_end":20}],"label":"pattern `Err(_)` not covered","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0004]: non-exhaustive patterns: `Err(_)` not covered\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:15:19\n   |\nLL |     let _ = match x {   //~ ERROR non-exhaustive\n   |                   ^ pattern `Err(_)` not covered\n\n"}
[00:53:48] {"message":"non-exhaustive patterns: type &Void is non-empty","code":{"code":"E0004","explanation":"\nThis error indicates that the compiler cannot guarantee a matching pattern for\none or more possible inputs to a match expression. Guaranteed matches are\nrequired in order to assign values to match expressions, or alternatively,\ndetermine the flow of execution. Erroneous code example:\n\n```compile_fail,E0004\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered\n    Terminator::TalkToMyHand => {}\n}\n```\n\nIf you encounter this error you must alter your patterns so that every possible\nvalue of the input type is matched. For types with a small number of variants\n(like enums) you should probably cover all cases explicitly. Alternatively, the\nunderscore `_` wildcard pattern can be added after all other patterns to match\n\"anything else\". Example:\n\n```\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    Terminator::HastaLaVistaBaby => {}\n}\n\n// or:\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    _ => {}\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":693,"byte_end":694,"line_start":20,"line_end":20,"column_start":19,"column_end":20,"is_primary":true,"text":[{"text":"    let _ = match x {}; //~ ERROR non-exhaustive","highlight_start":19,"highlight_end":20}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.","code":null,"level":"help","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":693,"byte_end":694,"line_start":20,"line_end":20,"column_start":19,"column_end":20,"is_primary":true,"text":[{"text":"    let _ = match x {}; //~ ERROR non-exhaustive","highlight_start":19,"highlight_end":20}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0004]: non-exhaustive patterns: type &Void is non-empty\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:20:19\n   |\nLL |     let _ = match x {}; //~ ERROR non-exhaustive\n   |                   ^\n   |\nhelp: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:20:19\n   |\nLL |     let _ = match x {}; //~ ERROR non-exhaustive\n   |                   ^\n\n"}
[00:53:48] {"message":"non-exhaustive patterns: `&[_]` not covered","code":{"code":"E0004","explanation":"\nThis error indicates that the compiler cannot guarantee a matching pattern for\none or more possible inputs to a match expression. Guaranteed matches are\nrequired in order to assign values to match expressions, or alternatively,\ndetermine the flow of execution. Erroneous code example:\n\n```compile_fail,E0004\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered\n    Terminator::TalkToMyHand => {}\n}\n```\n\nIf you encounter this error you must alter your patterns so that every possible\nvalue of the input type is matched. For types with a small number of variants\n(like enums) you should probably cover all cases explicitly. Alternatively, the\nunderscore `_` wildcard pattern can be added after all other patterns to match\n\"anything else\". Example:\n\n```\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    Terminator::HastaLaVistaBaby => {}\n}\n\n// or:\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    _ => {}\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":1022,"byte_end":1023,"line_start":29,"line_end":29,"column_start":19,"column_end":20,"is_primary":true,"text":[{"text":"    let _ = match x {   //~ ERROR non-exhaustive","highlight_start":19,"highlight_end":20}],"label":"pattern `&[_]` not covered","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0004]: non-exhaustive patterns: `&[_]` not covered\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:29:19\n   |\nLL |     let _ = match x {   //~ ERROR non-exhaustive\n   |                   ^ pattern `&[_]` not covered\n\n"}
[00:53:48] {"message":"non-exhaustive patterns: `Err(_)` not covered","code":{"code":"E0004","explanation":"\nThis error indicates that the compiler cannot guarantee a matching pattern for\none or more possible inputs to a match expression. Guaranteed matches are\nrequired in order to assign values to match expressions, or alternatively,\ndetermine the flow of execution. Erroneous code example:\n\n```compile_fail,E0004\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered\n    Terminator::TalkToMyHand => {}\n}\n```\n\nIf you encounter this error you must alter your patterns so that every possible\nvalue of the input type is matched. For types with a small number of variants\n(like enums) you should probably cover all cases explicitly. Alternatively, the\nunderscore `_` wildcard pattern can be added after all other patterns to match\n\"anything else\". Example:\n\n```\nenum Terminator {\n    HastaLaVistaBaby,\n    TalkToMyHand,\n}\n\nlet x = Terminator::HastaLaVistaBaby;\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    Terminator::HastaLaVistaBaby => {}\n}\n\n// or:\n\nmatch x {\n    Terminator::TalkToMyHand => {}\n    _ => {}\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":1226,"byte_end":1227,"line_start":37,"line_end":37,"column_start":19,"column_end":20,"is_primary":true,"text":[{"text":"    let _ = match x {   //~ ERROR non-exhaustive","highlight_start":19,"highlight_end":20}],"label":"pattern `Err(_)` not covered","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0004]: non-exhaustive patterns: `Err(_)` not covered\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:37:19\n   |\nLL |     let _ = match x {   //~ ERROR non-exhaustive\n   |                   ^ pattern `Err(_)` not covered\n\n"}
[00:53:48] {"message":"refutable pattern in local binding: `Err(_)` not covered","code":{"code":"E0005","explanation":"\nPatterns used to bind names must be irrefutable, that is, they must guarantee\nthat a name will be extracted in all cases. Erroneous code example:\n\n```compile_fail,E0005\nlet x = Some(1);\nlet Some(y) = x;\n// error: refutable pattern in local binding: `None` not covered\n```\n\nIf you encounter this error you probably need to use a `match` or `if let` to\ndeal with the possibility of failure. Example:\n\n```\nlet x = Some(1);\n\nmatch x {\n    Some(y) => {\n        // do something\n    },\n    None => {}\n}\n\n// or:\n\nif let Some(y) = x {\n    // do something\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs","byte_start":1332,"byte_end":1337,"line_start":42,"line_end":42,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":"    let Ok(x) = x;","highlight_start":9,"highlight_end":14}],"label":"pattern `Err(_)` not covered","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0005]: refutable pattern in local binding: `Err(_)` not covered\n  --> /checkout/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs:42:9\n   |\nLL |     let Ok(x) = x;\n   |         ^^^^^ pattern `Err(_)` not covered\n\n"}
[00:53:48] {"message":"aborting due to 5 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 5 previous errors\n\n"}
[00:53:48] {"message":"Some errors occurred: E0004, E0005.","code":null,"level":"","spans":[],"children":[],"rendered":"Some errors occurred: E0004, E0005.\n"}
[00:53:48] {"message":"For more information about an error, try `rustc --explain E0004`.","code":null,"level":"","spans":[],"children":[],"rendered":"For more information about an error, try `rustc --explain E0004`.\n"}
[00:53:48] ------------------------------------------
[00:53:48] 
[00:53:48] thread '[ui] ui/uninhabited/uninhabited-matches-feature-gated.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:3196:9
[00:53:48] note: Run with `RUST_BACKTRACE=1` for a backtrace.
---
[00:53:48] 
[00:53:48] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:497:22
[00:53:48] 
[00:53:48] 
[00:53:48] 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/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-5.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -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" "5.0.0\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:53:48] 
[00:53:48] 
[00:53:48] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:53:48] Build completed unsuccessfully in 0:08:03
[00:53:48] Build completed unsuccessfully in 0:08:03
[00:53:48] Makefile:58: recipe for target 'check' failed
[00:53:48] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:031817e1
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:0179bdce:start=1536670857442547996,finish=1536670857451384567,duration=8836571
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1a420044
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:17b764fc
travis_time:start:17b764fc
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:0359db09
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Show resolved Hide resolved src/librustc/ty/sty.rs Outdated
Show resolved Hide resolved src/librustc/ty/sty.rs Outdated
Show resolved Hide resolved src/librustc/ty/sty.rs Outdated
@eddyb

This comment has been minimized.

Member

eddyb commented Sep 14, 2018

I'm not sure I understand why places which checked .abi == Abi::Uninhabited where changed - an user-facing type-check-level "weak equivalence" to ! is not the same as the lower-level "whole values of this layout do not exist" (that optimizations can assume).

Ideally we'd have some implication between them, e.g. we can make a query for conservative_is_uninhabited (with the proper substitution and normalization that layout code does) and layout could assert that Abi::Uninhabited implies conservative_is_uninhabited as well.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Sep 14, 2018

I'm not sure I understand why places which checked .abi == Abi::Uninhabited where changed - an user-facing type-check-level "weak equivalence" to ! is not the same as the lower-level "whole values of this layout do not exist" (that optimizations can assume).

It is also not clear to me if we should change this code, but I think a possible justification arises from this stuff I wrote earlier:

In the terms from @RalfJung's Two Kinds of Invariants blog post, the justification for optimizations around uninhabitedness arises from the validity invariant (to a large extent). All values that the compiler thinks are initialized must meet this invariant: presumably this includes the return value. This means that, yes, if we find a ! embedded within a struct or tuple, we can justify saying that the fn never returns (etc).

But the validity invariant for &! is different, and doesn't require that the pointer is valid. The same is true of unions.

We might wind up requiring a stronger invariant of fn return values, mind you, that would make returning &! UB, but I think this is unlikely and certainly not decided.

But the validity invariant for &! is different, and doesn't require that the pointer is valid. The same is true of unions.

That said, I'm not entirely sure how to think about unions, and I'm wondering if what I wrote above is strictly correct. =) In particular, the compiler will (I think) get with you if you don't initialization the union somehow...? You might though be able to use a MaybeInit or something to read it out. I feel like we haven't quite settled enough of the rules to crisply call that illegal.
We might wind up requiring a stronger invariant of fn return values, mind you, that would make returning &! UB, but I think this is unlikely and certainly not decided.

@varkor

This comment has been minimized.

Member

varkor commented Sep 14, 2018

I'm not sure I understand why places which checked .abi == Abi::Uninhabited where changed - an user-facing type-check-level "weak equivalence" to ! is not the same as the lower-level "whole values of this layout do not exist" (that optimizations can assume).

I'll admit I mostly copied these over from the original PR — and I think at the time they were made, Abi::Uninhabited wasn't as precise as it is now (I could be mistaken about that, though). It shouldn't make much difference in these particular places, but I'll revert the changes.

I feel like we haven't quite settled enough of the rules to crisply call that illegal.

It's safer to treat them as possibly-inhabited for now.

@RalfJung

This comment has been minimized.

Member

RalfJung commented Sep 18, 2018

Extends the uninhabitedness check to [...] unions

Uh, please don't. We want to have some proper discussion before we make any assumption about union contents.

Show resolved Hide resolved src/librustc/ty/sty.rs Outdated
@varkor

This comment has been minimized.

Member

varkor commented Sep 18, 2018

Uh, please don't. We want to have some proper discussion before we make any assumption about union contents.

Ah, I removed the union handling, but forgot to update the comment. Unions are now currently never treated as uninhabited.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Sep 18, 2018

@varkor

Ah, I removed the union handling, but forgot to update the comment. Unions are now currently never treated as uninhabited.

Maybe you forgot to push? The code I am looking at doesn't seem to check for unions?

@varkor

This comment has been minimized.

Member

varkor commented Sep 18, 2018

Maybe you forgot to push? The code I am looking at doesn't seem to check for unions?

It's just above the main ADT handling:
https://github.com/rust-lang/rust/pull/54125/files#diff-b180e2fcc6ac765371cbd5b1dc95c914R1481

@RalfJung

This comment has been minimized.

Member

RalfJung commented Sep 19, 2018

Btw, #53508 also introduces an is_uninhabited function for layouts. Seems like there is some overlap?

Cc @japaric

@eddyb

This comment has been minimized.

Member

eddyb commented Sep 19, 2018

@RalfJung that's just a helper - you can't always compute the layout, even in cases where you determine separately from the layout, that the type is uninhabited.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Sep 20, 2018

@varkor

The comment about &T is still wrong. The current comment is definitely wrong. It says that null references are permitted in unsafe code, but in fact they are not (else the Option<&T> layout optimization is incorrect). What would be permitted is "non-null references to uninitialized memory".

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Sep 20, 2018

I am removing the S-blocked annotation since there was a deadlock:

This PR claimed to be blocked on #54123, but #54123 contained an annotation that it's better to review this one.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Sep 20, 2018

I changed to S-waiting-on-author because we need to at minimum change that comment. Other than that, I don't remember if there are any blocking concerns here?

Centril added a commit to Centril/rust that referenced this pull request Dec 2, 2018

Rollup merge of rust-lang#56110 - varkor:inhabitedness-union-enum, r=…
…cramertj

Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at rust-lang#54125.

cc @RalfJung

Centril added a commit to Centril/rust that referenced this pull request Dec 2, 2018

Rollup merge of rust-lang#56110 - varkor:inhabitedness-union-enum, r=…
…cramertj

Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at rust-lang#54125.

cc @RalfJung

Centril added a commit to Centril/rust that referenced this pull request Dec 2, 2018

Rollup merge of rust-lang#56110 - varkor:inhabitedness-union-enum, r=…
…cramertj

Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at rust-lang#54125.

cc @RalfJung

Centril added a commit to Centril/rust that referenced this pull request Dec 2, 2018

Rollup merge of rust-lang#56110 - varkor:inhabitedness-union-enum, r=…
…cramertj

Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at rust-lang#54125.

cc @RalfJung

Centril added a commit to Centril/rust that referenced this pull request Dec 2, 2018

Rollup merge of rust-lang#56110 - varkor:inhabitedness-union-enum, r=…
…cramertj

Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at rust-lang#54125.

cc @RalfJung

bors added a commit that referenced this pull request Dec 2, 2018

Auto merge of #56110 - varkor:inhabitedness-union-enum, r=cramertj
Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks

It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types.

This will also be more important in light of the changes at #54125.

cc @RalfJung

@varkor varkor force-pushed the varkor:less-conservative-uninhabitedness-check branch from 75de30f to 2ba3e66 Dec 11, 2018

@varkor

This comment has been minimized.

Member

varkor commented Dec 11, 2018

I'd like to at least have a mir-opt testcase for

I've added a mir-opt test, though with the reversion of the destination uninhabitedness checking (see below), they currently do result in slightly different MIR.


Regarding the state of the PR, I think it's ready. I've reverted the change in into.rs, since we seem to be unable to get the current module for visibility-based uninhabitedness checking there (#54125 (comment)) currently, so I've left it as a FIXME. It'd be good to get at least these changes approved and then we can make it more flexible in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment