From fa62a0c4a4f16cc34bea697a58efb3adbed02a4c Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 13 May 2017 17:54:50 +0800 Subject: [PATCH 01/15] Introduce 'run-pass' header to 'ui' tests in compiletest. Fix issue #36516. The 'run-pass' header cause a 'ui' test to execute the result. It is used to test the lint output, at the same time ensure those lints won't cause the source code to become compile-fail. 12 run-pass/run-pass-fulldeps tests gained the header and are moved to ui/ui-fulldeps. After this move, no run-pass/run-pass-fulldeps tests should rely on the compiler's JSON message. This allows us to stop passing `--error-format json` in run-pass tests, thus fixing #36516. --- .../auxiliary/lint_group_plugin_test.rs | 0 .../auxiliary/lint_plugin_test.rs | 0 .../deprecated-derive.rs | 2 + src/test/ui-fulldeps/deprecated-derive.stderr | 6 +++ .../lint-group-plugin.rs | 1 + src/test/ui-fulldeps/lint-group-plugin.stderr | 16 ++++++++ .../lint-plugin-cmdline-allow.rs | 1 + .../lint-plugin-cmdline-allow.stderr | 8 ++++ .../lint-plugin-cmdline-load.rs | 1 + .../lint-plugin-cmdline-load.stderr | 8 ++++ .../lint-plugin.rs | 1 + src/test/ui-fulldeps/lint-plugin.stderr | 8 ++++ .../deprecated-macro_escape-inner.rs | 2 + .../ui/deprecated-macro_escape-inner.stderr | 8 ++++ .../deprecated-macro_escape.rs | 2 + src/test/ui/deprecated-macro_escape.stderr | 6 +++ .../deriving-meta-empty-trait-list.rs | 2 + .../ui/deriving-meta-empty-trait-list.stderr | 12 ++++++ .../{run-pass => ui}/enum-size-variance.rs | 4 +- src/test/ui/enum-size-variance.stderr | 12 ++++++ src/test/{run-pass => ui}/issue-19100.rs | 2 + src/test/ui/issue-19100.stderr | 16 ++++++++ src/test/{run-pass => ui}/path-lookahead.rs | 2 + src/test/ui/path-lookahead.stderr | 28 +++++++++++++ .../test-should-panic-attr.rs | 1 + src/test/ui/test-should-panic-attr.stderr | 40 +++++++++++++++++++ src/tools/compiletest/src/header.rs | 12 ++++++ src/tools/compiletest/src/runtest.rs | 16 ++++++-- 28 files changed, 212 insertions(+), 5 deletions(-) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/lint_group_plugin_test.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/lint_plugin_test.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/deprecated-derive.rs (98%) create mode 100644 src/test/ui-fulldeps/deprecated-derive.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/lint-group-plugin.rs (98%) create mode 100644 src/test/ui-fulldeps/lint-group-plugin.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/lint-plugin-cmdline-allow.rs (98%) create mode 100644 src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/lint-plugin-cmdline-load.rs (98%) create mode 100644 src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/lint-plugin.rs (98%) create mode 100644 src/test/ui-fulldeps/lint-plugin.stderr rename src/test/{run-pass => ui}/deprecated-macro_escape-inner.rs (97%) create mode 100644 src/test/ui/deprecated-macro_escape-inner.stderr rename src/test/{run-pass => ui}/deprecated-macro_escape.rs (97%) create mode 100644 src/test/ui/deprecated-macro_escape.stderr rename src/test/{run-pass => ui}/deriving-meta-empty-trait-list.rs (98%) create mode 100644 src/test/ui/deriving-meta-empty-trait-list.stderr rename src/test/{run-pass => ui}/enum-size-variance.rs (98%) create mode 100644 src/test/ui/enum-size-variance.stderr rename src/test/{run-pass => ui}/issue-19100.rs (98%) create mode 100644 src/test/ui/issue-19100.stderr rename src/test/{run-pass => ui}/path-lookahead.rs (98%) create mode 100644 src/test/ui/path-lookahead.stderr rename src/test/{run-pass => ui}/test-should-panic-attr.rs (98%) create mode 100644 src/test/ui/test-should-panic-attr.stderr diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/lint_group_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs diff --git a/src/test/run-pass-fulldeps/deprecated-derive.rs b/src/test/ui-fulldeps/deprecated-derive.rs similarity index 98% rename from src/test/run-pass-fulldeps/deprecated-derive.rs rename to src/test/ui-fulldeps/deprecated-derive.rs index be2a45ca79abd..a728523d83267 100644 --- a/src/test/run-pass-fulldeps/deprecated-derive.rs +++ b/src/test/ui-fulldeps/deprecated-derive.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + #![feature(rustc_private)] #![allow(dead_code)] diff --git a/src/test/ui-fulldeps/deprecated-derive.stderr b/src/test/ui-fulldeps/deprecated-derive.stderr new file mode 100644 index 0000000000000..3ab7567f8dfb0 --- /dev/null +++ b/src/test/ui-fulldeps/deprecated-derive.stderr @@ -0,0 +1,6 @@ +warning: derive(Encodable) is deprecated in favor of derive(RustcEncodable) + --> $DIR/deprecated-derive.rs:18:10 + | +18 | #[derive(Encodable)] + | ^^^^^^^^^ + diff --git a/src/test/run-pass-fulldeps/lint-group-plugin.rs b/src/test/ui-fulldeps/lint-group-plugin.rs similarity index 98% rename from src/test/run-pass-fulldeps/lint-group-plugin.rs rename to src/test/ui-fulldeps/lint-group-plugin.rs index 978a78cee4f1e..fee9f45972dfc 100644 --- a/src/test/run-pass-fulldeps/lint-group-plugin.rs +++ b/src/test/ui-fulldeps/lint-group-plugin.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // aux-build:lint_group_plugin_test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-group-plugin.stderr b/src/test/ui-fulldeps/lint-group-plugin.stderr new file mode 100644 index 0000000000000..1d68e78de5ed1 --- /dev/null +++ b/src/test/ui-fulldeps/lint-group-plugin.stderr @@ -0,0 +1,16 @@ +warning: item is named 'lintme' + --> $DIR/lint-group-plugin.rs:18:1 + | +18 | fn lintme() { } //~ WARNING item is named 'lintme' + | ^^^^^^^^^^^^^^^ + | + = note: #[warn(test_lint)] on by default + +warning: item is named 'pleaselintme' + --> $DIR/lint-group-plugin.rs:19:1 + | +19 | fn pleaselintme() { } //~ WARNING item is named 'pleaselintme' + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(please_lint)] on by default + diff --git a/src/test/run-pass-fulldeps/lint-plugin-cmdline-allow.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs similarity index 98% rename from src/test/run-pass-fulldeps/lint-plugin-cmdline-allow.rs rename to src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs index 204312064b582..1e428629cc2ff 100644 --- a/src/test/run-pass-fulldeps/lint-plugin-cmdline-allow.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // aux-build:lint_plugin_test.rs // ignore-stage1 // compile-flags: -A test-lint diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr new file mode 100644 index 0000000000000..b8513b95d36c0 --- /dev/null +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr @@ -0,0 +1,8 @@ +warning: function is never used: `lintme` + --> $DIR/lint-plugin-cmdline-allow.rs:19:1 + | +19 | fn lintme() { } + | ^^^^^^^^^^^^^^^ + | + = note: #[warn(dead_code)] on by default + diff --git a/src/test/run-pass-fulldeps/lint-plugin-cmdline-load.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs similarity index 98% rename from src/test/run-pass-fulldeps/lint-plugin-cmdline-load.rs rename to src/test/ui-fulldeps/lint-plugin-cmdline-load.rs index 2e86e11bd6a5f..27ef9649cf34f 100644 --- a/src/test/run-pass-fulldeps/lint-plugin-cmdline-load.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // aux-build:lint_plugin_test.rs // ignore-stage1 // compile-flags: -Z extra-plugins=lint_plugin_test diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr new file mode 100644 index 0000000000000..42ececc93bd79 --- /dev/null +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr @@ -0,0 +1,8 @@ +warning: item is named 'lintme' + --> $DIR/lint-plugin-cmdline-load.rs:18:1 + | +18 | fn lintme() { } //~ WARNING item is named 'lintme' + | ^^^^^^^^^^^^^^^ + | + = note: #[warn(test_lint)] on by default + diff --git a/src/test/run-pass-fulldeps/lint-plugin.rs b/src/test/ui-fulldeps/lint-plugin.rs similarity index 98% rename from src/test/run-pass-fulldeps/lint-plugin.rs rename to src/test/ui-fulldeps/lint-plugin.rs index 753ad33bd01e9..304cfc3eb6d1d 100644 --- a/src/test/run-pass-fulldeps/lint-plugin.rs +++ b/src/test/ui-fulldeps/lint-plugin.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // aux-build:lint_plugin_test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin.stderr b/src/test/ui-fulldeps/lint-plugin.stderr new file mode 100644 index 0000000000000..1fe821d31159c --- /dev/null +++ b/src/test/ui-fulldeps/lint-plugin.stderr @@ -0,0 +1,8 @@ +warning: item is named 'lintme' + --> $DIR/lint-plugin.rs:18:1 + | +18 | fn lintme() { } //~ WARNING item is named 'lintme' + | ^^^^^^^^^^^^^^^ + | + = note: #[warn(test_lint)] on by default + diff --git a/src/test/run-pass/deprecated-macro_escape-inner.rs b/src/test/ui/deprecated-macro_escape-inner.rs similarity index 97% rename from src/test/run-pass/deprecated-macro_escape-inner.rs rename to src/test/ui/deprecated-macro_escape-inner.rs index 1a2be7a719e17..3d253ba49dad9 100644 --- a/src/test/run-pass/deprecated-macro_escape-inner.rs +++ b/src/test/ui/deprecated-macro_escape-inner.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + mod foo { #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use //~^ HELP consider an outer attribute diff --git a/src/test/ui/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecated-macro_escape-inner.stderr new file mode 100644 index 0000000000000..c91db6c3365a4 --- /dev/null +++ b/src/test/ui/deprecated-macro_escape-inner.stderr @@ -0,0 +1,8 @@ +warning: macro_escape is a deprecated synonym for macro_use + --> $DIR/deprecated-macro_escape-inner.rs:14:5 + | +14 | #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use + | ^^^^^^^^^^^^^^^^ + | + = help: consider an outer attribute, #[macro_use] mod ... + diff --git a/src/test/run-pass/deprecated-macro_escape.rs b/src/test/ui/deprecated-macro_escape.rs similarity index 97% rename from src/test/run-pass/deprecated-macro_escape.rs rename to src/test/ui/deprecated-macro_escape.rs index b9f756cc79c8f..a234572343c15 100644 --- a/src/test/run-pass/deprecated-macro_escape.rs +++ b/src/test/ui/deprecated-macro_escape.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + #[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use mod foo { } diff --git a/src/test/ui/deprecated-macro_escape.stderr b/src/test/ui/deprecated-macro_escape.stderr new file mode 100644 index 0000000000000..aa77129528165 --- /dev/null +++ b/src/test/ui/deprecated-macro_escape.stderr @@ -0,0 +1,6 @@ +warning: macro_escape is a deprecated synonym for macro_use + --> $DIR/deprecated-macro_escape.rs:13:1 + | +13 | #[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use + | ^^^^^^^^^^^^^^^ + diff --git a/src/test/run-pass/deriving-meta-empty-trait-list.rs b/src/test/ui/deriving-meta-empty-trait-list.rs similarity index 98% rename from src/test/run-pass/deriving-meta-empty-trait-list.rs rename to src/test/ui/deriving-meta-empty-trait-list.rs index ed8a50998daee..cf4dfb947f419 100644 --- a/src/test/run-pass/deriving-meta-empty-trait-list.rs +++ b/src/test/ui/deriving-meta-empty-trait-list.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + #![allow(dead_code)] #[derive] //~ WARNING empty trait list in `derive` diff --git a/src/test/ui/deriving-meta-empty-trait-list.stderr b/src/test/ui/deriving-meta-empty-trait-list.stderr new file mode 100644 index 0000000000000..58f871413f106 --- /dev/null +++ b/src/test/ui/deriving-meta-empty-trait-list.stderr @@ -0,0 +1,12 @@ +warning: empty trait list in `derive` + --> $DIR/deriving-meta-empty-trait-list.rs:15:1 + | +15 | #[derive] //~ WARNING empty trait list in `derive` + | ^^^^^^^^^ + +warning: empty trait list in `derive` + --> $DIR/deriving-meta-empty-trait-list.rs:18:1 + | +18 | #[derive()] //~ WARNING empty trait list in `derive` + | ^^^^^^^^^^^ + diff --git a/src/test/run-pass/enum-size-variance.rs b/src/test/ui/enum-size-variance.rs similarity index 98% rename from src/test/run-pass/enum-size-variance.rs rename to src/test/ui/enum-size-variance.rs index a3e95a153418d..9f64761eed3be 100644 --- a/src/test/run-pass/enum-size-variance.rs +++ b/src/test/ui/enum-size-variance.rs @@ -7,7 +7,9 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// + +// run-pass + #![warn(variant_size_differences)] #![allow(dead_code)] diff --git a/src/test/ui/enum-size-variance.stderr b/src/test/ui/enum-size-variance.stderr new file mode 100644 index 0000000000000..e7e3f2609fa89 --- /dev/null +++ b/src/test/ui/enum-size-variance.stderr @@ -0,0 +1,12 @@ +warning: enum variant is more than three times larger (32 bytes) than the next largest + --> $DIR/enum-size-variance.rs:28:5 + | +28 | L(isize, isize, isize, isize), //~ WARNING three times larger + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/enum-size-variance.rs:13:9 + | +13 | #![warn(variant_size_differences)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/run-pass/issue-19100.rs b/src/test/ui/issue-19100.rs similarity index 98% rename from src/test/run-pass/issue-19100.rs rename to src/test/ui/issue-19100.rs index 7ff9ae996f525..bcadd94eb6fba 100644 --- a/src/test/run-pass/issue-19100.rs +++ b/src/test/ui/issue-19100.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + #![allow(non_snake_case)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/issue-19100.stderr b/src/test/ui/issue-19100.stderr new file mode 100644 index 0000000000000..45e2ef652d5a3 --- /dev/null +++ b/src/test/ui/issue-19100.stderr @@ -0,0 +1,16 @@ +warning[E0170]: pattern binding `Bar` is named the same as one of the variants of the type `Foo` + --> $DIR/issue-19100.rs:27:1 + | +27 | Bar if true + | ^^^ + | + = help: if you meant to match on a variant, consider making the path in the pattern qualified: `Foo::Bar` + +warning[E0170]: pattern binding `Baz` is named the same as one of the variants of the type `Foo` + --> $DIR/issue-19100.rs:32:1 + | +32 | Baz if false + | ^^^ + | + = help: if you meant to match on a variant, consider making the path in the pattern qualified: `Foo::Baz` + diff --git a/src/test/run-pass/path-lookahead.rs b/src/test/ui/path-lookahead.rs similarity index 98% rename from src/test/run-pass/path-lookahead.rs rename to src/test/ui/path-lookahead.rs index 5c195c8a4c63a..c43f2229cdc33 100644 --- a/src/test/run-pass/path-lookahead.rs +++ b/src/test/ui/path-lookahead.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass + // Parser test for #37765 fn with_parens(arg: T) -> String { //~WARN function is never used: `with_parens` diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr new file mode 100644 index 0000000000000..1e19977e84a3d --- /dev/null +++ b/src/test/ui/path-lookahead.stderr @@ -0,0 +1,28 @@ +warning: unnecessary parentheses around `return` value + --> $DIR/path-lookahead.rs:16:10 + | +16 | return (::to_string(&arg)); //~WARN unnecessary parentheses around `return` value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(unused_parens)] on by default + +warning: function is never used: `with_parens` + --> $DIR/path-lookahead.rs:15:1 + | +15 | / fn with_parens(arg: T) -> String { //~WARN function is never used: `with_parens` +16 | | return (::to_string(&arg)); //~WARN unnecessary parentheses around `return` value +17 | | } + | |_^ + | + = note: #[warn(dead_code)] on by default + +warning: function is never used: `no_parens` + --> $DIR/path-lookahead.rs:19:1 + | +19 | / fn no_parens(arg: T) -> String { //~WARN function is never used: `no_parens` +20 | | return ::to_string(&arg); +21 | | } + | |_^ + | + = note: #[warn(dead_code)] on by default + diff --git a/src/test/run-pass/test-should-panic-attr.rs b/src/test/ui/test-should-panic-attr.rs similarity index 98% rename from src/test/run-pass/test-should-panic-attr.rs rename to src/test/ui/test-should-panic-attr.rs index 2d068872a4d3d..8986732a2694d 100644 --- a/src/test/run-pass/test-should-panic-attr.rs +++ b/src/test/ui/test-should-panic-attr.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // compile-flags: --test #[test] diff --git a/src/test/ui/test-should-panic-attr.stderr b/src/test/ui/test-should-panic-attr.stderr new file mode 100644 index 0000000000000..6f143b6cbeeba --- /dev/null +++ b/src/test/ui/test-should-panic-attr.stderr @@ -0,0 +1,40 @@ +warning: attribute must be of the form: `#[should_panic]` or `#[should_panic(expected = "error message")]` + --> $DIR/test-should-panic-attr.rs:15:1 + | +15 | #[should_panic = "foo"] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + +warning: argument must be of the form: `expected = "error message"` + --> $DIR/test-should-panic-attr.rs:22:1 + | +22 | #[should_panic(expected)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + +warning: argument must be of the form: `expected = "error message"` + --> $DIR/test-should-panic-attr.rs:29:1 + | +29 | #[should_panic(expect)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + +warning: argument must be of the form: `expected = "error message"` + --> $DIR/test-should-panic-attr.rs:36:1 + | +36 | #[should_panic(expected(foo, bar))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + +warning: argument must be of the form: `expected = "error message"` + --> $DIR/test-should-panic-attr.rs:43:1 + | +43 | #[should_panic(expected = "foo", bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 0f653dfbcf07c..e0999ae7793f5 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -233,6 +233,9 @@ pub struct TestProps { pub must_compile_successfully: bool, // rustdoc will test the output of the `--test` option pub check_test_line_numbers_match: bool, + // The test must be compiled and run successfully. Only used in UI tests for + // now. + pub run_pass: bool, } impl TestProps { @@ -258,6 +261,7 @@ impl TestProps { incremental_dir: None, must_compile_successfully: false, check_test_line_numbers_match: false, + run_pass: false, } } @@ -368,6 +372,10 @@ impl TestProps { if !self.check_test_line_numbers_match { self.check_test_line_numbers_match = config.parse_check_test_line_numbers_match(ln); } + + if !self.run_pass { + self.run_pass = config.parse_run_pass(ln); + } }); for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] { @@ -485,6 +493,10 @@ impl Config { self.parse_name_directive(line, "check-test-line-numbers-match") } + fn parse_run_pass(&self, line: &str) -> bool { + self.parse_name_directive(line, "run-pass") + } + fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> { self.parse_name_value_directive(line, name).map(|nv| { // nv is either FOO or FOO=BAR diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1bec6f6af8381..01419c4257074 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -214,10 +214,10 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec("compilation failed!", &proc_res); } + // FIXME(#41968): Move this check to tidy? let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); - if !expected_errors.is_empty() { - self.check_expected_errors(expected_errors, &proc_res); - } + assert!(expected_errors.is_empty(), + "run-pass tests with expected warnings should be moved to ui/"); let proc_res = self.exec_compiled_test(); @@ -1394,7 +1394,6 @@ actual:\n\ match self.config.mode { CompileFail | ParseFail | - RunPass | Incremental => { // If we are extracting and matching errors in the new // fashion, then you want JSON mode. Old-skool error @@ -1422,6 +1421,7 @@ actual:\n\ args.push(dir_opt); } + RunPass | RunFail | RunPassValgrind | Pretty | @@ -2254,6 +2254,14 @@ actual:\n\ self.fatal_proc_rec(&format!("{} errors occurred comparing output.", errors), &proc_res); } + + if self.props.run_pass { + let proc_res = self.exec_compiled_test(); + + if !proc_res.status.success() { + self.fatal_proc_rec("test run failed!", &proc_res); + } + } } fn run_mir_opt_test(&self) { From 15edf4f70b07ea3cf9b1f662019e5d1da785016d Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 24 May 2017 16:11:32 +0800 Subject: [PATCH 02/15] compiletest: Force directive to be first complete word in header comment. Refactored some related code to take advantage of this change. --- src/test/codegen/fastcall-inreg.rs | 2 +- src/test/run-pass/i128-ffi.rs | 3 +- src/tools/compiletest/src/header.rs | 59 +++++++++++++++-------------- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs index 1cbde9b1a7c77..f02e7e9f0ddcf 100644 --- a/src/test/codegen/fastcall-inreg.rs +++ b/src/test/codegen/fastcall-inreg.rs @@ -37,7 +37,7 @@ // ignore-tce // ignore-thumb // ignore-thumbeb -// ignore-x86_64 no-ignore-x86 +// ignore-x86_64 // ignore-xcore // ignore-nvptx // ignore-nvptx64 diff --git a/src/test/run-pass/i128-ffi.rs b/src/test/run-pass/i128-ffi.rs index 473f1cc2301dc..d07fb7b4a7143 100644 --- a/src/test/run-pass/i128-ffi.rs +++ b/src/test/run-pass/i128-ffi.rs @@ -15,7 +15,8 @@ // ignore-windows // Ignore 32 bit targets: -// ignore-x86, ignore-arm +// ignore-x86 +// ignore-arm // ignore-emscripten diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index e0999ae7793f5..c503ca7d8cd14 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -80,13 +80,12 @@ impl EarlyProps { return false; } - if !line.contains("ignore-gdb-version") && - config.parse_name_directive(line, "ignore-gdb") { + if config.parse_name_directive(line, "ignore-gdb") { return true; } if let Some(actual_version) = config.gdb_version { - if line.contains("min-gdb-version") { + if line.starts_with("min-gdb-version") { let (start_ver, end_ver) = extract_gdb_version_range(line); if start_ver != end_ver { @@ -95,7 +94,7 @@ impl EarlyProps { // Ignore if actual version is smaller the minimum required // version actual_version < start_ver - } else if line.contains("ignore-gdb-version") { + } else if line.starts_with("ignore-gdb-version") { let (min_version, max_version) = extract_gdb_version_range(line); if max_version < min_version { @@ -119,20 +118,21 @@ impl EarlyProps { fn extract_gdb_version_range(line: &str) -> (u32, u32) { const ERROR_MESSAGE: &'static str = "Malformed GDB version directive"; - let range_components = line.split(' ') - .flat_map(|word| word.split('-')) - .filter(|word| word.len() > 0) - .skip_while(|word| extract_gdb_version(word).is_none()) - .collect::>(); + let range_components = line.split(&[' ', '-'][..]) + .filter(|word| !word.is_empty()) + .map(extract_gdb_version) + .skip_while(Option::is_none) + .take(3) // 3 or more = invalid, so take at most 3. + .collect::>>(); match range_components.len() { 1 => { - let v = extract_gdb_version(range_components[0]).unwrap(); + let v = range_components[0].unwrap(); (v, v) } 2 => { - let v_min = extract_gdb_version(range_components[0]).unwrap(); - let v_max = extract_gdb_version(range_components[1]).expect(ERROR_MESSAGE); + let v_min = range_components[0].unwrap(); + let v_max = range_components[1].expect(ERROR_MESSAGE); (v_min, v_max) } _ => panic!(ERROR_MESSAGE), @@ -149,10 +149,10 @@ impl EarlyProps { } if let Some(ref actual_version) = config.lldb_version { - if line.contains("min-lldb-version") { - let min_version = line.trim() - .split(' ') - .last() + if line.starts_with("min-lldb-version") { + let min_version = line.trim_right() + .rsplit(' ') + .next() .expect("Malformed lldb version directive"); // Ignore if actual version is smaller the minimum required // version @@ -167,10 +167,10 @@ impl EarlyProps { fn ignore_llvm(config: &Config, line: &str) -> bool { if let Some(ref actual_version) = config.llvm_version { - if line.contains("min-llvm-version") { - let min_version = line.trim() - .split(' ') - .last() + if line.starts_with("min-llvm-version") { + let min_version = line.trim_right() + .rsplit(' ') + .next() .expect("Malformed llvm version directive"); // Ignore if actual version is smaller the minimum required // version @@ -413,14 +413,14 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) { None => false, }; if matches { - it(&ln[close_brace + 1..]); + it(ln[(close_brace + 1) ..].trim_left()); } } else { panic!("malformed condition directive: expected `//[foo]`, found `{}`", ln) } } else if ln.starts_with("//") { - it(&ln[2..]); + it(ln[2..].trim_left()); } } return; @@ -528,15 +528,18 @@ impl Config { } fn parse_name_directive(&self, line: &str, directive: &str) -> bool { - // This 'no-' rule is a quick hack to allow pretty-expanded and - // no-pretty-expanded to coexist - line.contains(directive) && !line.contains(&("no-".to_owned() + directive)) + // Ensure the directive is a whole word. Do not match "ignore-x86" when + // the line says "ignore-x86_64". + line.starts_with(directive) && match line.as_bytes().get(directive.len()) { + None | Some(&b' ') | Some(&b':') => true, + _ => false + } } pub fn parse_name_value_directive(&self, line: &str, directive: &str) -> Option { - let keycolon = format!("{}:", directive); - if let Some(colon) = line.find(&keycolon) { - let value = line[(colon + keycolon.len())..line.len()].to_owned(); + let colon = directive.len(); + if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') { + let value = line[(colon + 1) ..].to_owned(); debug!("{}: {}", directive, value); Some(expand_variables(value, self)) } else { From ecde1e1d3b077f22f75ad34e12e35eef0b6c85f3 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 7 May 2017 00:14:04 -0700 Subject: [PATCH 03/15] Lower `?` to `Try` instead of `Carrier` The easy parts of RFC 1859. (Just the trait and the lowering, none of the error message improvements nor the insta-stable impl for Option.) --- src/doc/unstable-book/src/SUMMARY.md | 1 + .../library-features/question-mark-carrier.md | 6 ++ .../src/library-features/try-trait.md | 7 ++ src/libcore/ops.rs | 65 ++++++++++++++----- src/libcore/result.rs | 19 ++++++ src/librustc/hir/lowering.rs | 12 ++-- src/test/run-pass/try-operator-custom.rs | 18 +++-- 7 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/try-trait.md diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 456a683dc33c8..7684f89960cd5 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -208,6 +208,7 @@ - [toowned_clone_into](library-features/toowned-clone-into.md) - [trusted_len](library-features/trusted-len.md) - [try_from](library-features/try-from.md) + - [try_trait](library-features/try-trait.md) - [unicode](library-features/unicode.md) - [unique](library-features/unique.md) - [unsize](library-features/unsize.md) diff --git a/src/doc/unstable-book/src/library-features/question-mark-carrier.md b/src/doc/unstable-book/src/library-features/question-mark-carrier.md index 56154acc02bbf..a5e6965faec42 100644 --- a/src/doc/unstable-book/src/library-features/question-mark-carrier.md +++ b/src/doc/unstable-book/src/library-features/question-mark-carrier.md @@ -5,3 +5,9 @@ The tracking issue for this feature is: [#31436] [#31436]: https://github.com/rust-lang/rust/issues/31436 ------------------------ + +This feature has been superseded by [`try_trait`][try_trait]. + +It exists only in stage0 for bootstrapping. + +[try_trait]: library-features/try-trait.html diff --git a/src/doc/unstable-book/src/library-features/try-trait.md b/src/doc/unstable-book/src/library-features/try-trait.md new file mode 100644 index 0000000000000..f08929d4e3c2a --- /dev/null +++ b/src/doc/unstable-book/src/library-features/try-trait.md @@ -0,0 +1,7 @@ +# `try_trait` + +The tracking issue for this feature is: [#31436] + +[#31436]: https://github.com/rust-lang/rust/issues/31436 + +------------------------ diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index c76cff4dc34d1..912f3d4ff07d0 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -2918,15 +2918,9 @@ pub trait BoxPlace : Place { fn make_place() -> Self; } -/// A trait for types which have success and error states and are meant to work -/// with the question mark operator. -/// When the `?` operator is used with a value, whether the value is in the -/// success or error state is determined by calling `translate`. -/// -/// This trait is **very** experimental, it will probably be iterated on heavily -/// before it is stabilised. Implementors should expect change. Users of `?` -/// should not rely on any implementations of `Carrier` other than `Result`, -/// i.e., you should not expect `?` to continue to work with `Option`, etc. +/// This trait has been superseded by the `Try` trait, but must remain +/// here as `?` is still lowered to it in stage0 . +#[cfg(stage0)] #[unstable(feature = "question_mark_carrier", issue = "31436")] pub trait Carrier { /// The type of the value when computation succeeds. @@ -2945,6 +2939,7 @@ pub trait Carrier { fn translate(self) -> T where T: Carrier; } +#[cfg(stage0)] #[unstable(feature = "question_mark_carrier", issue = "31436")] impl Carrier for Result { type Success = U; @@ -2970,21 +2965,57 @@ impl Carrier for Result { struct _DummyErrorType; -impl Carrier for _DummyErrorType { - type Success = (); +impl Try for _DummyErrorType { + type Ok = (); type Error = (); - fn from_success(_: ()) -> _DummyErrorType { + fn into_result(self) -> Result { + Ok(()) + } + + fn from_ok(_: ()) -> _DummyErrorType { _DummyErrorType } fn from_error(_: ()) -> _DummyErrorType { _DummyErrorType } +} - fn translate(self) -> T - where T: Carrier - { - T::from_success(()) - } +/// A trait for customizing the behaviour of the `?` operator. +/// +/// A type implementing `Try` is one that has a canonical way to view it +/// in terms of a success/failure dichotomy. This trait allows both +/// extracting those success or failure values from an existing instance and +/// creating a new instance from a success or failure value. +#[unstable(feature = "try_trait", issue = "31436")] +pub trait Try { + /// The type of this value when viewed as successful. + #[unstable(feature = "try_trait", issue = "31436")] + type Ok; + /// The type of this value when viewed as failed. + #[unstable(feature = "try_trait", issue = "31436")] + type Error; + + /// Applies the "?" operator. A return of `Ok(t)` means that the + /// execution should continue normally, and the result of `?` is the + /// value `t`. A return of `Err(e)` means that execution should branch + /// to the innermost enclosing `catch`, or return from the function. + /// + /// If an `Err(e)` result is returned, the value `e` will be "wrapped" + /// in the return type of the enclosing scope (which must itself implement + /// `Try`). Specifically, the value `X::from_error(From::from(e))` + /// is returned, where `X` is the return type of the enclosing function. + #[unstable(feature = "try_trait", issue = "31436")] + fn into_result(self) -> Result; + + /// Wrap an error value to construct the composite result. For example, + /// `Result::Err(x)` and `Result::from_error(x)` are equivalent. + #[unstable(feature = "try_trait", issue = "31436")] + fn from_error(v: Self::Error) -> Self; + + /// Wrap an OK value to construct the composite result. For example, + /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent. + #[unstable(feature = "try_trait", issue = "31436")] + fn from_ok(v: Self::Ok) -> Self; } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index c46b0c1324de6..a02c19f5f38b5 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -242,6 +242,7 @@ use fmt; use iter::{FromIterator, FusedIterator, TrustedLen}; +use ops; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). /// @@ -1108,3 +1109,21 @@ impl> FromIterator> for Result { } } } + +#[unstable(feature = "try_trait", issue = "31436")] +impl ops::Try for Result { + type Ok = T; + type Error = E; + + fn into_result(self) -> Self { + self + } + + fn from_ok(v: T) -> Self { + Ok(v) + } + + fn from_error(v: E) -> Self { + Err(v) + } +} \ No newline at end of file diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d359c69d3a092..68cee5b93fea8 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2244,23 +2244,23 @@ impl<'a> LoweringContext<'a> { ExprKind::Try(ref sub_expr) => { // to: // - // match Carrier::translate() { + // match Try::into_result() { // Ok(val) => #[allow(unreachable_code)] val, // Err(err) => #[allow(unreachable_code)] // // If there is an enclosing `catch {...}` - // break 'catch_target Carrier::from_error(From::from(err)), + // break 'catch_target Try::from_error(From::from(err)), // // Otherwise - // return Carrier::from_error(From::from(err)), + // return Try::from_error(From::from(err)), // } let unstable_span = self.allow_internal_unstable("?", e.span); - // Carrier::translate() + // Try::into_result() let discr = { // expand let sub_expr = self.lower_expr(sub_expr); - let path = &["ops", "Carrier", "translate"]; + let path = &["ops", "Try", "into_result"]; let path = P(self.expr_std_path(unstable_span, path, ThinVec::new())); P(self.expr_call(e.span, path, hir_vec![sub_expr])) }; @@ -2306,7 +2306,7 @@ impl<'a> LoweringContext<'a> { self.expr_call(e.span, from, hir_vec![err_expr]) }; let from_err_expr = { - let path = &["ops", "Carrier", "from_error"]; + let path = &["ops", "Try", "from_error"]; let from_err = P(self.expr_std_path(unstable_span, path, ThinVec::new())); P(self.expr_call(e.span, from_err, hir_vec![from_expr])) diff --git a/src/test/run-pass/try-operator-custom.rs b/src/test/run-pass/try-operator-custom.rs index 577d19a58960d..82ba70c945944 100644 --- a/src/test/run-pass/try-operator-custom.rs +++ b/src/test/run-pass/try-operator-custom.rs @@ -8,20 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(question_mark, question_mark_carrier)] +#![feature(try_trait)] -use std::ops::Carrier; +use std::ops::Try; enum MyResult { Awesome(T), Terrible(U) } -impl Carrier for MyResult { - type Success = U; +impl Try for MyResult { + type Ok = U; type Error = V; - fn from_success(u: U) -> MyResult { + fn from_ok(u: U) -> MyResult { MyResult::Awesome(u) } @@ -29,12 +29,10 @@ impl Carrier for MyResult { MyResult::Terrible(e) } - fn translate(self) -> T - where T: Carrier - { + fn into_result(self) -> Result { match self { - MyResult::Awesome(u) => T::from_success(u), - MyResult::Terrible(e) => T::from_error(e), + MyResult::Awesome(u) => Ok(u), + MyResult::Terrible(e) => Err(e), } } } From eeebfd667bd1524476229ecb910f9751405e85c7 Mon Sep 17 00:00:00 2001 From: Edward Yang Date: Mon, 29 May 2017 21:31:33 -0500 Subject: [PATCH 04/15] Add RLS to .exe and .msi installers --- src/bootstrap/dist.rs | 36 ++++++++++++++++++++++++++++++++++ src/etc/installer/exe/rust.iss | 3 +++ src/etc/installer/msi/rust.wxs | 10 ++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c50165c5e3904..8a8e5539ef05d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -949,6 +949,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { let _ = fs::remove_dir_all(&exe); t!(fs::create_dir_all(exe.join("rustc"))); t!(fs::create_dir_all(exe.join("cargo"))); + t!(fs::create_dir_all(exe.join("rls"))); + t!(fs::create_dir_all(exe.join("rust-analysis"))); t!(fs::create_dir_all(exe.join("rust-docs"))); t!(fs::create_dir_all(exe.join("rust-std"))); cp_r(&work.join(&format!("{}-{}", pkgname(build, "rustc"), target)) @@ -963,11 +965,19 @@ pub fn extended(build: &Build, stage: u32, target: &str) { cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-std"), target)) .join(format!("rust-std-{}", target)), &exe.join("rust-std")); + cp_r(&work.join(&format!("{}-{}", pkgname(build, "rls"), target)) + .join("rls"), + &exe.join("rls")); + cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-analysis"), target)) + .join(format!("rust-analysis-{}", target)), + &exe.join("rust-analysis")); t!(fs::remove_file(exe.join("rustc/manifest.in"))); t!(fs::remove_file(exe.join("cargo/manifest.in"))); t!(fs::remove_file(exe.join("rust-docs/manifest.in"))); t!(fs::remove_file(exe.join("rust-std/manifest.in"))); + t!(fs::remove_file(exe.join("rls/manifest.in"))); + t!(fs::remove_file(exe.join("rust-analysis/manifest.in"))); if target.contains("windows-gnu") { t!(fs::create_dir_all(exe.join("rust-mingw"))); @@ -1041,6 +1051,26 @@ pub fn extended(build: &Build, stage: u32, target: &str) { .arg("-dr").arg("Std") .arg("-var").arg("var.StdDir") .arg("-out").arg(exe.join("StdGroup.wxs"))); + build.run(Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rls") + .args(&heat_flags) + .arg("-cg").arg("RlsGroup") + .arg("-dr").arg("Rls") + .arg("-var").arg("var.RlsDir") + .arg("-out").arg(exe.join("RlsGroup.wxs")) + .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); + build.run(Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-analysis") + .args(&heat_flags) + .arg("-cg").arg("AnalysisGroup") + .arg("-dr").arg("Analysis") + .arg("-var").arg("var.AnalysisDir") + .arg("-out").arg(exe.join("AnalysisGroup.wxs")) + .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); if target.contains("windows-gnu") { build.run(Command::new(&heat) .current_dir(&exe) @@ -1064,6 +1094,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { .arg("-dDocsDir=rust-docs") .arg("-dCargoDir=cargo") .arg("-dStdDir=rust-std") + .arg("-dRlsDir=rls") + .arg("-dAnalysisDir=rust-analysis") .arg("-arch").arg(&arch) .arg("-out").arg(&output) .arg(&input); @@ -1081,6 +1113,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { candle("DocsGroup.wxs".as_ref()); candle("CargoGroup.wxs".as_ref()); candle("StdGroup.wxs".as_ref()); + candle("RlsGroup.wxs".as_ref()); + candle("AnalysisGroup.wxs".as_ref()); if target.contains("windows-gnu") { candle("GccGroup.wxs".as_ref()); @@ -1103,6 +1137,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { .arg("DocsGroup.wixobj") .arg("CargoGroup.wixobj") .arg("StdGroup.wixobj") + .arg("RlsGroup.wixobj") + .arg("AnalysisGroup.wixobj") .current_dir(&exe); if target.contains("windows-gnu") { diff --git a/src/etc/installer/exe/rust.iss b/src/etc/installer/exe/rust.iss index a61a19f909af3..e7d4ec6194686 100644 --- a/src/etc/installer/exe/rust.iss +++ b/src/etc/installer/exe/rust.iss @@ -46,6 +46,7 @@ Name: gcc; Description: "Linker and platform libraries"; Types: full Name: docs; Description: "HTML documentation"; Types: full Name: cargo; Description: "Cargo, the Rust package manager"; Types: full Name: std; Description: "The Rust Standard Library"; Types: full +Name: rls; Description: "RLS, the Rust Language Server" [Files] Source: "rustc/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: rust @@ -55,6 +56,8 @@ Source: "rust-mingw/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Source: "rust-docs/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: docs Source: "cargo/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: cargo Source: "rust-std/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: std +Source: "rls/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: rls +Source: "rust-analysis/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: rls [Code] const diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs index fb076ccb09180..258291cbb72e1 100644 --- a/src/etc/installer/msi/rust.wxs +++ b/src/etc/installer/msi/rust.wxs @@ -170,6 +170,8 @@ + + @@ -273,6 +275,14 @@ + + + + From 7c362732dc49d7ab6d3fcf973922337dae53dd5c Mon Sep 17 00:00:00 2001 From: Edward Yang Date: Mon, 29 May 2017 21:44:09 -0500 Subject: [PATCH 05/15] Add RLS to .pkg installer --- src/bootstrap/dist.rs | 10 ++++++++++ src/etc/installer/pkg/Distribution.xml | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 8a8e5539ef05d..14f467ecc5511 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -899,6 +899,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { t!(fs::create_dir_all(pkg.join("cargo"))); t!(fs::create_dir_all(pkg.join("rust-docs"))); t!(fs::create_dir_all(pkg.join("rust-std"))); + t!(fs::create_dir_all(pkg.join("rls"))); + t!(fs::create_dir_all(pkg.join("rust-analysis"))); cp_r(&work.join(&format!("{}-{}", pkgname(build, "rustc"), target)), &pkg.join("rustc")); @@ -908,11 +910,17 @@ pub fn extended(build: &Build, stage: u32, target: &str) { &pkg.join("rust-docs")); cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-std"), target)), &pkg.join("rust-std")); + cp_r(&work.join(&format!("{}-{}", pkgname(build, "rls"), target)), + &pkg.join("rls")); + cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-analysis"), target)), + &pkg.join("rust-analysis")); install(&etc.join("pkg/postinstall"), &pkg.join("rustc"), 0o755); install(&etc.join("pkg/postinstall"), &pkg.join("cargo"), 0o755); install(&etc.join("pkg/postinstall"), &pkg.join("rust-docs"), 0o755); install(&etc.join("pkg/postinstall"), &pkg.join("rust-std"), 0o755); + install(&etc.join("pkg/postinstall"), &pkg.join("rls"), 0o755); + install(&etc.join("pkg/postinstall"), &pkg.join("rust-analysis"), 0o755); let pkgbuild = |component: &str| { let mut cmd = Command::new("pkgbuild"); @@ -926,6 +934,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { pkgbuild("cargo"); pkgbuild("rust-docs"); pkgbuild("rust-std"); + pkgbuild("rls"); + pkgbuild("rust-analysis"); // create an 'uninstall' package install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755); diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml index 79f99818ba3f9..fd09f7b0a67d3 100644 --- a/src/etc/installer/pkg/Distribution.xml +++ b/src/etc/installer/pkg/Distribution.xml @@ -16,6 +16,7 @@ + @@ -61,10 +62,20 @@ > + + + + rustc.pkg cargo.pkg rust-docs.pkg rust-std.pkg + rls.pkg + rust-analysis.pkg uninstall.pkg From f3b29d3f010e9895e711767eb9eeba7f5de9ba50 Mon Sep 17 00:00:00 2001 From: Edward Yang Date: Mon, 29 May 2017 21:55:35 -0500 Subject: [PATCH 06/15] Fix formatting issues in Distribution.xml --- src/etc/installer/pkg/Distribution.xml | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml index fd09f7b0a67d3..f138a1a315489 100644 --- a/src/etc/installer/pkg/Distribution.xml +++ b/src/etc/installer/pkg/Distribution.xml @@ -12,61 +12,61 @@ - - - - - + + + + + + title="Install Rust" description="Install the Rust compiler, package manager and documentation." + customLocation="/usr/local" + selected="!choices.uninstall.selected" + /> - + title="Uninstall Rust" description="Select this option to uninstall an existing Rust installation." + customLocation="/usr/local" + selected="!(choices.install.selected || choices.rustc.selected || choices.cargo.selected || choices['rust-docs'].selected)" + start_selected="false" + > + + title="Compiler" description="rustc, the Rust compiler, and rustdoc, the API documentation tool." + selected="(!choices.uninstall.selected && choices.rustc.selected) || (choices.uninstall.selected && choices.install.selected)" + > + title="Cargo" description="cargo, the Rust package manager." + selected="(!choices.uninstall.selected && choices.cargo.selected) || (choices.uninstall.selected && choices.install.selected)" + > + title="Standard Library" description="The Rust standard library." + selected="(!choices.uninstall.selected && choices['rust-std'].selected) || (choices.uninstall.selected && choices.install.selected)" + > + title="Documentation" description="HTML documentation." + selected="(!choices.uninstall.selected && choices['rust-docs'].selected) || (choices.uninstall.selected && choices.install.selected)" + > + > From 4450807ead1c5f9a5f8d44ffee6ed0f968c68c34 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Tue, 30 May 2017 17:50:44 +0200 Subject: [PATCH 07/15] ARMv5 needs +strict-align Without that flag, LLVM generates unaligned memory access instructions, which are not allowed on ARMv5. For example, the 'hello world' example from `cargo --new` failed with: ``` $ ./hello Hello, world! thread 'main' panicked at 'assertion failed: end <= len', src/libcollections/vec.rs:1113 note: Run with `RUST_BACKTRACE=1` for a backtrace. ``` I traced this error back to the following assembler code in `BufWriter::flush_buf`: ``` 6f44: e28d0018 add r0, sp, #24 [...] 6f54: e280b005 add fp, r0, #5 [...] 7018: e5cd001c strb r0, [sp, #28] 701c: e1a0082a lsr r0, sl, #16 7020: 03a01001 moveq r1, #1 7024: e5cb0002 strb r0, [fp, #2] 7028: e1cba0b0 strh sl, [fp] ``` Note that `fp` points to `sp + 29`, so the three `str*`-instructions should fill up a 32bit - value at `sp + 28`, which is later used as the value `n` in `Ok(n) => written += n`. This doesn't work on ARMv5 as the `strh` can't write to the unaligned contents of `fp`, so the upper bits of `n` won't get cleared, leading to the assertion failure in Vec::drain. With `+strict-align`, the code works as expected. --- src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs index 200c6ab74cc6d..ef00c9a3278b9 100644 --- a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs +++ b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs @@ -25,7 +25,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+soft-float".to_string(), + features: "+soft-float,+strict-align".to_string(), // No atomic instructions on ARMv5 max_atomic_width: Some(0), abi_blacklist: super::arm_base::abi_blacklist(), From 068a3ba50a45dd59a386ca71a9c973e8351fc889 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 23 May 2017 19:02:23 -0700 Subject: [PATCH 08/15] Support VS 2017 Fixes #38584 --- src/Cargo.lock | 42 ++-- src/Cargo.toml | 1 + src/bootstrap/Cargo.toml | 2 +- src/liballoc_jemalloc/Cargo.toml | 2 +- src/libcompiler_builtins/Cargo.toml | 2 +- src/libflate/Cargo.toml | 2 +- src/librustc_llvm/Cargo.toml | 2 +- src/librustc_trans/Cargo.toml | 3 + src/librustc_trans/back/link.rs | 41 ++- src/librustc_trans/back/msvc/arch.rs | 56 ----- src/librustc_trans/back/msvc/mod.rs | 305 ----------------------- src/librustc_trans/back/msvc/registry.rs | 136 ---------- src/librustc_trans/lib.rs | 6 +- src/librustdoc/Cargo.toml | 2 +- src/libstd/Cargo.toml | 2 +- 15 files changed, 71 insertions(+), 533 deletions(-) delete mode 100644 src/librustc_trans/back/msvc/arch.rs delete mode 100644 src/librustc_trans/back/msvc/mod.rs delete mode 100644 src/librustc_trans/back/msvc/registry.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index d55dd919bdf28..7e4b6c4a1f81f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -44,7 +44,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -84,7 +84,7 @@ name = "backtrace-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -110,7 +110,7 @@ dependencies = [ "build_helper 0.1.0", "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -239,7 +239,7 @@ name = "cmake" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -257,7 +257,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -308,7 +308,7 @@ name = "curl-sys" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -411,7 +411,7 @@ name = "flate" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -444,8 +444,14 @@ dependencies = [ [[package]] name = "gcc" -version = "0.3.46" +version = "0.3.49" +source = "git+https://github.com/brson/gcc-rs?branch=vs2017#165ee635bb261aa39c1948058e6c38e7d03c5abf" + +[[package]] +name = "gcc" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" +replace = "gcc 0.3.49 (git+https://github.com/brson/gcc-rs?branch=vs2017)" [[package]] name = "gdi32-sys" @@ -605,7 +611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -630,7 +636,7 @@ name = "libz-sys" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -650,7 +656,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -697,7 +703,7 @@ name = "miniz-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -830,7 +836,7 @@ name = "openssl-sys" version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1248,7 +1254,7 @@ name = "rustc_llvm" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_bitflags 0.0.0", ] @@ -1375,6 +1381,7 @@ name = "rustc_trans" version = "0.0.0" dependencies = [ "flate 0.0.0", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1425,7 +1432,7 @@ dependencies = [ "arena 0.0.0", "build_helper 0.1.0", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1577,7 +1584,7 @@ dependencies = [ "collections 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", @@ -2042,7 +2049,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" "checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf" -"checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f" +"checksum gcc 0.3.49 (git+https://github.com/brson/gcc-rs?branch=vs2017)" = "" +"checksum gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "9be730064c122681712957ba1a9abaf082150be8aaf94526a805d900015b65b9" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9de9df4358c17e448a778d90cd0272e1dab5eae30244502333fa2001c4e24357" diff --git a/src/Cargo.toml b/src/Cargo.toml index 85a6df3573ae1..927bc64032a95 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -37,3 +37,4 @@ debug-assertions = false [replace] "https://github.com/rust-lang/cargo#0.20.0" = { path = "tools/cargo" } +"gcc:0.3.49" = { git = "https://github.com/brson/gcc-rs", branch = "vs2017" } diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index cc560e0172e3a..efceb103715a1 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -36,5 +36,5 @@ num_cpus = "1.0" toml = "0.1" getopts = "0.2" rustc-serialize = "0.3" -gcc = "0.3.46" +gcc = "0.3.49" libc = "0.2" diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml index 01393be9949ae..6c9b64fe85caa 100644 --- a/src/liballoc_jemalloc/Cargo.toml +++ b/src/liballoc_jemalloc/Cargo.toml @@ -17,7 +17,7 @@ libc = { path = "../rustc/libc_shim" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.49" [features] debug = [] diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml index 3f844b3f09e3a..64217a9cd4ace 100644 --- a/src/libcompiler_builtins/Cargo.toml +++ b/src/libcompiler_builtins/Cargo.toml @@ -16,4 +16,4 @@ core = { path = "../libcore" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.49" diff --git a/src/libflate/Cargo.toml b/src/libflate/Cargo.toml index 5423da9c81c02..87362f01ce265 100644 --- a/src/libflate/Cargo.toml +++ b/src/libflate/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["dylib"] [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.47" diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index f97daa22ff662..9d70e2ff406c1 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -17,4 +17,4 @@ rustc_bitflags = { path = "../librustc_bitflags" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.49" diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 4ccc85257f3c9..86c6b51e303d8 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -25,3 +25,6 @@ rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } + +[target."cfg(windows)".dependencies] +gcc = "0.3.49" diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e40267238801c..ee92a4b4a2dfe 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -12,7 +12,6 @@ use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::linker::Linker; use super::rpath::RPathConfig; use super::rpath; -use super::msvc; use metadata::METADATA_FILENAME; use rustc::session::config::{self, NoDebugInfo, OutputFilenames, Input, OutputType}; use rustc::session::filesearch; @@ -142,20 +141,41 @@ pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMet return r; } -// The third parameter is for an extra path to add to PATH for MSVC -// cross linkers for host toolchain DLL dependencies -pub fn get_linker(sess: &Session) -> (String, Command, Option) { +// The third parameter is for an env vars, used to set up the path for MSVC +// to find its DLLs +pub fn get_linker(sess: &Session) -> (String, Command, Vec<(OsString, OsString)>) { if let Some(ref linker) = sess.opts.cg.linker { - (linker.clone(), Command::new(linker), None) + (linker.clone(), Command::new(linker), vec![]) } else if sess.target.target.options.is_like_msvc { - let (cmd, host) = msvc::link_exe_cmd(sess); - ("link.exe".to_string(), cmd, host) + let (cmd, envs) = msvc_link_exe_cmd(sess); + ("link.exe".to_string(), cmd, envs) } else { (sess.target.target.options.linker.clone(), - Command::new(&sess.target.target.options.linker), None) + Command::new(&sess.target.target.options.linker), vec![]) } } +#[cfg(windows)] +pub fn msvc_link_exe_cmd(sess: &Session) -> (Command, Vec<(OsString, OsString)>) { + use gcc::windows_registry; + + let target = &sess.opts.target_triple; + let tool = windows_registry::find_tool(target, "link.exe"); + + if let Some(tool) = tool { + let envs = tool.env().to_vec(); + (tool.to_command(), envs) + } else { + debug!("Failed to locate linker."); + (Command::new("link.exe"), vec![]) + } +} + +#[cfg(not(windows))] +pub fn msvc_link_exe_cmd(_sess: &Session) -> (Command, Vec<(OsString, OsString)>) { + (Command::new("link.exe"), vec![]) +} + pub fn get_ar_prog(sess: &Session) -> String { sess.opts.cg.ar.clone().unwrap_or_else(|| { sess.target.target.options.ar.clone() @@ -706,8 +726,9 @@ fn link_natively(sess: &Session, let flavor = sess.linker_flavor(); // The invocations of cc share some flags across platforms - let (pname, mut cmd, extra) = get_linker(sess); - cmd.env("PATH", command_path(sess, extra)); + let (pname, mut cmd, envs) = get_linker(sess); + // This will set PATH on MSVC + cmd.envs(envs); let root = sess.target_filesearch(PathKind::Native).get_lib_path(); if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { diff --git a/src/librustc_trans/back/msvc/arch.rs b/src/librustc_trans/back/msvc/arch.rs deleted file mode 100644 index c10312a8e1710..0000000000000 --- a/src/librustc_trans/back/msvc/arch.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(non_camel_case_types, non_snake_case)] - -use libc::c_void; -use std::mem; - -type DWORD = u32; -type WORD = u16; -type LPVOID = *mut c_void; -type DWORD_PTR = usize; - -const PROCESSOR_ARCHITECTURE_INTEL: WORD = 0; -const PROCESSOR_ARCHITECTURE_AMD64: WORD = 9; - -#[repr(C)] -struct SYSTEM_INFO { - wProcessorArchitecture: WORD, - _wReserved: WORD, - _dwPageSize: DWORD, - _lpMinimumApplicationAddress: LPVOID, - _lpMaximumApplicationAddress: LPVOID, - _dwActiveProcessorMask: DWORD_PTR, - _dwNumberOfProcessors: DWORD, - _dwProcessorType: DWORD, - _dwAllocationGranularity: DWORD, - _wProcessorLevel: WORD, - _wProcessorRevision: WORD, -} - -extern "system" { - fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO); -} - -pub enum Arch { - X86, - Amd64, -} - -pub fn host_arch() -> Option { - let mut info = unsafe { mem::zeroed() }; - unsafe { GetNativeSystemInfo(&mut info) }; - match info.wProcessorArchitecture { - PROCESSOR_ARCHITECTURE_INTEL => Some(Arch::X86), - PROCESSOR_ARCHITECTURE_AMD64 => Some(Arch::Amd64), - _ => None, - } -} diff --git a/src/librustc_trans/back/msvc/mod.rs b/src/librustc_trans/back/msvc/mod.rs deleted file mode 100644 index 97648888fa9b9..0000000000000 --- a/src/librustc_trans/back/msvc/mod.rs +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! MSVC-specific logic for linkers and such. -//! -//! This module contains a cross-platform interface but has a blank unix -//! implementation. The Windows implementation builds on top of Windows native -//! libraries (reading registry keys), so it otherwise wouldn't link on unix. -//! -//! Note that we don't have much special logic for finding the system linker on -//! any other platforms, so it may seem a little odd to single out MSVC to have -//! a good deal of code just to find the linker. Unlike Unix systems, however, -//! the MSVC linker is not in the system PATH by default. It also additionally -//! needs a few environment variables or command line flags to be able to link -//! against system libraries. -//! -//! In order to have a nice smooth experience on Windows, the logic in this file -//! is here to find the MSVC linker and set it up in the default configuration -//! one would need to set up anyway. This means that the Rust compiler can be -//! run not only in the developer shells of MSVC but also the standard cmd.exe -//! shell or MSYS shells. -//! -//! As a high-level note, all logic in this module for looking up various -//! paths/files is based on Microsoft's logic in their vcvars bat files, but -//! comments can also be found below leading through the various code paths. - -// A simple macro to make this option mess easier to read -#[cfg(windows)] -macro_rules! otry { - ($expr:expr) => (match $expr { - Some(val) => val, - None => return None, - }) -} - -#[cfg(windows)] -mod registry; -#[cfg(windows)] -mod arch; - -#[cfg(windows)] -mod platform { - use std::env; - use std::ffi::OsString; - use std::fs; - use std::path::{Path, PathBuf}; - use std::process::Command; - use rustc::session::Session; - use super::arch::{host_arch, Arch}; - use super::registry::LOCAL_MACHINE; - - // First we need to figure out whether the environment is already correctly - // configured by vcvars. We do this by looking at the environment variable - // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set - // otherwise. If it is defined, then we find `link.exe` in `PATH and trust - // that everything else is configured correctly. - // - // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where - // it claimed it should be), then we resort to finding everything - // ourselves. First we find where the latest version of MSVC is installed - // and what version it is. Then based on the version we find the - // appropriate SDKs. - // - // If despite our best efforts we are still unable to find MSVC then we - // just blindly call `link.exe` and hope for the best. - // - // This code only supports VC 11 through 15. For versions older than that - // the user will need to manually execute the appropriate vcvars bat file - // and it should hopefully work. - // - // The second member of the tuple we return is the directory for the host - // linker toolchain, which is necessary when using the cross linkers. - pub fn link_exe_cmd(sess: &Session) -> (Command, Option) { - let arch = &sess.target.target.arch; - env::var_os("VCINSTALLDIR").and_then(|_| { - debug!("Detected that vcvars was already run."); - let path = otry!(env::var_os("PATH")); - // Mingw has its own link which is not the link we want so we - // look for `cl.exe` too as a precaution. - env::split_paths(&path).find(|path| { - path.join("cl.exe").is_file() - && path.join("link.exe").is_file() - }).map(|path| { - (Command::new(path.join("link.exe")), None) - }) - }).or_else(|| { - None.or_else(|| { - find_msvc_latest(arch, "15.0") - }).or_else(|| { - find_msvc_latest(arch, "14.0") - }).or_else(|| { - find_msvc_12(arch) - }).or_else(|| { - find_msvc_11(arch) - }).map(|(cmd, path)| (cmd, Some(path))) - }).unwrap_or_else(|| { - debug!("Failed to locate linker."); - (Command::new("link.exe"), None) - }) - } - - // For MSVC 14 or newer we need to find the Universal CRT as well as either - // the Windows 10 SDK or Windows 8.1 SDK. - fn find_msvc_latest(arch: &str, ver: &str) -> Option<(Command, PathBuf)> { - let vcdir = otry!(get_vc_dir(ver)); - let (mut cmd, host) = otry!(get_linker(&vcdir, arch)); - let sub = otry!(lib_subdir(arch)); - let ucrt = otry!(get_ucrt_dir()); - debug!("Found Universal CRT {:?}", ucrt); - add_lib(&mut cmd, &ucrt.join("ucrt").join(sub)); - if let Some(dir) = get_sdk10_dir() { - debug!("Found Win10 SDK {:?}", dir); - add_lib(&mut cmd, &dir.join("um").join(sub)); - } else if let Some(dir) = get_sdk81_dir() { - debug!("Found Win8.1 SDK {:?}", dir); - add_lib(&mut cmd, &dir.join("um").join(sub)); - } else { - return None - } - Some((cmd, host)) - } - - // For MSVC 12 we need to find the Windows 8.1 SDK. - fn find_msvc_12(arch: &str) -> Option<(Command, PathBuf)> { - let vcdir = otry!(get_vc_dir("12.0")); - let (mut cmd, host) = otry!(get_linker(&vcdir, arch)); - let sub = otry!(lib_subdir(arch)); - let sdk81 = otry!(get_sdk81_dir()); - debug!("Found Win8.1 SDK {:?}", sdk81); - add_lib(&mut cmd, &sdk81.join("um").join(sub)); - Some((cmd, host)) - } - - // For MSVC 11 we need to find the Windows 8 SDK. - fn find_msvc_11(arch: &str) -> Option<(Command, PathBuf)> { - let vcdir = otry!(get_vc_dir("11.0")); - let (mut cmd, host) = otry!(get_linker(&vcdir, arch)); - let sub = otry!(lib_subdir(arch)); - let sdk8 = otry!(get_sdk8_dir()); - debug!("Found Win8 SDK {:?}", sdk8); - add_lib(&mut cmd, &sdk8.join("um").join(sub)); - Some((cmd, host)) - } - - // A convenience function to append library paths. - fn add_lib(cmd: &mut Command, lib: &Path) { - let mut arg: OsString = "/LIBPATH:".into(); - arg.push(lib); - cmd.arg(arg); - } - - // Given a possible MSVC installation directory, we look for the linker and - // then add the MSVC library path. - fn get_linker(path: &Path, arch: &str) -> Option<(Command, PathBuf)> { - debug!("Looking for linker in {:?}", path); - bin_subdir(arch).into_iter().map(|(sub, host)| { - (path.join("bin").join(sub).join("link.exe"), - path.join("bin").join(host)) - }).filter(|&(ref path, _)| { - path.is_file() - }).map(|(path, host)| { - (Command::new(path), host) - }).filter_map(|(mut cmd, host)| { - let sub = otry!(vc_lib_subdir(arch)); - add_lib(&mut cmd, &path.join("lib").join(sub)); - Some((cmd, host)) - }).next() - } - - // To find MSVC we look in a specific registry key for the version we are - // trying to find. - fn get_vc_dir(ver: &str) -> Option { - let key = otry!(LOCAL_MACHINE - .open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref()).ok()); - let path = otry!(key.query_str(ver).ok()); - Some(path.into()) - } - - // To find the Universal CRT we look in a specific registry key for where - // all the Universal CRTs are located and then sort them asciibetically to - // find the newest version. While this sort of sorting isn't ideal, it is - // what vcvars does so that's good enough for us. - fn get_ucrt_dir() -> Option { - let key = otry!(LOCAL_MACHINE - .open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref()).ok()); - let root = otry!(key.query_str("KitsRoot10").ok()); - let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok()); - readdir.filter_map(|dir| { - dir.ok() - }).map(|dir| { - dir.path() - }).filter(|dir| { - dir.components().last().and_then(|c| { - c.as_os_str().to_str() - }).map(|c| { - c.starts_with("10.") && dir.join("ucrt").is_dir() - }).unwrap_or(false) - }).max() - } - - // Vcvars finds the correct version of the Windows 10 SDK by looking - // for the include `um\Windows.h` because sometimes a given version will - // only have UCRT bits without the rest of the SDK. Since we only care about - // libraries and not includes, we instead look for `um\x64\kernel32.lib`. - // Since the 32-bit and 64-bit libraries are always installed together we - // only need to bother checking x64, making this code a tiny bit simpler. - // Like we do for the Universal CRT, we sort the possibilities - // asciibetically to find the newest one as that is what vcvars does. - fn get_sdk10_dir() -> Option { - let key = otry!(LOCAL_MACHINE - .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref()).ok()); - let root = otry!(key.query_str("InstallationFolder").ok()); - let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok()); - let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok()) - .map(|dir| dir.path()).collect(); - dirs.sort(); - dirs.into_iter().rev().filter(|dir| { - dir.join("um").join("x64").join("kernel32.lib").is_file() - }).next() - } - - // Interestingly there are several subdirectories, `win7` `win8` and - // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same - // applies to us. Note that if we were targetting kernel mode drivers - // instead of user mode applications, we would care. - fn get_sdk81_dir() -> Option { - let key = otry!(LOCAL_MACHINE - .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref()).ok()); - let root = otry!(key.query_str("InstallationFolder").ok()); - Some(Path::new(&root).join("lib").join("winv6.3")) - } - - fn get_sdk8_dir() -> Option { - let key = otry!(LOCAL_MACHINE - .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref()).ok()); - let root = otry!(key.query_str("InstallationFolder").ok()); - Some(Path::new(&root).join("lib").join("win8")) - } - - // When choosing the linker toolchain to use, we have to choose the one - // which matches the host architecture. Otherwise we end up in situations - // where someone on 32-bit Windows is trying to cross compile to 64-bit and - // it tries to invoke the native 64-bit linker which won't work. - // - // For the return value of this function, the first member of the tuple is - // the folder of the linker we will be invoking, while the second member - // is the folder of the host toolchain for that linker which is essential - // when using a cross linker. We return a Vec since on x64 there are often - // two linkers that can target the architecture we desire. The 64-bit host - // linker is preferred, and hence first, due to 64-bit allowing it more - // address space to work with and potentially being faster. - // - // FIXME - Figure out what happens when the host architecture is arm. - fn bin_subdir(arch: &str) -> Vec<(&'static str, &'static str)> { - match (arch, host_arch()) { - ("x86", Some(Arch::X86)) => vec![("", "")], - ("x86", Some(Arch::Amd64)) => vec![("amd64_x86", "amd64"), ("", "")], - ("x86_64", Some(Arch::X86)) => vec![("x86_amd64", "")], - ("x86_64", Some(Arch::Amd64)) => vec![("amd64", "amd64"), ("x86_amd64", "")], - ("arm", Some(Arch::X86)) => vec![("x86_arm", "")], - ("arm", Some(Arch::Amd64)) => vec![("amd64_arm", "amd64"), ("x86_arm", "")], - _ => vec![], - } - } - - fn lib_subdir(arch: &str) -> Option<&'static str> { - match arch { - "x86" => Some("x86"), - "x86_64" => Some("x64"), - "arm" => Some("arm"), - _ => None, - } - } - - // MSVC's x86 libraries are not in a subfolder - fn vc_lib_subdir(arch: &str) -> Option<&'static str> { - match arch { - "x86" => Some(""), - "x86_64" => Some("amd64"), - "arm" => Some("arm"), - _ => None, - } - } -} - -// If we're not on Windows, then there's no registry to search through and MSVC -// wouldn't be able to run, so we just call `link.exe` and hope for the best. -#[cfg(not(windows))] -mod platform { - use std::path::PathBuf; - use std::process::Command; - use rustc::session::Session; - pub fn link_exe_cmd(_sess: &Session) -> (Command, Option) { - (Command::new("link.exe"), None) - } -} - -pub use self::platform::*; diff --git a/src/librustc_trans/back/msvc/registry.rs b/src/librustc_trans/back/msvc/registry.rs deleted file mode 100644 index 8242f53896afc..0000000000000 --- a/src/librustc_trans/back/msvc/registry.rs +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::io; -use std::ffi::{OsString, OsStr}; -use std::os::windows::prelude::*; -use std::ptr; -use libc::c_long; - -pub type DWORD = u32; -type LPCWSTR = *const u16; -type LONG = c_long; -type LPDWORD = *mut DWORD; -type LPBYTE = *mut u8; - - -const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY; -const KEY_WOW64_32KEY: REGSAM = 0x0200; -const KEY_READ: REGSAM = (STANDARD_RIGTS_READ | KEY_QUERY_VALUE | - KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & !SYNCHRONIZE; -const STANDARD_RIGTS_READ: REGSAM = READ_CONTROL; -const READ_CONTROL: REGSAM = 0x00020000; -const KEY_QUERY_VALUE: REGSAM = 0x0001; -const KEY_ENUMERATE_SUB_KEYS: REGSAM = 0x0008; -const KEY_NOTIFY: REGSAM = 0x0010; -const SYNCHRONIZE: REGSAM = 0x00100000; -const REG_SZ: DWORD = 1; -const ERROR_SUCCESS: i32 = 0; - -pub enum __HKEY__ {} -pub type HKEY = *mut __HKEY__; -pub type PHKEY = *mut HKEY; -pub type REGSAM = DWORD; - -#[link(name = "advapi32")] -extern "system" { - fn RegOpenKeyExW(hKey: HKEY, - lpSubKey: LPCWSTR, - ulOptions: DWORD, - samDesired: REGSAM, - phkResult: PHKEY) -> LONG; - fn RegQueryValueExW(hKey: HKEY, - lpValueName: LPCWSTR, - lpReserved: LPDWORD, - lpType: LPDWORD, - lpData: LPBYTE, - lpcbData: LPDWORD) -> LONG; - fn RegCloseKey(hKey: HKEY) -> LONG; -} - -pub struct RegistryKey(Repr); - -struct OwnedKey(HKEY); - -enum Repr { - Const(HKEY), - Owned(OwnedKey), -} - -unsafe impl Sync for RegistryKey {} -unsafe impl Send for RegistryKey {} - -pub static LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE)); - -impl RegistryKey { - fn raw(&self) -> HKEY { - match self.0 { - Repr::Const(val) => val, - Repr::Owned(ref val) => val.0, - } - } - - pub fn open(&self, key: &OsStr) -> io::Result { - let key = key.encode_wide().chain(Some(0)).collect::>(); - let mut ret = ptr::null_mut(); - let err = unsafe { - RegOpenKeyExW(self.raw(), key.as_ptr(), 0, - KEY_READ | KEY_WOW64_32KEY, &mut ret) - }; - if err == ERROR_SUCCESS { - Ok(RegistryKey(Repr::Owned(OwnedKey(ret)))) - } else { - Err(io::Error::from_raw_os_error(err as i32)) - } - } - - pub fn query_str(&self, name: &str) -> io::Result { - let name: &OsStr = name.as_ref(); - let name = name.encode_wide().chain(Some(0)).collect::>(); - let mut len = 0; - let mut kind = 0; - unsafe { - let err = RegQueryValueExW(self.raw(), name.as_ptr(), ptr::null_mut(), - &mut kind, ptr::null_mut(), &mut len); - if err != ERROR_SUCCESS { - return Err(io::Error::from_raw_os_error(err as i32)) - } - if kind != REG_SZ { - return Err(io::Error::new(io::ErrorKind::Other, - "registry key wasn't a string")) - } - - // The length here is the length in bytes, but we're using wide - // characters so we need to be sure to halve it for the capacity - // passed in. - let mut v = Vec::with_capacity(len as usize / 2); - let err = RegQueryValueExW(self.raw(), name.as_ptr(), ptr::null_mut(), - ptr::null_mut(), v.as_mut_ptr() as *mut _, - &mut len); - if err != ERROR_SUCCESS { - return Err(io::Error::from_raw_os_error(err as i32)) - } - v.set_len(len as usize / 2); - - // Some registry keys may have a terminating nul character, but - // we're not interested in that, so chop it off if it's there. - if v[v.len() - 1] == 0 { - v.pop(); - } - Ok(OsString::from_wide(&v)) - } - } -} - -impl Drop for OwnedKey { - fn drop(&mut self) { - unsafe { RegCloseKey(self.0); } - } -} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index c111a3983e7ea..71fb2e5fb202a 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -35,6 +35,7 @@ #![feature(slice_patterns)] #![feature(unicode)] #![feature(conservative_impl_trait)] +#![feature(command_envs)] #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))] #![cfg_attr(stage0, feature(rustc_private))] @@ -62,6 +63,8 @@ extern crate rustc_bitflags; extern crate syntax_pos; extern crate rustc_errors as errors; extern crate serialize; +#[cfg(windows)] +extern crate gcc; // Used to locate MSVC, not gcc :) pub use base::trans_crate; pub use back::symbol_names::provide; @@ -77,8 +80,7 @@ pub mod back { pub(crate) mod symbol_export; pub(crate) mod symbol_names; pub mod write; - mod msvc; - mod rpath; + pub mod rpath; } mod diagnostics; diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 0e8a6606ae79f..20f150741a0a3 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -30,4 +30,4 @@ pulldown-cmark = { version = "0.0.14", default-features = false } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.49" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 717892be2abad..4e11969a4296f 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -35,7 +35,7 @@ rustc_tsan = { path = "../librustc_tsan" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.27" +gcc = "0.3.49" [features] backtrace = [] From 594f597c408d4fb39b6d24b6673dd2e7774a81d8 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 26 May 2017 14:31:02 -0700 Subject: [PATCH 09/15] wip --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 190cb3380a18c..a8f0595765404 100644 --- a/.travis.yml +++ b/.travis.yml @@ -165,6 +165,7 @@ script: stamp src/ci/docker/run.sh $IMAGE; fi fi + - sleep 300000 after_success: - > From a333be7cfecbbe9a659f4f180978fa4dd74d455d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 May 2017 18:46:29 +0200 Subject: [PATCH 10/15] Add new error code --- src/librustc/diagnostics.rs | 19 ++++++++++++++++++- src/librustc/middle/entry.rs | 2 +- src/librustc/session/mod.rs | 18 +++++++++++------- src/librustc_errors/lib.rs | 6 ++++++ src/libsyntax/diagnostics/macros.rs | 8 ++++++++ src/test/ui/missing-items/m2.stderr | 2 +- src/test/ui/resolve/issue-14254.stderr | 2 +- src/test/ui/resolve/issue-21221-2.stderr | 2 +- ...uggest-path-instead-of-mod-dot-item.stderr | 2 +- src/test/ui/span/issue-35987.stderr | 2 +- src/test/ui/token/issue-10636-2.stderr | 2 +- src/test/ui/token/issue-41155.stderr | 2 +- 12 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 470dcb4bd61e1..2beb40d6b2f1a 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1871,7 +1871,9 @@ makes a difference in practice.) E0593: r##" You tried to supply an `Fn`-based type with an incorrect number of arguments -than what was expected. Erroneous code example: +than what was expected. + +Erroneous code example: ```compile_fail,E0593 fn foo(x: F) { } @@ -1883,6 +1885,21 @@ fn main() { ``` "##, +E0601: r##" +No `main` function was found in a binary crate. To fix this error, just add a +`main` function. For example: + +``` +fn main() { + // Your program will start here. + println!("Hello world!"); +} +``` + +If you don't know the basics of Rust, you can go look to the Rust Book to get +started: https://doc.rust-lang.org/book/ +"##, + } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 24748b6cf65b8..b26cccf5f1617 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -162,7 +162,7 @@ fn configure_main(this: &mut EntryContext) { this.session.entry_type.set(Some(config::EntryMain)); } else { // No main function - let mut err = this.session.struct_err("main function not found"); + let mut err = struct_err!(this.session, E0601, "main function not found"); if !this.non_main_fns.is_empty() { // There were some functions named 'main' though. Try to give the user a hint. err.note("the main function must be defined at the crate level \ diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 28531893659e6..827fa72f03404 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -158,14 +158,14 @@ impl Session { pub fn struct_span_warn<'a, S: Into>(&'a self, sp: S, msg: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_warn(sp, msg) } pub fn struct_span_warn_with_code<'a, S: Into>(&'a self, sp: S, msg: &str, code: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { @@ -174,30 +174,34 @@ impl Session { pub fn struct_span_err<'a, S: Into>(&'a self, sp: S, msg: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_err(sp, msg) } pub fn struct_span_err_with_code<'a, S: Into>(&'a self, sp: S, msg: &str, code: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_err_with_code(sp, msg, code) } - pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + // FIXME: This method should be removed (every error should have an associated error code). + pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { self.diagnostic().struct_err(msg) } + pub fn struct_err_with_code<'a>(&'a self, msg: &str, code: &str) -> DiagnosticBuilder<'a> { + self.diagnostic().struct_err_with_code(msg, code) + } pub fn struct_span_fatal<'a, S: Into>(&'a self, sp: S, msg: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_fatal(sp, msg) } pub fn struct_span_fatal_with_code<'a, S: Into>(&'a self, sp: S, msg: &str, code: &str) - -> DiagnosticBuilder<'a> { + -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index f7191e4921637..d1aaaf4ba7b37 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -345,9 +345,15 @@ impl Handler { result.code(code.to_owned()); result } + // FIXME: This method should be removed (every error should have an associated error code). pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { DiagnosticBuilder::new(self, Level::Error, msg) } + pub fn struct_err_with_code<'a>(&'a self, msg: &str, code: &str) -> DiagnosticBuilder<'a> { + let mut result = DiagnosticBuilder::new(self, Level::Error, msg); + result.code(code.to_owned()); + result + } pub fn struct_span_fatal<'a, S: Into>(&'a self, sp: S, msg: &str) diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs index 25e0428248df4..13016d72127ea 100644 --- a/src/libsyntax/diagnostics/macros.rs +++ b/src/libsyntax/diagnostics/macros.rs @@ -38,6 +38,14 @@ macro_rules! span_warn { }) } +#[macro_export] +macro_rules! struct_err { + ($session:expr, $code:ident, $($message:tt)*) => ({ + __diagnostic_used!($code); + $session.struct_err_with_code(&format!($($message)*), stringify!($code)) + }) +} + #[macro_export] macro_rules! span_err_or_warn { ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr index 26748d18ffa95..2d699c66359d8 100644 --- a/src/test/ui/missing-items/m2.stderr +++ b/src/test/ui/missing-items/m2.stderr @@ -1,4 +1,4 @@ -error: main function not found +error[E0601]: main function not found error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method` --> $DIR/m2.rs:20:1 diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr index 8aaad906ea28a..009d969fc285d 100644 --- a/src/test/ui/resolve/issue-14254.stderr +++ b/src/test/ui/resolve/issue-14254.stderr @@ -142,7 +142,7 @@ error[E0425]: cannot find value `bah` in this scope 133 | bah; | ^^^ did you mean `Self::bah`? -error: main function not found +error[E0601]: main function not found error: aborting due to previous error(s) diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index f0b22754e6444..b35f1bd26706c 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -7,7 +7,7 @@ error[E0405]: cannot find trait `T` in this scope help: possible candidate is found in another module, you can import it into scope | use foo::bar::T; -error: main function not found +error[E0601]: main function not found error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index 24cef694737e0..a34c27a47da82 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -72,7 +72,7 @@ error[E0423]: expected function, found module `a::b` | | | did you mean `I`? -error: main function not found +error[E0601]: main function not found error: aborting due to previous error(s) diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index e53ea6a55afb5..a2597aba0bd29 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -7,7 +7,7 @@ error[E0404]: expected trait, found type parameter `Add` help: possible better candidate is found in another module, you can import it into scope | use std::ops::Add; -error: main function not found +error[E0601]: main function not found error: cannot continue compilation due to previous error diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index faa30dca94581..4b0b05ca65adc 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -22,7 +22,7 @@ error: expected expression, found `)` 19 | } //~ ERROR: incorrect close delimiter | ^ -error: main function not found +error[E0601]: main function not found error: aborting due to previous error(s) diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr index 96c2d764e7101..56f71a2995382 100644 --- a/src/test/ui/token/issue-41155.stderr +++ b/src/test/ui/token/issue-41155.stderr @@ -12,7 +12,7 @@ error[E0412]: cannot find type `S` in this scope 11 | impl S { | ^ not found in this scope -error: main function not found +error[E0601]: main function not found error: aborting due to previous error(s) From 62989c1a0cf0840315becf2ba0a141b9b3a1c62b Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 30 May 2017 22:21:00 -0700 Subject: [PATCH 11/15] associated_consts: check trait obligations and regionck for associated consts Closes #41323 --- src/librustc_typeck/check/compare_method.rs | 10 ++++++- .../associated-const-generic-obligations.rs | 30 +++++++++++++++++++ .../associated-const-impl-wrong-lifetime.rs | 27 +++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/associated-const-generic-obligations.rs create mode 100644 src/test/compile-fail/associated-const-impl-wrong-lifetime.rs diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 767cf8f48cfea..3121f4948504e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -787,6 +787,14 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diag.emit(); } - // FIXME(#41323) Check the obligations in the fulfillment context. + // Check that all obligations are satisfied by the implementation's + // version. + if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { + infcx.report_fulfillment_errors(errors); + return; + } + + let fcx = FnCtxt::new(&inh, impl_c_node_id); + fcx.regionck_item(impl_c_node_id, impl_c_span, &[]); }); } diff --git a/src/test/compile-fail/associated-const-generic-obligations.rs b/src/test/compile-fail/associated-const-generic-obligations.rs new file mode 100644 index 0000000000000..90afe8d7336a7 --- /dev/null +++ b/src/test/compile-fail/associated-const-generic-obligations.rs @@ -0,0 +1,30 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(associated_consts)] + +trait Foo { + type Out: Sized; +} + +impl Foo for String { + type Out = String; +} + +trait Bar: Foo { + const FROM: Self::Out; +} + +impl Bar for T { + const FROM: &'static str = "foo"; + //~^ ERROR the trait bound `T: Foo` is not satisfied [E0277] +} + +fn main() {} diff --git a/src/test/compile-fail/associated-const-impl-wrong-lifetime.rs b/src/test/compile-fail/associated-const-impl-wrong-lifetime.rs new file mode 100644 index 0000000000000..834f346069418 --- /dev/null +++ b/src/test/compile-fail/associated-const-impl-wrong-lifetime.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(associated_consts)] + +trait Foo { + const NAME: &'static str; +} + + +impl<'a> Foo for &'a () { +//~^ NOTE the lifetime 'a as defined + const NAME: &'a str = "unit"; + //~^ ERROR mismatched types [E0308] + //~| NOTE lifetime mismatch + //~| NOTE expected type `&'static str` + //~| NOTE ...does not necessarily outlive the static lifetime +} + +fn main() {} From 7a87469af7be24f6653ab59be0f1a544f4f3eb80 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 31 May 2017 01:30:13 -0700 Subject: [PATCH 12/15] Give the `try_trait` feature its own tracking issue --- .../unstable-book/src/library-features/try-trait.md | 4 ++-- src/libcore/ops.rs | 12 ++++++------ src/libcore/result.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/try-trait.md b/src/doc/unstable-book/src/library-features/try-trait.md index f08929d4e3c2a..7289e95c2a002 100644 --- a/src/doc/unstable-book/src/library-features/try-trait.md +++ b/src/doc/unstable-book/src/library-features/try-trait.md @@ -1,7 +1,7 @@ # `try_trait` -The tracking issue for this feature is: [#31436] +The tracking issue for this feature is: [#42327] -[#31436]: https://github.com/rust-lang/rust/issues/31436 +[#42327]: https://github.com/rust-lang/rust/issues/42327 ------------------------ diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 912f3d4ff07d0..a1de8fe76e258 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -2988,13 +2988,13 @@ impl Try for _DummyErrorType { /// in terms of a success/failure dichotomy. This trait allows both /// extracting those success or failure values from an existing instance and /// creating a new instance from a success or failure value. -#[unstable(feature = "try_trait", issue = "31436")] +#[unstable(feature = "try_trait", issue = "42327")] pub trait Try { /// The type of this value when viewed as successful. - #[unstable(feature = "try_trait", issue = "31436")] + #[unstable(feature = "try_trait", issue = "42327")] type Ok; /// The type of this value when viewed as failed. - #[unstable(feature = "try_trait", issue = "31436")] + #[unstable(feature = "try_trait", issue = "42327")] type Error; /// Applies the "?" operator. A return of `Ok(t)` means that the @@ -3006,16 +3006,16 @@ pub trait Try { /// in the return type of the enclosing scope (which must itself implement /// `Try`). Specifically, the value `X::from_error(From::from(e))` /// is returned, where `X` is the return type of the enclosing function. - #[unstable(feature = "try_trait", issue = "31436")] + #[unstable(feature = "try_trait", issue = "42327")] fn into_result(self) -> Result; /// Wrap an error value to construct the composite result. For example, /// `Result::Err(x)` and `Result::from_error(x)` are equivalent. - #[unstable(feature = "try_trait", issue = "31436")] + #[unstable(feature = "try_trait", issue = "42327")] fn from_error(v: Self::Error) -> Self; /// Wrap an OK value to construct the composite result. For example, /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent. - #[unstable(feature = "try_trait", issue = "31436")] + #[unstable(feature = "try_trait", issue = "42327")] fn from_ok(v: Self::Ok) -> Self; } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index a02c19f5f38b5..df7fff0df9270 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1110,7 +1110,7 @@ impl> FromIterator> for Result { } } -#[unstable(feature = "try_trait", issue = "31436")] +#[unstable(feature = "try_trait", issue = "42327")] impl ops::Try for Result { type Ok = T; type Error = E; From 3119e634e178d8acaed4a2d4a9d52e3b76ae79cf Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 31 May 2017 02:16:01 -0700 Subject: [PATCH 13/15] Add some try_trait ramblings to the unstable book --- .../src/library-features/try-trait.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/doc/unstable-book/src/library-features/try-trait.md b/src/doc/unstable-book/src/library-features/try-trait.md index 7289e95c2a002..0c07329025bca 100644 --- a/src/doc/unstable-book/src/library-features/try-trait.md +++ b/src/doc/unstable-book/src/library-features/try-trait.md @@ -5,3 +5,46 @@ The tracking issue for this feature is: [#42327] [#42327]: https://github.com/rust-lang/rust/issues/42327 ------------------------ + +This introduces a new trait `Try` for extending the `?` operator to types +other than `Result` (a part of [RFC 1859]). The trait provides the canonical +way to _view_ a type in terms of a success/failure dichotomy. This will +allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!` +macro on `Poll`, among other things. + +[RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859 + +Here's an example implementation of the trait: + +```rust,ignore +/// A distinct type to represent the `None` value of an `Option`. +/// +/// This enables using the `?` operator on `Option`; it's rarely useful alone. +#[derive(Debug)] +#[unstable(feature = "try_trait", issue = "42327")] +pub struct None { _priv: () } + +#[unstable(feature = "try_trait", issue = "42327")] +impl ops::Try for Option { + type Ok = T; + type Error = None; + + fn into_result(self) -> Result { + self.ok_or(None { _priv: () }) + } + + fn from_ok(v: T) -> Self { + Some(v) + } + + fn from_error(_: None) -> Self { + None + } +} +``` + +Note the `Error` associated type here is a new marker. The `?` operator +allows interconversion between different `Try` implementers only when +the error type can be converted `Into` the error type of the enclosing +function (or catch block). Having a distinct error type (as opposed to +just `()`, or similar) restricts this to where it's semantically meaningful. From e5e664fb07fcfa29f131243e5b8830834133280e Mon Sep 17 00:00:00 2001 From: Tobias Schottdorf Date: Wed, 31 May 2017 12:35:13 -0400 Subject: [PATCH 14/15] Upgrade ProjectionTy's Name to a DefId Part of #42171, in preparation for downgrading the contained `TraitRef` to only its `substs`. --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/infer/region_inference/mod.rs | 3 +- src/librustc/traits/project.rs | 27 +++++++++------- src/librustc/ty/context.rs | 2 +- src/librustc/ty/mod.rs | 4 +-- src/librustc/ty/relate.rs | 9 +++--- src/librustc/ty/structural_impls.rs | 7 ++-- src/librustc/ty/sty.rs | 37 ++++++++++++++++++---- src/librustc/ty/util.rs | 3 +- src/librustc/util/ppaux.rs | 11 ++++--- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_typeck/astconv.rs | 22 +++++++------ src/librustc_typeck/check/autoderef.rs | 9 +++--- src/librustc_typeck/check/regionck.rs | 10 +++--- src/librustdoc/clean/mod.rs | 2 +- 15 files changed, 91 insertions(+), 59 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 3bbac8d6a6425..b43c516f317f2 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -181,7 +181,7 @@ impl<'a, 'tcx, A, B> HashStable> for ty::Outlives } impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty }); -impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name }); +impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_def_id }); impl<'a, 'tcx> HashStable> for ty::Predicate<'tcx> { diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 2e3c2443544f6..acc1a397b4560 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -1542,7 +1542,8 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> { pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> { match *self { GenericKind::Param(ref p) => p.to_ty(tcx), - GenericKind::Projection(ref p) => tcx.mk_projection(p.trait_ref.clone(), p.item_name), + GenericKind::Projection(ref p) => tcx.mk_projection( + p.trait_ref.clone(), p.item_name(tcx)), } } } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index d7911870f391a..f5672ffbdc534 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -355,7 +355,7 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>( let tcx = selcx.infcx().tcx; let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i| - i.name == projection_ty.item_name && i.kind == ty::AssociatedKind::Type + i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type ).map(|i| i.def_id).unwrap(); let ty_var = selcx.infcx().next_ty_var( TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id))); @@ -436,7 +436,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>( // // ``` // let ty = selcx.tcx().mk_projection(projection_ty.trait_ref, - // projection_ty.item_name); + // projection_ty.item_name(tcx); // return Some(NormalizedTy { value: v, obligations: vec![] }); // ``` @@ -574,7 +574,7 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc predicate: trait_ref.to_predicate() }; let tcx = selcx.infcx().tcx; let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i| - i.name == projection_ty.item_name && i.kind == ty::AssociatedKind::Type + i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type ).map(|i| i.def_id).unwrap(); let new_value = selcx.infcx().next_ty_var( TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id))); @@ -729,7 +729,7 @@ fn project_type<'cx, 'gcx, 'tcx>( Ok(ProjectedTy::NoProgress( selcx.tcx().mk_projection( obligation.predicate.trait_ref.clone(), - obligation.predicate.item_name))) + obligation.predicate.item_name(selcx.tcx())))) } } } @@ -815,7 +815,8 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>( predicate); match predicate { ty::Predicate::Projection(ref data) => { - let same_name = data.item_name() == obligation.predicate.item_name; + let tcx = selcx.tcx(); + let same_name = data.item_name(tcx) == obligation.predicate.item_name(tcx); let is_match = same_name && infcx.probe(|_| { let data_poly_trait_ref = @@ -902,7 +903,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>( // type. let node_item = assoc_ty_def(selcx, impl_data.impl_def_id, - obligation.predicate.item_name); + obligation.predicate.item_name(selcx.tcx())); let is_default = if node_item.node.is_from_trait() { // If true, the impl inherited a `type Foo = Bar` @@ -1075,9 +1076,10 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>( // select only those projections that are actually projecting an // item with the correct name + let tcx = selcx.tcx(); let env_predicates = env_predicates.filter_map(|p| match p { ty::Predicate::Projection(data) => - if data.item_name() == obligation.predicate.item_name { + if data.item_name(tcx) == obligation.predicate.item_name(tcx) { Some(data) } else { None @@ -1180,10 +1182,11 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>( flag); let predicate = ty::Binder(ty::ProjectionPredicate { // (1) recreate binder here - projection_ty: ty::ProjectionTy { - trait_ref: trait_ref, - item_name: Symbol::intern(FN_OUTPUT_NAME), - }, + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + Symbol::intern(FN_OUTPUT_NAME), + ), ty: ret_type }); @@ -1228,7 +1231,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>( let VtableImplData { substs, nested, impl_def_id } = impl_vtable; let tcx = selcx.tcx(); - let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name); + let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name(tcx)); let ty = if !assoc_ty.item.defaultness.has_value() { // This means that the impl is missing a definition for the diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7316d45dc21ae..ce5f8394c8521 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1321,7 +1321,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { item_name: Name) -> Ty<'tcx> { // take a copy of substs so that we own the vectors inside - let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name }; + let inner = ProjectionTy::from_ref_and_name(self, trait_ref, item_name); self.mk_ty(TyProjection(inner)) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index aeffd71a09649..22fcc61953b2b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1051,8 +1051,8 @@ pub struct ProjectionPredicate<'tcx> { pub type PolyProjectionPredicate<'tcx> = Binder>; impl<'tcx> PolyProjectionPredicate<'tcx> { - pub fn item_name(&self) -> Name { - self.0.projection_ty.item_name // safe to skip the binder to access a name + pub fn item_name(&self, tcx: TyCtxt) -> Name { + self.0.projection_ty.item_name(tcx) // safe to skip the binder to access a name } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index bbe682e74bc04..d4f06a902eeaa 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -225,12 +225,13 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> { -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { - if a.item_name != b.item_name { + let tcx = relation.tcx(); + if a.item_name(tcx) != b.item_name(tcx) { Err(TypeError::ProjectionNameMismatched( - expected_found(relation, &a.item_name, &b.item_name))) + expected_found(relation, &a.item_name(tcx), &b.item_name(tcx)))) } else { let trait_ref = relation.relate(&a.trait_ref, &b.trait_ref)?; - Ok(ty::ProjectionTy { trait_ref: trait_ref, item_name: a.item_name }) + Ok(ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, a.item_name(tcx))) } } } @@ -457,7 +458,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, (&ty::TyProjection(ref a_data), &ty::TyProjection(ref b_data)) => { let projection_ty = relation.relate(a_data, b_data)?; - Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name)) + Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name(tcx))) } (&ty::TyAnon(a_def_id, a_substs), &ty::TyAnon(b_def_id, b_substs)) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 53d516e581b2a..c3ca679153759 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -135,10 +135,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> { fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { tcx.lift(&self.trait_ref).map(|trait_ref| { - ty::ProjectionTy { - trait_ref: trait_ref, - item_name: self.item_name - } + ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, self.item_name(tcx)) }) } } @@ -771,7 +768,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::ProjectionTy { trait_ref: self.trait_ref.fold_with(folder), - item_name: self.item_name, + item_def_id: self.item_def_id, } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 348d164af4190..bbb399434d6ae 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -556,9 +556,34 @@ pub struct ProjectionTy<'tcx> { /// The trait reference `T as Trait<..>`. pub trait_ref: ty::TraitRef<'tcx>, - /// The name `N` of the associated type. - pub item_name: Name, + /// The DefId of the TraitItem for the associated type N. + /// + /// Note that this is not the DefId of the TraitRef containing this + /// associated type, which is in tcx.associated_item(item_def_id).container. + pub item_def_id: DefId, } + +impl<'a, 'tcx> ProjectionTy<'tcx> { + /// Construct a ProjectionTy by searching the trait from trait_ref for the + /// associated item named item_name. + pub fn from_ref_and_name( + tcx: TyCtxt, trait_ref: ty::TraitRef<'tcx>, item_name: Name + ) -> ProjectionTy<'tcx> { + let item_def_id = tcx.associated_items(trait_ref.def_id).find( + |item| item.name == item_name).unwrap().def_id; + + ProjectionTy { + trait_ref: trait_ref, + item_def_id: item_def_id, + } + } + + pub fn item_name(self, tcx: TyCtxt) -> Name { + tcx.associated_item(self.item_def_id).name + } +} + + /// Signature of a function type, which I have arbitrarily /// decided to use to refer to the input/output types. /// @@ -871,10 +896,10 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> { assert!(!self_ty.has_escaping_regions()); ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), - item_name: self.item_name, - }, + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + self.trait_ref.with_self_ty(tcx, self_ty), + self.item_name), ty: self.ty, } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 8edae027dbfbc..ce0f1ed5bb86c 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -691,8 +691,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> self.hash(p.name.as_str()); } TyProjection(ref data) => { - self.def_id(data.trait_ref.def_id); - self.hash(data.item_name.as_str()); + self.def_id(data.item_def_id); } TyNever | TyBool | diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 340e4f2cfccbc..5a1b7393db312 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -216,9 +216,11 @@ pub fn parameterized(f: &mut fmt::Formatter, for projection in projections { start_or_continue(f, "<", ", ")?; - write!(f, "{}={}", - projection.projection_ty.item_name, - projection.ty)?; + ty::tls::with(|tcx| + write!(f, "{}={}", + projection.projection_ty.item_name(tcx), + projection.ty) + )?; } start_or_continue(f, "", ">")?; @@ -929,9 +931,10 @@ impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> { impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let item_name = ty::tls::with(|tcx| self.item_name(tcx)); write!(f, "{:?}::{}", self.trait_ref, - self.item_name) + item_name) } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d83740936d5d4..fa74e4d6ffccc 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -618,7 +618,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if let ty::TyProjection(proj) = ty.sty { for item in self.tcx.associated_items(proj.trait_ref.def_id) { if item.kind == ty::AssociatedKind::Type { - if item.name == proj.item_name { + if item.name == proj.item_name(self.tcx) { return Def::AssociatedTy(item.def_id); } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c9eb9807c41a5..212461a6d70e2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -553,10 +553,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) { return Ok(trait_ref.map_bound(|trait_ref| { ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - trait_ref: trait_ref, - item_name: binding.item_name, - }, + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + binding.item_name, + ), ty: binding.ty, } })); @@ -575,10 +576,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Ok(candidate.map_bound(|trait_ref| { ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - trait_ref: trait_ref, - item_name: binding.item_name, - }, + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + binding.item_name, + ), ty: binding.ty, } })) @@ -652,7 +654,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let p = b.projection_ty; ty::ExistentialProjection { trait_ref: self.trait_ref_to_existential(p.trait_ref), - item_name: p.item_name, + item_name: p.item_name(tcx), ty: b.ty } }) @@ -679,7 +681,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { for projection_bound in &projection_bounds { let pair = (projection_bound.0.projection_ty.trait_ref.def_id, - projection_bound.0.projection_ty.item_name); + projection_bound.0.projection_ty.item_name(tcx)); associated_types.remove(&pair); } diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index f03451c04ed00..7d3a63263edbf 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -124,10 +124,11 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { } let normalized = traits::normalize_projection_type(&mut selcx, - ty::ProjectionTy { - trait_ref: trait_ref, - item_name: Symbol::intern("Target"), - }, + ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + Symbol::intern("Target"), + ), cause, 0); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b29bf01ba1996..fd26ff65661ca 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1651,8 +1651,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { declared_bounds, projection_ty); // see the extensive comment in projection_must_outlive - - let ty = self.tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name); + let item_name = projection_ty.item_name(self.tcx); + let ty = self.tcx.mk_projection(projection_ty.trait_ref, item_name); let recursive_bound = self.recursive_type_bound(span, ty); VerifyBound::AnyRegion(declared_bounds).or(recursive_bound) @@ -1718,9 +1718,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { { debug!("projection_bounds(projection_ty={:?})", projection_ty); - + let item_name = projection_ty.item_name(self.tcx); let ty = self.tcx.mk_projection(projection_ty.trait_ref.clone(), - projection_ty.item_name); + item_name); // Say we have a projection `>::SomeType`. We are interested // in looking for a trait definition like: @@ -1758,7 +1758,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let (outlives, _) = self.replace_late_bound_regions_with_fresh_var( span, - infer::AssocTypeProjection(projection_ty.item_name), + infer::AssocTypeProjection(projection_ty.item_name(self.tcx)), &outlives); debug!("projection_bounds: outlives={:?} (3)", diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 48d387f812d25..6d11770cffbb4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -955,7 +955,7 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { } }; Type::QPath { - name: self.item_name.clean(cx), + name: self.item_name(cx.tcx).clean(cx), self_type: box self.trait_ref.self_ty().clean(cx), trait_: box trait_ } From 86ea93e83cc0d0dbe59067d0154c6e32e73f094a Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 31 May 2017 18:02:35 +0100 Subject: [PATCH 15/15] rustdoc: Cleanup associated const value rendering Rather than (ab)using Debug for outputting the type in plain text use the alternate format parameter which already does exactly that. This fixes type parameters for example which would output raw HTML. Also cleans up adding parens around references to trait objects. --- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/html/format.rs | 206 ++++++++----------------------- src/librustdoc/html/render.rs | 4 +- src/test/rustdoc/assoc-consts.rs | 18 +++ 4 files changed, 74 insertions(+), 156 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 48d387f812d25..593477b066583 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1487,7 +1487,7 @@ pub struct PolyTrait { /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original /// type out of the AST/TyCtxt given one of these, if more information is needed. Most importantly /// it does not preserve mutability or boxes. -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)] pub enum Type { /// structs/enums/traits (most that'd be an hir::TyPath) ResolvedPath { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 19a863bdc62e1..6111ea073dd19 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -106,16 +106,6 @@ impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> { } } -impl<'a, T: fmt::Debug> fmt::Debug for CommaSep<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for (i, item) in self.0.iter().enumerate() { - if i != 0 { write!(f, ", ")?; } - fmt::Debug::fmt(item, f)?; - } - Ok(()) - } -} - impl<'a> fmt::Display for TyParamBounds<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let &TyParamBounds(bounds) = self; @@ -469,8 +459,7 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> { /// Used when rendering a `ResolvedPath` structure. This invokes the `path` /// rendering function with the necessary arguments for linking to a local path. fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, - print_all: bool, use_absolute: bool, is_not_debug: bool, - need_paren: bool) -> fmt::Result { + print_all: bool, use_absolute: bool) -> fmt::Result { let empty = clean::PathSegment { name: String::new(), params: clean::PathParameters::Parenthesized { @@ -499,13 +488,9 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, } else { root.push_str(&seg.name); root.push_str("/"); - if is_not_debug { - write!(w, "{}::", - root, - seg.name)?; - } else { - write!(w, "{}::", seg.name)?; - } + write!(w, "{}::", + root, + seg.name)?; } } } @@ -517,39 +502,21 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, } } if w.alternate() { - if is_not_debug { - write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?; - } else { - write!(w, "{:?}{}", HRef::new(did, &last.name), last.params)?; - } + write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?; } else { - if is_not_debug { - let path = if use_absolute { - match href(did) { - Some((_, _, fqp)) => format!("{}::{}", - fqp[..fqp.len()-1].join("::"), - HRef::new(did, fqp.last() - .unwrap_or(&String::new()))), - None => format!("{}", HRef::new(did, &last.name)), + let path = if use_absolute { + match href(did) { + Some((_, _, fqp)) => { + format!("{}::{}", + fqp[..fqp.len() - 1].join("::"), + HRef::new(did, fqp.last().unwrap_or(&String::new()))) } - } else { - format!("{}", HRef::new(did, &last.name)) - }; - write!(w, "{}{}{}", if need_paren { "(" } else { "" }, path, last.params)?; + None => format!("{}", HRef::new(did, &last.name)), + } } else { - let path = if use_absolute { - match href(did) { - Some((_, _, fqp)) => format!("{:?}::{:?}", - fqp[..fqp.len()-1].join("::"), - HRef::new(did, fqp.last() - .unwrap_or(&String::new()))), - None => format!("{:?}", HRef::new(did, &last.name)), - } - } else { - format!("{:?}", HRef::new(did, &last.name)) - }; - write!(w, "{}{}{}", if need_paren { "(" } else { "" }, path, last.params)?; - } + format!("{}", HRef::new(did, &last.name)) + }; + write!(w, "{}{}", path, last.params)?; } Ok(()) } @@ -600,17 +567,13 @@ fn primitive_link(f: &mut fmt::Formatter, /// Helper to render type parameters fn tybounds(w: &mut fmt::Formatter, - typarams: &Option>, - need_paren: bool) -> fmt::Result { + typarams: &Option>) -> fmt::Result { match *typarams { Some(ref params) => { for param in params { write!(w, " + ")?; fmt::Display::fmt(param, w)?; } - if need_paren { - write!(w, ")")?; - } Ok(()) } None => Ok(()) @@ -637,30 +600,18 @@ impl<'a> fmt::Display for HRef<'a> { } } -impl<'a> fmt::Debug for HRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.text) - } -} - -fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, - is_not_debug: bool, is_ref: bool) -> fmt::Result { +fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt::Result { match *t { clean::Generic(ref name) => { f.write_str(name) } clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => { // Paths like T::Output and Self::Output should be rendered with all segments - let need_paren = match *typarams { - Some(ref v) => !v.is_empty(), - _ => false, - } && is_ref; - resolved_path(f, did, path, is_generic, use_absolute, is_not_debug, need_paren)?; - tybounds(f, typarams, need_paren) + resolved_path(f, did, path, is_generic, use_absolute)?; + tybounds(f, typarams) } clean::Infer => write!(f, "_"), - clean::Primitive(prim) if is_not_debug => primitive_link(f, prim, prim.as_str()), - clean::Primitive(prim) => write!(f, "{}", prim.as_str()), + clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()), clean::BareFunction(ref decl) => { if f.alternate() { write!(f, "{}{}fn{:#}{:#}", @@ -678,30 +629,26 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, } clean::Tuple(ref typs) => { match &typs[..] { - &[] if is_not_debug => primitive_link(f, PrimitiveType::Tuple, "()"), - &[] => write!(f, "()"), - &[ref one] if is_not_debug => { + &[] => primitive_link(f, PrimitiveType::Tuple, "()"), + &[ref one] => { primitive_link(f, PrimitiveType::Tuple, "(")?; //carry f.alternate() into this display w/o branching manually fmt::Display::fmt(one, f)?; primitive_link(f, PrimitiveType::Tuple, ",)") } - &[ref one] => write!(f, "({:?},)", one), - many if is_not_debug => { + many => { primitive_link(f, PrimitiveType::Tuple, "(")?; fmt::Display::fmt(&CommaSep(&many), f)?; primitive_link(f, PrimitiveType::Tuple, ")") } - many => write!(f, "({:?})", &CommaSep(&many)), } } - clean::Vector(ref t) if is_not_debug => { + clean::Vector(ref t) => { primitive_link(f, PrimitiveType::Slice, "[")?; fmt::Display::fmt(t, f)?; primitive_link(f, PrimitiveType::Slice, "]") } - clean::Vector(ref t) => write!(f, "[{:?}]", t), - clean::FixedVector(ref t, ref s) if is_not_debug => { + clean::FixedVector(ref t, ref s) => { primitive_link(f, PrimitiveType::Array, "[")?; fmt::Display::fmt(t, f)?; if f.alternate() { @@ -712,17 +659,10 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, &format!("; {}]", Escape(s))) } } - clean::FixedVector(ref t, ref s) => { - if f.alternate() { - write!(f, "[{:?}; {}]", t, s) - } else { - write!(f, "[{:?}; {}]", t, Escape(s)) - } - } clean::Never => f.write_str("!"), clean::RawPointer(m, ref t) => { match **t { - clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} if is_not_debug => { + clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { if f.alternate() { primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{}{:#}", RawMutableSpace(m), t)) @@ -731,21 +671,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, &format!("*{}{}", RawMutableSpace(m), t)) } } - clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { - if f.alternate() { - write!(f, "*{}{:#?}", RawMutableSpace(m), t) - } else { - write!(f, "*{}{:?}", RawMutableSpace(m), t) - } - } - _ if is_not_debug => { + _ => { primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{}", RawMutableSpace(m)))?; fmt::Display::fmt(t, f) } - _ => { - write!(f, "*{}{:?}", RawMutableSpace(m), t) - } } } clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => { @@ -757,7 +687,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, match **ty { clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T] match **bt { - clean::Generic(_) if is_not_debug => { + clean::Generic(_) => { if f.alternate() { primitive_link(f, PrimitiveType::Slice, &format!("&{}{}[{:#}]", lt, m, **bt)) @@ -766,14 +696,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, &format!("&{}{}[{}]", lt, m, **bt)) } } - clean::Generic(_) => { - if f.alternate() { - write!(f, "&{}{}[{:#?}]", lt, m, **bt) - } else { - write!(f, "&{}{}[{:?}]", lt, m, **bt) - } - } - _ if is_not_debug => { + _ => { if f.alternate() { primitive_link(f, PrimitiveType::Slice, &format!("&{}{}[", lt, m))?; @@ -785,26 +708,25 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, } primitive_link(f, PrimitiveType::Slice, "]") } - _ => { - if f.alternate() { - write!(f, "&{}{}[{:#?}]", lt, m, **bt) - } else { - write!(f, "&{}{}[{:?}]", lt, m, **bt) - } - } } } + clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => { + if f.alternate() { + write!(f, "&{}{}", lt, m)?; + } else { + write!(f, "&{}{}", lt, m)?; + } + write!(f, "(")?; + fmt_type(&ty, f, use_absolute)?; + write!(f, ")") + } _ => { if f.alternate() { write!(f, "&{}{}", lt, m)?; - fmt_type(&ty, f, use_absolute, is_not_debug, true) + fmt_type(&ty, f, use_absolute) } else { - if is_not_debug { - write!(f, "&{}{}", lt, m)?; - } else { - write!(f, "&{}{}", lt, m)?; - } - fmt_type(&ty, f, use_absolute, is_not_debug, true) + write!(f, "&{}{}", lt, m)?; + fmt_type(&ty, f, use_absolute) } } } @@ -833,32 +755,16 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, _ => true, }; if f.alternate() { - if is_not_debug { - if should_show_cast { - write!(f, "<{:#} as {:#}>::", self_type, trait_)? - } else { - write!(f, "{:#}::", self_type)? - } + if should_show_cast { + write!(f, "<{:#} as {:#}>::", self_type, trait_)? } else { - if should_show_cast { - write!(f, "<{:#?} as {:#?}>::", self_type, trait_)? - } else { - write!(f, "{:#?}::", self_type)? - } + write!(f, "{:#}::", self_type)? } } else { - if is_not_debug { - if should_show_cast { - write!(f, "<{} as {}>::", self_type, trait_)? - } else { - write!(f, "{}::", self_type)? - } + if should_show_cast { + write!(f, "<{} as {}>::", self_type, trait_)? } else { - if should_show_cast { - write!(f, "<{:?} as {:?}>::", self_type, trait_)? - } else { - write!(f, "{:?}::", self_type)? - } + write!(f, "{}::", self_type)? } }; match *trait_ { @@ -874,7 +780,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, // look at). box clean::ResolvedPath { did, ref typarams, .. } => { let path = clean::Path::singleton(name.clone()); - resolved_path(f, did, &path, true, use_absolute, is_not_debug, false)?; + resolved_path(f, did, &path, true, use_absolute)?; // FIXME: `typarams` are not rendered, and this seems bad? drop(typarams); @@ -893,13 +799,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool, impl fmt::Display for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt_type(self, f, false, true, false) - } -} - -impl fmt::Debug for clean::Type { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt_type(self, f, false, false, false) + fmt_type(self, f, false) } } @@ -933,7 +833,7 @@ fn fmt_impl(i: &clean::Impl, write!(f, " for ")?; } - fmt_type(&i.for_, f, use_absolute, true, false)?; + fmt_type(&i.for_, f, use_absolute)?; fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?; Ok(()) @@ -1139,7 +1039,7 @@ impl fmt::Display for clean::Import { impl fmt::Display for clean::ImportSource { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.did { - Some(did) => resolved_path(f, did, &self.path, true, false, true, false), + Some(did) => resolved_path(f, did, &self.path, true, false), _ => { for (i, seg) in self.path.segments.iter().enumerate() { if i > 0 { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index fa9315054a11f..a588460d467d2 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1662,9 +1662,9 @@ fn md_render_assoc_item(item: &clean::Item) -> String { match item.inner { clean::AssociatedConstItem(ref ty, ref default) => { if let Some(default) = default.as_ref() { - format!("```\n{}: {:?} = {}\n```\n\n", item.name.as_ref().unwrap(), ty, default) + format!("```\n{}: {:#} = {}\n```\n\n", item.name.as_ref().unwrap(), ty, default) } else { - format!("```\n{}: {:?}\n```\n\n", item.name.as_ref().unwrap(), ty) + format!("```\n{}: {:#}\n```\n\n", item.name.as_ref().unwrap(), ty) } } _ => String::new(), diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs index d4119f5d351c1..04709407e58a8 100644 --- a/src/test/rustdoc/assoc-consts.rs +++ b/src/test/rustdoc/assoc-consts.rs @@ -26,3 +26,21 @@ impl Bar { // @has - '//*[@class="docblock"]' 'BAR: usize = 3' pub const BAR: usize = 3; } + +pub struct Baz<'a, U: 'a, T>(T, &'a [U]); + +impl Bar { + // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.BAZ"]' \ + // "const BAZ: Baz<'static, u8, u32>" + // @has - '//*[@class="docblock"]' "BAZ: Baz<'static, u8, u32> = Baz(321, &[1, 2, 3])" + pub const BAZ: Baz<'static, u8, u32> = Baz(321, &[1, 2, 3]); +} + +pub fn f(_: &(ToString + 'static)) {} + +impl Bar { + // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \ + // "const F: fn(_: &(ToString + 'static))" + // @has - '//*[@class="docblock"]' "F: fn(_: &(ToString + 'static)) = f" + pub const F: fn(_: &(ToString + 'static)) = f; +}