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

Move error codes #66314

Merged
merged 14 commits into from
Nov 14, 2019
Merged

Move error codes #66314

merged 14 commits into from
Nov 14, 2019

Conversation

GuillaumeGomez
Copy link
Member

@GuillaumeGomez GuillaumeGomez commented Nov 11, 2019

Works towards #66210.

r? @Centril

Oh btw, for the ones interested, I used this python script to get all error codes content sorted into one final file:

from os import listdir
from os.path import isdir, isfile, join


def get_error_codes(error_codes, f_path):
    with open(f_path) as f:
        short_mode = False
        lines = f.read().split("\n")
        i = 0
        while i < len(lines):
            line = lines[i]
            if not short_mode and line.startswith("E0") and line.endswith(": r##\""):
                error = line
                error += "\n"
                i += 1
                while i < len(lines):
                    line = lines[i]
                    error += line
                    if line.endswith("\"##,"):
                        break
                    error += "\n"
                    i += 1
                error_codes["long"].append(error)
            elif line == ';':
                short_mode = True
            elif short_mode is True and len(line) > 0 and line != "}":
                error_codes["short"].append(line)
                while i + 1 < len(lines):
                    line = lines[i + 1].strip()
                    if not line.startswith("//"):
                        break
                    parts = line.split("//")
                    if len(parts) < 2:
                        break
                    if parts[1].strip().startswith("E0"):
                        break
                    error_codes["short"][-1] += "\n"
                    error_codes["short"][-1] += lines[i + 1]
                    i += 1
            i += 1


def loop_dirs(error_codes, cur_dir):
    for entry in listdir(cur_dir):
        f = join(cur_dir, entry)
        if isfile(f) and entry == "error_codes.rs":
            get_error_codes(error_codes, f)
        elif isdir(f) and not entry.startswith("librustc_error_codes"):
            loop_dirs(error_codes, f)


def get_error_code(err):
    x = err.split(",")
    if len(x) < 2:
        return err
    x = x[0]
    if x.strip().startswith("//"):
        x = x.split("//")[1].strip()
    return x.strip()


def write_into_file(error_codes, f_path):
    with open(f_path, "w") as f:
        f.write("// Error messages for EXXXX errors.  Each message should start and end with a\n")
        f.write("// new line, and be wrapped to 80 characters.  In vim you can `:set tw=80` and\n")
        f.write("// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.\n\n")
        f.write("syntax::register_diagnostics! {\n\n")
        error_codes["long"].sort()
        for i in error_codes["long"]:
            f.write(i)
            f.write("\n\n")
        f.write(";\n")
        error_codes["short"] = sorted(error_codes["short"], key=lambda err: get_error_code(err))
        for i in error_codes["short"]:
            f.write(i)
            f.write("\n")
        f.write("}\n")



error_codes = {
    "long": [],
    "short": []
}
loop_dirs(error_codes, "src")
write_into_file(error_codes, "src/librustc_error_codes/src/error_codes.rs")

And to move the error codes into their own files:

import os

try:
    os.mkdir("src/librustc_error_codes/error_codes")
except OSError:
    print("Seems like folder already exist, moving on!")
data = ''
with open("src/librustc_error_codes/error_codes.rs") as f:
    x = f.read().split('\n')
    i = 0
    short_part = False
    while i < len(x):
        line = x[i]
        if short_part is False and line.startswith('E0') and line.endswith(': r##"'):
            err_code = line.split(':')[0]
            i += 1
            content = ''
            while i < len(x):
                if x[i] == '"##,':
                    break
                content += x[i]
                content += '\n'
                i += 1
            f_path = "src/librustc_error_codes/error_codes/{}.md".format(err_code)
            with open(f_path, "w") as ff:
                ff.write(content)
            data += '{}: include_str!("./error_codes/{}.md"),'.format(err_code, err_code)
        elif short_part is False and line == ';':
            short_part is True
            data += ';\n'
        else:
            data += line
            data += '\n'
        i += 1
with open("src/librustc_error_codes/error_codes.rs", "w") as f:
    f.write(data)

@rust-highfive
Copy link
Collaborator

Some changes occurred in diagnostic error codes

cc @GuillaumeGomez

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 11, 2019
@rust-highfive

This comment has been minimized.

@Dylan-DPC-zz Dylan-DPC-zz added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 11, 2019
@GuillaumeGomez GuillaumeGomez added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 11, 2019
@rust-highfive

This comment has been minimized.

@@ -1,7 +1,7 @@
#[macro_export]
Copy link
Contributor

Choose a reason for hiding this comment

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

The remainder of this file should probably be moved to librustc_errors?

Copy link
Member Author

Choose a reason for hiding this comment

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

They seem to be "independent"? A bit weird...

@@ -16,6 +16,8 @@ use std::fmt::{self, Display};
use syntax::{attr, symbol::sym};
use syntax_pos::Span;

use rustc_error_codes::*;
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm; why do this in each of the files? Shouldn't we change the diagnostics macros to not use constants at all but rather to just do the stringification? Tidy can do the validation later to make sure that there are no unused error codes or references to codes not registered. This way we don't have to change any of the Cargo.toml files here except for librustc_interface.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't agree with this: it allows us to be sure that the used error codes exist at compile time. If we switch to strings, we won't be able to have this check anymore (or at least, not at compile time).

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused... In the issue you noted that doing what you are doing here would make the recompilation issue worse, so what changed? -- Tidy is part of "compile time" for the purposes of CI so moving the checks there still means problems are rejected. Moreover, eventually and ideally we want to make this crate only have rustc_driver as the only reverse dependency and maybe even link this in dynamically so that it can be swapped for something else at runtime (e.g. for Spanish translations or whatnot).

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem is that, if we do it like this, the only way to check that a used error code exists will be to add another check after the compiler is built. I prefer re-building some dependencies rather than having to wait the whole build to see if I didn't forget to create a new error code.

Copy link
Contributor

Choose a reason for hiding this comment

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

If that's an issue then we can move the tidy checks (or this specific check) early or something and always execute them on e.g. ./x.py test -i src/test/ui --stage 1 --pass check which is the common command to do. We could also execute tidy on ./x.py check. cc @Mark-Simulacrum

The way you've implemented this now, if I were to e.g. add a new error code I would need to rebuild pretty much everything, including librustc, instead of just rebuilding librustc_interface, which goes quickly. This would be painful if all you want to do is to --bless some UI tests.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, then I suggest this: let's open an issue about this once this PR is merged and handle it into another PR. I think this one is already *huge* enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough. :)

Copy link
Member

Choose a reason for hiding this comment

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

I am against adding anything to x.py check or x.py test that runs by default and isn't tidy. You can always run tidy first if you want.

Copy link
Contributor

Choose a reason for hiding this comment

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

@Mark-Simulacrum What about always running tidy on said commands? -- I personally have been bitten many times by forgetting to do so since I typically never use the full ./x.py test and I always forget to run tidy manually.

Copy link
Member

Choose a reason for hiding this comment

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

I am against running tidy implicitly unless we can make it much faster; currently it's 1-3 seconds of overhead which is way to much for a "always run" type command.

src/librustc_interface/Cargo.toml Show resolved Hide resolved

#[macro_export]
macro_rules! register_diagnostics {
($($ecode:ident: $message:expr,)*) => (
Copy link
Contributor

Choose a reason for hiding this comment

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

This matcher looks unused now.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's still being used actually. (it's the separation between long and short error codes) :)

$( (stringify!($ecode), $message), )*
];

$(
Copy link
Contributor

Choose a reason for hiding this comment

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

These constants shouldn't be necessary if we unlink things from the various crates as noted in a different comment of mine.

Copy link
Member Author

Choose a reason for hiding this comment

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

Like I said, if we decide to do it, let's make it into another PR. I think this one is already big enough.

//! being to make their maintenance easier.

#[macro_export]
macro_rules! register_diagnostics {
Copy link
Contributor

Choose a reason for hiding this comment

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

And then this macro can be inlined to where it is defined.

Copy link
Member Author

Choose a reason for hiding this comment

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

Again: I prefer to keep them separated, makes the reading simpler.


mod error_codes;

pub use error_codes::*;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could just export DIAGNOSTICS now that it is the only item of interest; alternatively, since it is the only item, we could inline the whole error_codes file into lib.rs.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd prefer not. The file is big enough on its own so let's keep what's error code specific outside if possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

It becomes small after using include!(...)s. ;)

Copy link
Member Author

Choose a reason for hiding this comment

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

(unless the error codes long explanation are moved into files.

Copy link
Member Author

Choose a reason for hiding this comment

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

Even after the change, I still think it's better to keep it in its own file. :)

src/librustc_error_codes/error_codes.rs Outdated Show resolved Hide resolved
@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

@GuillaumeGomez
Copy link
Member Author

So it seems like all is done and that we need to open some issues?

What do you think @Centril ?

@Centril
Copy link
Contributor

Centril commented Nov 12, 2019

Adding a checkbox to the existing issue would be enough I think.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Nov 13, 2019

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

@GuillaumeGomez
Copy link
Member Author

@Centril It's getting a bit complicated to follow with the rebases. A little review please so I can move forward? :)

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, 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.
2019-11-13T17:02:12.5254453Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-11-13T17:02:13.3023164Z ##[command]git config gc.auto 0
2019-11-13T17:02:13.3027337Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-11-13T17:02:13.3028933Z ##[command]git config --get-all http.proxy
2019-11-13T17:02:13.3036495Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/66314/merge:refs/remotes/pull/66314/merge
---
2019-11-13T17:05:15.1073939Z 
2019-11-13T17:05:15.1074707Z ######################################################################## 100.0%
2019-11-13T17:05:15.4094561Z extracting /checkout/obj/build/cache/2019-11-06/cargo-beta-x86_64-unknown-linux-gnu.tar.gz
2019-11-13T17:05:15.4721266Z     Updating crates.io index
2019-11-13T17:05:20.6012781Z error: the lock file /checkout/Cargo.lock needs to be updated but --locked was passed to prevent this
2019-11-13T17:05:20.6039458Z failed to run: /checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path /checkout/src/bootstrap/Cargo.toml --locked
2019-11-13T17:05:20.6080117Z make: *** [prepare] Error 1
2019-11-13T17:05:20.6080922Z Makefile:67: recipe for target 'prepare' failed
2019-11-13T17:05:21.6109683Z Command failed. Attempt 2/5:
2019-11-13T17:05:21.6109683Z Command failed. Attempt 2/5:
2019-11-13T17:05:21.7710280Z error: the lock file /checkout/Cargo.lock needs to be updated but --locked was passed to prevent this
2019-11-13T17:05:21.7724394Z failed to run: /checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path /checkout/src/bootstrap/Cargo.toml --locked
2019-11-13T17:05:21.7776183Z Makefile:67: recipe for target 'prepare' failed
2019-11-13T17:05:21.7776254Z make: *** [prepare] Error 1
2019-11-13T17:05:23.7797070Z Command failed. Attempt 3/5:
2019-11-13T17:05:23.7797070Z Command failed. Attempt 3/5:
2019-11-13T17:05:23.9529870Z error: the lock file /checkout/Cargo.lock needs to be updated but --locked was passed to prevent this
2019-11-13T17:05:23.9539970Z failed to run: /checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path /checkout/src/bootstrap/Cargo.toml --locked
2019-11-13T17:05:23.9574439Z Makefile:67: recipe for target 'prepare' failed
2019-11-13T17:05:23.9576830Z make: *** [prepare] Error 1
2019-11-13T17:05:26.9588238Z Command failed. Attempt 4/5:
2019-11-13T17:05:26.9588238Z Command failed. Attempt 4/5:
2019-11-13T17:05:27.1512211Z error: the lock file /checkout/Cargo.lock needs to be updated but --locked was passed to prevent this
2019-11-13T17:05:27.1522422Z failed to run: /checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path /checkout/src/bootstrap/Cargo.toml --locked
2019-11-13T17:05:27.1559639Z Makefile:67: recipe for target 'prepare' failed
2019-11-13T17:05:27.1562071Z make: *** [prepare] Error 1
2019-11-13T17:05:31.1575692Z Command failed. Attempt 5/5:
2019-11-13T17:05:31.1575692Z Command failed. Attempt 5/5:
2019-11-13T17:05:31.3200091Z error: the lock file /checkout/Cargo.lock needs to be updated but --locked was passed to prevent this
2019-11-13T17:05:31.3212175Z failed to run: /checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path /checkout/src/bootstrap/Cargo.toml --locked
2019-11-13T17:05:31.3264899Z Makefile:67: recipe for target 'prepare' failed
2019-11-13T17:05:31.3283712Z The command has failed after 5 attempts.
2019-11-13T17:05:31.3283851Z == clock drift check ==
2019-11-13T17:05:31.3283975Z   local time: Wed Nov 13 17:05:31 UTC 2019
2019-11-13T17:05:31.3283975Z   local time: Wed Nov 13 17:05:31 UTC 2019
2019-11-13T17:05:31.3284032Z   network time: make: *** [prepare] Error 1
2019-11-13T17:05:31.3483590Z Wed, 13 Nov 2019 17:05:31 GMT
2019-11-13T17:05:31.3485859Z == end clock drift check ==
2019-11-13T17:05:43.4925006Z 
2019-11-13T17:05:43.5021277Z ##[error]Bash exited with code '1'.
2019-11-13T17:05:43.5044871Z ##[section]Starting: Checkout
2019-11-13T17:05:43.5046431Z ==============================================================================
2019-11-13T17:05:43.5046474Z Task         : Get sources
2019-11-13T17:05:43.5046511Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

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)

@@ -1,4 +1,4 @@
Per [RFC 401][rfc401], if you have a function declaration `foo`:
er [RFC 401][rfc401], if you have a function declaration `foo`:
Copy link
Contributor

Choose a reason for hiding this comment

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

Oops?

@@ -1,5 +1,4 @@
{"message":"mismatched types","code":{"code":"E0308","explanation":"
This error occurs when the compiler was unable to infer the concrete type of a
{"message":"mismatched types","code":{"code":"E0308","explanation":"This error occurs when the compiler was unable to infer the concrete type of a
Copy link
Contributor

Choose a reason for hiding this comment

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

Intentional?

Copy link
Member Author

Choose a reason for hiding this comment

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

Must be part of a rebase I suppose?

Copy link
Contributor

Choose a reason for hiding this comment

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

I've no idea myself. :)

@Centril
Copy link
Contributor

Centril commented Nov 13, 2019

r=me with ^-- addressed somehow and when you think this is landable.

@bors rollup=never p=100

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, 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.
2019-11-13T17:22:07.5009219Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-11-13T17:22:07.5220050Z ##[command]git config gc.auto 0
2019-11-13T17:22:08.1764675Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-11-13T17:22:08.1774715Z ##[command]git config --get-all http.proxy
2019-11-13T17:22:08.1781030Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/66314/merge:refs/remotes/pull/66314/merge
---
2019-11-13T18:23:09.1744607Z .................................................................................................... 1500/9239
2019-11-13T18:23:15.4338496Z .................................................................................................... 1600/9239
2019-11-13T18:23:24.8555339Z .................................................................................................... 1700/9239
2019-11-13T18:23:34.2159583Z ....i............................................................................................... 1800/9239
2019-11-13T18:23:40.6209598Z ........................................................................................iiiii....... 1900/9239
2019-11-13T18:24:02.9164795Z .................................................................................................... 2100/9239
2019-11-13T18:24:05.4299982Z .................................................................................................... 2200/9239
2019-11-13T18:24:08.0523432Z .................................................................................................... 2300/9239
2019-11-13T18:24:15.2871728Z ...................F................................................................................ 2400/9239
---
2019-11-13T18:27:16.8445541Z .......................................................................................i............ 4700/9239
2019-11-13T18:27:23.7107573Z ...i................................................................................................ 4800/9239
2019-11-13T18:27:33.4552911Z .................................................................................................... 4900/9239
2019-11-13T18:27:39.0577004Z .................................................................................................... 5000/9239
2019-11-13T18:27:50.4997859Z ..........................................................................................ii.ii..... 5100/9239
2019-11-13T18:27:59.1898652Z .........................i.......................................................................... 5300/9239
2019-11-13T18:28:08.2310128Z .................................................................................................... 5400/9239
2019-11-13T18:28:17.1298661Z ........................................................................i........................... 5500/9239
2019-11-13T18:28:24.7451868Z .................................................................................................... 5600/9239
2019-11-13T18:28:24.7451868Z .................................................................................................... 5600/9239
2019-11-13T18:28:32.0748374Z .................................................................................................... 5700/9239
2019-11-13T18:28:42.1932822Z ...........................................................ii..i..ii...........i.................... 5800/9239
2019-11-13T18:29:05.6959381Z .................................................................................................... 6000/9239
2019-11-13T18:29:14.3722794Z .................................................................................................... 6100/9239
2019-11-13T18:29:14.3722794Z .................................................................................................... 6100/9239
2019-11-13T18:29:19.2363993Z .............................................................................i..ii.................. 6200/9239
2019-11-13T18:29:49.2671708Z .................................................................................................... 6400/9239
2019-11-13T18:29:52.0907089Z .............................................i...................................................... 6500/9239
2019-11-13T18:29:54.3802927Z .................................................................................................... 6600/9239
2019-11-13T18:29:56.8156306Z .............................i...................................................................... 6700/9239
---
2019-11-13T18:34:56.0476991Z 
2019-11-13T18:34:56.0477760Z ---- [ui] ui/explain.rs stdout ----
2019-11-13T18:34:56.0478024Z diff of stdout:
2019-11-13T18:34:56.0478160Z 
2019-11-13T18:34:56.0478637Z - Per [RFC 401][rfc401], if you have a function declaration `foo`:
2019-11-13T18:34:56.0478873Z + er [RFC 401][rfc401], if you have a function declaration `foo`:
2019-11-13T18:34:56.0479173Z 3 ```
2019-11-13T18:34:56.0479338Z 4 // For the purposes of this explanation, all of these
2019-11-13T18:34:56.0479468Z 
2019-11-13T18:34:56.0479591Z 
2019-11-13T18:34:56.0479591Z 
2019-11-13T18:34:56.0479739Z The actual stdout differed from the expected stdout.
2019-11-13T18:34:56.0480234Z Actual stdout saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/explain/explain.stdout
2019-11-13T18:34:56.0480689Z To update references, rerun the tests and pass the `--bless` flag
2019-11-13T18:34:56.0481162Z To only update this specific test, also pass `--test-args explain.rs`
2019-11-13T18:34:56.0481508Z error: 1 errors occurred comparing output.
2019-11-13T18:34:56.0481670Z status: exit code: 0
2019-11-13T18:34:56.0481670Z status: exit code: 0
2019-11-13T18:34:56.0482581Z command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/explain.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/explain" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--explain" "E0591" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/explain/auxiliary" "-A" "unused"
2019-11-13T18:34:56.0483232Z ------------------------------------------
2019-11-13T18:34:56.0483232Z ------------------------------------------
2019-11-13T18:34:56.0483431Z er [RFC 401][rfc401], if you have a function declaration `foo`:
2019-11-13T18:34:56.0483753Z ```
2019-11-13T18:34:56.0483901Z // For the purposes of this explanation, all of these
2019-11-13T18:34:56.0483901Z // For the purposes of this explanation, all of these
2019-11-13T18:34:56.0484071Z // different kinds of `fn` declarations are equivalent:
2019-11-13T18:34:56.0484745Z struct S;
2019-11-13T18:34:56.0485287Z fn foo(x: S) { /* ... */ }
2019-11-13T18:34:56.0485672Z extern "C" { fn foo(x: S); }
2019-11-13T18:34:56.0485811Z impl S { fn foo(self) { /* ... */ } }
2019-11-13T18:34:56.0486080Z 
2019-11-13T18:34:56.0486080Z 
2019-11-13T18:34:56.0486219Z the type of `foo` is **not** `fn(S)`, as one might expect.
2019-11-13T18:34:56.0486732Z Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`.
2019-11-13T18:34:56.0486940Z However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`,
2019-11-13T18:34:56.0487082Z so you rarely notice this:
2019-11-13T18:34:56.0487358Z ```
2019-11-13T18:34:56.0487358Z ```
2019-11-13T18:34:56.0487497Z let x: fn(S) = foo; // OK, coerces
2019-11-13T18:34:56.0487757Z 
2019-11-13T18:34:56.0487757Z 
2019-11-13T18:34:56.0487917Z The reason that this matter is that the type `fn(S)` is not specific to
2019-11-13T18:34:56.0488443Z any particular function: it's a function _pointer_. So calling `x()` results
2019-11-13T18:34:56.0488653Z in a virtual call, whereas `foo()` is statically dispatched, because the type
2019-11-13T18:34:56.0488816Z of `foo` tells us precisely what function is being called.
2019-11-13T18:34:56.0488959Z 
2019-11-13T18:34:56.0489360Z As noted above, coercions mean that most code doesn't have to be
2019-11-13T18:34:56.0489550Z concerned with this distinction. However, you can tell the difference
2019-11-13T18:34:56.0489810Z when using **transmute** to convert a fn item into a fn pointer.
2019-11-13T18:34:56.0490095Z This is sometimes done as part of an FFI:
2019-11-13T18:34:56.0490212Z 
2019-11-13T18:34:56.0490358Z ```
2019-11-13T18:34:56.0490358Z ```
2019-11-13T18:34:56.0490492Z extern "C" fn foo(userdata: Box<i32>) {
2019-11-13T18:34:56.0490628Z     /* ... */
2019-11-13T18:34:56.0491056Z 
2019-11-13T18:34:56.0491056Z 
2019-11-13T18:34:56.0491198Z let f: extern "C" fn(*mut i32) = transmute(foo);
2019-11-13T18:34:56.0491353Z callback(f);
2019-11-13T18:34:56.0491599Z 
2019-11-13T18:34:56.0491762Z Here, transmute is being used to convert the types of the fn arguments.
2019-11-13T18:34:56.0491937Z This pattern is incorrect because, because the type of `foo` is a function
2019-11-13T18:34:56.0491937Z This pattern is incorrect because, because the type of `foo` is a function
2019-11-13T18:34:56.0492391Z **item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
2019-11-13T18:34:56.0492934Z is a function pointer, which is not zero-sized.
2019-11-13T18:34:56.0493120Z This pattern should be rewritten. There are a few possible ways to do this:
2019-11-13T18:34:56.0493610Z - change the original fn declaration to match the expected signature,
2019-11-13T18:34:56.0493815Z   and do the cast in the fn body (the preferred option)
2019-11-13T18:34:56.0493815Z   and do the cast in the fn body (the preferred option)
2019-11-13T18:34:56.0494843Z - cast the fn item fo a fn pointer before calling transmute, as shown here:
2019-11-13T18:34:56.0495181Z     ```
2019-11-13T18:34:56.0495181Z     ```
2019-11-13T18:34:56.0495322Z     let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
2019-11-13T18:34:56.0495491Z     let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
2019-11-13T18:34:56.0495640Z     ```
2019-11-13T18:34:56.0495755Z 
2019-11-13T18:34:56.0495916Z The same applies to transmutes to `*mut fn()`, which were observed in practice.
2019-11-13T18:34:56.0496221Z The intention is typically to describe a function pointer, but just `fn()`
2019-11-13T18:34:56.0496221Z The intention is typically to describe a function pointer, but just `fn()`
2019-11-13T18:34:56.0496365Z alone suffices for that. `*mut fn()` is a pointer to a fn pointer.
2019-11-13T18:34:56.0496519Z (Since these values are typically just passed to C code, however, this rarely
2019-11-13T18:34:56.0496684Z makes a difference in practice.)
2019-11-13T18:34:56.0496808Z 
2019-11-13T18:34:56.0497254Z [rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
2019-11-13T18:34:56.0497858Z ------------------------------------------
2019-11-13T18:34:56.0498049Z stderr:
2019-11-13T18:34:56.0498428Z ------------------------------------------
2019-11-13T18:34:56.0498610Z 
---
2019-11-13T18:34:56.0526384Z thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:537:22
2019-11-13T18:34:56.0526687Z note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
2019-11-13T18:34:56.0545869Z 
2019-11-13T18:34:56.0546189Z 
2019-11-13T18:34:56.0548449Z 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-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -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" "6.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"
2019-11-13T18:34:56.0549043Z 
2019-11-13T18:34:56.0549202Z 
2019-11-13T18:34:56.0566248Z failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
2019-11-13T18:34:56.0566326Z Build completed unsuccessfully in 1:06:32
2019-11-13T18:34:56.0566326Z Build completed unsuccessfully in 1:06:32
2019-11-13T18:34:56.0609039Z == clock drift check ==
2019-11-13T18:34:56.0629062Z   local time: Wed Nov 13 18:34:56 UTC 2019
2019-11-13T18:34:56.3470948Z   network time: Wed, 13 Nov 2019 18:34:56 GMT
2019-11-13T18:34:56.3478598Z == end clock drift check ==
2019-11-13T18:34:57.1459271Z 
2019-11-13T18:34:57.1563377Z ##[error]Bash exited with code '1'.
2019-11-13T18:34:57.1634196Z ##[section]Starting: Checkout
2019-11-13T18:34:57.1636721Z ==============================================================================
2019-11-13T18:34:57.1636803Z Task         : Get sources
2019-11-13T18:34:57.1636857Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

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)

@GuillaumeGomez
Copy link
Member Author

Finally! Let's quickly move this in then!

@bors: r=Centril

@GuillaumeGomez
Copy link
Member Author

Another try...

@bors: r=Centril

@bors
Copy link
Contributor

bors commented Nov 14, 2019

📌 Commit b5b2a89 has been approved by Centril

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 14, 2019
bors added a commit that referenced this pull request Nov 14, 2019
Move error codes

Works towards #66210.

r? @Centril

Oh btw, for the ones interested, I used this python script to get all error codes content sorted into one final file:

<details>

```python
from os import listdir
from os.path import isdir, isfile, join

def get_error_codes(error_codes, f_path):
    with open(f_path) as f:
        short_mode = False
        lines = f.read().split("\n")
        i = 0
        while i < len(lines):
            line = lines[i]
            if not short_mode and line.startswith("E0") and line.endswith(": r##\""):
                error = line
                error += "\n"
                i += 1
                while i < len(lines):
                    line = lines[i]
                    error += line
                    if line.endswith("\"##,"):
                        break
                    error += "\n"
                    i += 1
                error_codes["long"].append(error)
            elif line == ';':
                short_mode = True
            elif short_mode is True and len(line) > 0 and line != "}":
                error_codes["short"].append(line)
                while i + 1 < len(lines):
                    line = lines[i + 1].strip()
                    if not line.startswith("//"):
                        break
                    parts = line.split("//")
                    if len(parts) < 2:
                        break
                    if parts[1].strip().startswith("E0"):
                        break
                    error_codes["short"][-1] += "\n"
                    error_codes["short"][-1] += lines[i + 1]
                    i += 1
            i += 1

def loop_dirs(error_codes, cur_dir):
    for entry in listdir(cur_dir):
        f = join(cur_dir, entry)
        if isfile(f) and entry == "error_codes.rs":
            get_error_codes(error_codes, f)
        elif isdir(f) and not entry.startswith("librustc_error_codes"):
            loop_dirs(error_codes, f)

def get_error_code(err):
    x = err.split(",")
    if len(x) < 2:
        return err
    x = x[0]
    if x.strip().startswith("//"):
        x = x.split("//")[1].strip()
    return x.strip()

def write_into_file(error_codes, f_path):
    with open(f_path, "w") as f:
        f.write("// Error messages for EXXXX errors.  Each message should start and end with a\n")
        f.write("// new line, and be wrapped to 80 characters.  In vim you can `:set tw=80` and\n")
        f.write("// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.\n\n")
        f.write("syntax::register_diagnostics! {\n\n")
        error_codes["long"].sort()
        for i in error_codes["long"]:
            f.write(i)
            f.write("\n\n")
        f.write(";\n")
        error_codes["short"] = sorted(error_codes["short"], key=lambda err: get_error_code(err))
        for i in error_codes["short"]:
            f.write(i)
            f.write("\n")
        f.write("}\n")

error_codes = {
    "long": [],
    "short": []
}
loop_dirs(error_codes, "src")
write_into_file(error_codes, "src/librustc_error_codes/src/error_codes.rs")
```
</details>

And to move the error codes into their own files:

<details>

```python
import os

try:
    os.mkdir("src/librustc_error_codes/error_codes")
except OSError:
    print("Seems like folder already exist, moving on!")
data = ''
with open("src/librustc_error_codes/error_codes.rs") as f:
    x = f.read().split('\n')
    i = 0
    short_part = False
    while i < len(x):
        line = x[i]
        if short_part is False and line.startswith('E0') and line.endswith(': r##"'):
            err_code = line.split(':')[0]
            i += 1
            content = ''
            while i < len(x):
                if x[i] == '"##,':
                    break
                content += x[i]
                content += '\n'
                i += 1
            f_path = "src/librustc_error_codes/error_codes/{}.md".format(err_code)
            with open(f_path, "w") as ff:
                ff.write(content)
            data += '{}: include_str!("./error_codes/{}.md"),'.format(err_code, err_code)
        elif short_part is False and line == ';':
            short_part is True
            data += ';\n'
        else:
            data += line
            data += '\n'
        i += 1
with open("src/librustc_error_codes/error_codes.rs", "w") as f:
    f.write(data)
```
</details>
@bors
Copy link
Contributor

bors commented Nov 14, 2019

⌛ Testing commit b5b2a89 with merge 82cf3a4...

@bors
Copy link
Contributor

bors commented Nov 14, 2019

☀️ Test successful - checks-azure
Approved by: Centril
Pushing 82cf3a4 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 14, 2019
@bors bors merged commit b5b2a89 into rust-lang:master Nov 14, 2019
@GuillaumeGomez GuillaumeGomez deleted the move-error-codes branch November 14, 2019 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants