From ecde1e1d3b077f22f75ad34e12e35eef0b6c85f3 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 7 May 2017 00:14:04 -0700 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 a333be7cfecbbe9a659f4f180978fa4dd74d455d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 May 2017 18:46:29 +0200 Subject: [PATCH 06/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 caecb76f08e1365fe245118c7caa4f6add0f95f5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 21 May 2017 14:11:08 +0300 Subject: [PATCH 07/15] Turn sufficiently old compatibility lints into hard errors --- src/librustc/lint/builtin.rs | 65 ----------------- src/librustc_const_eval/pattern.rs | 21 ++---- src/librustc_lint/lib.rs | 73 ++++++++----------- src/librustc_passes/ast_validation.rs | 25 ++----- src/librustc_resolve/lib.rs | 17 ++--- src/librustc_resolve/resolve_imports.rs | 25 ++----- src/librustc_typeck/collect.rs | 9 +-- src/libsyntax/test.rs | 8 -- .../bound-lifetime-constrained.rs | 1 - .../bound-lifetime-in-return-only.rs | 1 - .../compile-fail/extern-crate-visibility.rs | 6 -- .../future-incompatible-lint-group.rs} | 19 ++--- .../generic-impl-less-params-with-defaults.rs | 2 +- .../generic-impl-more-params-with-defaults.rs | 2 +- src/test/compile-fail/issue-1920-1.rs | 2 +- src/test/compile-fail/issue-1920-3.rs | 2 +- src/test/compile-fail/issue-6804.rs | 2 - src/test/compile-fail/lifetime-underscore.rs | 4 - src/test/compile-fail/match-argm-statics-2.rs | 2 + .../restricted/struct-literal-field.rs | 1 - .../compile-fail/privacy/restricted/test.rs | 1 - .../compile-fail/private-in-public-lint.rs | 2 - ...eexport.rs => private-variant-reexport.rs} | 11 --- .../pub-reexport-priv-extern-crate.rs | 31 ++++++++ src/test/compile-fail/resolve-self-in-impl.rs | 1 - src/test/compile-fail/rfc1445/feature-gate.rs | 3 +- .../rfc1445/match-forbidden-without-eq.rs | 5 -- .../match-requires-both-partialeq-and-eq.rs | 4 - .../type-parameter-invalid-lint.rs | 5 -- .../compile-fail/use-super-global-path.rs | 2 - 30 files changed, 102 insertions(+), 250 deletions(-) rename src/test/{run-pass/issue-37020.rs => compile-fail/future-incompatible-lint-group.rs} (62%) rename src/test/compile-fail/{private-variant-and-crate-reexport.rs => private-variant-reexport.rs} (73%) create mode 100644 src/test/compile-fail/pub-reexport-priv-extern-crate.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 0bc1be70174e6..5a88731f16c38 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -130,68 +130,12 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation" } -declare_lint! { - pub INACCESSIBLE_EXTERN_CRATE, - Deny, - "use of inaccessible extern crate erroneously allowed" -} - -declare_lint! { - pub INVALID_TYPE_PARAM_DEFAULT, - Deny, - "type parameter default erroneously allowed in invalid location" -} - -declare_lint! { - pub ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN, - Deny, - "floating-point constants cannot be used in patterns" -} - -declare_lint! { - pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN, - Deny, - "constants of struct or enum type can only be used in a pattern if \ - the struct or enum has `#[derive(PartialEq, Eq)]`" -} - -declare_lint! { - pub RAW_POINTER_DERIVE, - Warn, - "uses of #[derive] with raw pointers are rarely correct" -} - -declare_lint! { - pub HR_LIFETIME_IN_ASSOC_TYPE, - Deny, - "binding for associated type references higher-ranked lifetime \ - that does not appear in the trait input types" -} - -declare_lint! { - pub OVERLAPPING_INHERENT_IMPLS, - Deny, - "two overlapping inherent impls define an item with the same name were erroneously allowed" -} - declare_lint! { pub RENAMED_AND_REMOVED_LINTS, Warn, "lints that have been renamed or removed" } -declare_lint! { - pub SUPER_OR_SELF_IN_GLOBAL_PATH, - Deny, - "detects super or self keywords at the beginning of global path" -} - -declare_lint! { - pub LIFETIME_UNDERSCORE, - Deny, - "lifetimes or labels named `'_` were erroneously allowed" -} - declare_lint! { pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT, Warn, @@ -280,17 +224,8 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, - INACCESSIBLE_EXTERN_CRATE, - INVALID_TYPE_PARAM_DEFAULT, - ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN, - ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN, CONST_ERR, - RAW_POINTER_DERIVE, - OVERLAPPING_INHERENT_IMPLS, RENAMED_AND_REMOVED_LINTS, - SUPER_OR_SELF_IN_GLOBAL_PATH, - HR_LIFETIME_IN_ASSOC_TYPE, - LIFETIME_UNDERSCORE, RESOLVE_TRAIT_ON_DEFAULTED_UNIT, SAFE_EXTERN_STATICS, PATTERNS_IN_FNS_WITHOUT_BODY, diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index e15d63a63c258..a2e0bb80d23dd 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -10,7 +10,6 @@ use eval; -use rustc::lint; use rustc::middle::const_val::{ConstEvalErr, ConstVal}; use rustc::mir::{Field, BorrowKind, Mutability}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, TypeVariants, Region}; @@ -644,11 +643,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { debug!("expr={:?} pat_ty={:?} pat_id={}", expr, pat_ty, pat_id); match pat_ty.sty { ty::TyFloat(_) => { - self.tcx.sess.add_lint( - lint::builtin::ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN, - pat_id, - span, - format!("floating point constants cannot be used in patterns")); + self.tcx.sess.span_err(span, "floating point constants cannot be used in patterns"); } ty::TyAdt(adt_def, _) if adt_def.is_union() => { // Matching on union fields is unsafe, we can't hide it in constants @@ -656,15 +651,11 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } ty::TyAdt(adt_def, _) => { if !self.tcx.has_attr(adt_def.did, "structural_match") { - self.tcx.sess.add_lint( - lint::builtin::ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN, - pat_id, - span, - format!("to use a constant of type `{}` \ - in a pattern, \ - `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - self.tcx.item_path_str(adt_def.did), - self.tcx.item_path_str(adt_def.did))); + let msg = format!("to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + self.tcx.item_path_str(adt_def.did), + self.tcx.item_path_str(adt_def.did)); + self.tcx.sess.span_err(span, &msg); } } _ => { } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d8f29768ccd67..a5b1d39dd869e 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -179,7 +179,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // - Create a lint defaulting to warn as normal, with ideally the same error // message you would normally give // - Add a suitable reference, typically an RFC or tracking issue. Go ahead - // and include the full URL. + // and include the full URL, sort items in ascending order of issue numbers. // - Later, change lint to error // - Eventually, remove lint store.register_future_incompatible(sess, @@ -189,48 +189,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #34537 ", }, FutureIncompatibleInfo { - id: LintId::of(INACCESSIBLE_EXTERN_CRATE), - reference: "issue #36886 ", - }, - FutureIncompatibleInfo { - id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), - reference: "issue #36887 ", - }, - FutureIncompatibleInfo { - id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH), - reference: "issue #36888 ", - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN), - reference: "issue #36890 ", - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), - reference: "issue #41620 ", - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN), - reference: "issue #36891 ", - }, - FutureIncompatibleInfo { - id: LintId::of(HR_LIFETIME_IN_ASSOC_TYPE), - reference: "issue #33685 ", - }, - FutureIncompatibleInfo { - id: LintId::of(LIFETIME_UNDERSCORE), - reference: "issue #36892 ", - }, - FutureIncompatibleInfo { - id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT), - reference: "issue #39216 ", + id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), + reference: "issue #35203 ", }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), - reference: "issue #36247 ", - }, - FutureIncompatibleInfo { - id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), - reference: "issue #35203 ", + reference: "issue #36247 ", }, FutureIncompatibleInfo { id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL), @@ -248,18 +212,26 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), reference: "issue #39207 ", }, + FutureIncompatibleInfo { + id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT), + reference: "issue #39216 ", + }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", }, FutureIncompatibleInfo { - id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), - reference: "issue #42238 ", + id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), + reference: "issue #41620 ", }, FutureIncompatibleInfo { id: LintId::of(ANONYMOUS_PARAMETERS), reference: "issue #41686 ", }, + FutureIncompatibleInfo { + id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), + reference: "issue #42238 ", + } ]); // Register renamed and removed lints @@ -275,5 +247,20 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_removed("drop_with_repr_extern", "drop flags have been removed"); store.register_removed("transmute_from_fn_item_types", "always cast functions before transmuting them"); - store.register_removed("overlapping_inherent_impls", "converted into hard error, see #36889"); + store.register_removed("hr_lifetime_in_assoc_type", + "converted into hard error, see https://github.com/rust-lang/rust/issues/33685"); + store.register_removed("inaccessible_extern_crate", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36886"); + store.register_removed("invalid_type_param_default", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36887"); + store.register_removed("super_or_self_in_global_path", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36888"); + store.register_removed("overlapping_inherent_impls", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36889"); + store.register_removed("illegal_floating_point_constant_pattern", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36890"); + store.register_removed("illegal_struct_or_enum_constant_pattern", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36891"); + store.register_removed("lifetime_underscore", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36892"); } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 79d90210d47f7..7c443a4ac7520 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -36,16 +36,10 @@ impl<'a> AstValidator<'a> { &self.session.parse_sess.span_diagnostic } - fn check_label(&self, label: Ident, span: Span, id: NodeId) { - if label.name == keywords::StaticLifetime.name() { + fn check_label(&self, label: Ident, span: Span) { + if label.name == keywords::StaticLifetime.name() || label.name == "'_" { self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name)); } - if label.name == "'_" { - self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE, - id, - span, - format!("invalid label name `{}`", label.name)); - } } fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) { @@ -104,10 +98,7 @@ impl<'a> AstValidator<'a> { impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_lifetime(&mut self, lt: &'a Lifetime) { if lt.ident.name == "'_" { - self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE, - lt.id, - lt.span, - format!("invalid lifetime name `{}`", lt.ident)); + self.err_handler().span_err(lt.span, &format!("invalid lifetime name `{}`", lt.ident)); } visit::walk_lifetime(self, lt) @@ -121,7 +112,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ExprKind::ForLoop(.., Some(ident)) | ExprKind::Break(Some(ident), _) | ExprKind::Continue(Some(ident)) => { - self.check_label(ident.node, ident.span, expr.id); + self.check_label(ident.node, ident.span); } _ => {} } @@ -169,14 +160,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_ty(self, ty) } - fn visit_path(&mut self, path: &'a Path, id: NodeId) { + fn visit_path(&mut self, path: &'a Path, _: NodeId) { if path.segments.len() >= 2 && path.is_global() { let ident = path.segments[1].identifier; if token::Ident(ident).is_path_segment_keyword() { - self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH, - id, - path.span, - format!("global paths cannot start with `{}`", ident)); + self.err_handler() + .span_err(path.span, &format!("global paths cannot start with `{}`", ident)); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f1be821d526e1..a40c191f7bd29 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1069,6 +1069,10 @@ impl<'a> NameBinding<'a> { _ => false, } } + + fn descr(&self) -> &'static str { + if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() } + } } /// Interns the names of the primitive types. @@ -3424,18 +3428,7 @@ impl<'a> Resolver<'a> { for &PrivacyError(span, name, binding) in &self.privacy_errors { if !reported_spans.insert(span) { continue } - if binding.is_extern_crate() { - // Warn when using an inaccessible extern crate. - let node_id = match binding.kind { - NameBindingKind::Import { directive, .. } => directive.id, - _ => unreachable!(), - }; - let msg = format!("extern crate `{}` is private", name); - self.session.add_lint(lint::builtin::INACCESSIBLE_EXTERN_CRATE, node_id, span, msg); - } else { - let def = binding.def(); - self.session.span_err(span, &format!("{} `{}` is private", def.kind_name(), name)); - } + self.session.span_err(span, &format!("{} `{}` is private", binding.descr(), name)); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index c077f507932c6..8745e51f5b45a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -18,7 +18,6 @@ use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc::ty; -use rustc::lint::builtin::PRIVATE_IN_PUBLIC; use rustc::hir::def_id::DefId; use rustc::hir::def::*; use rustc::util::nodemap::FxHashMap; @@ -295,8 +294,7 @@ impl<'a> Resolver<'a> { // return the corresponding binding defined by the import directive. pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) -> &'a NameBinding<'a> { - let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || - !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC` + let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) { directive.vis.get() } else { binding.pseudo_vis() @@ -720,13 +718,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // All namespaces must be re-exported with extra visibility for an error to occur. if !any_successful_reexport { - let (ns, binding) = reexport_error.unwrap(); - if ns == TypeNS && binding.is_extern_crate() { - let msg = format!("extern crate `{}` is private, and cannot be reexported \ - (error E0364), consider declaring with `pub`", - ident); - self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg); - } else if ns == TypeNS { + if reexport_error.unwrap().0 == TypeNS { struct_span_err!(self.session, directive.span, E0365, "`{}` is private, and cannot be reexported", ident) .span_label(directive.span, format!("reexport of private `{}`", ident)) @@ -792,8 +784,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.record_def(directive.id, PathResolution::new(module.def().unwrap())); } - // Miscellaneous post-processing, including recording reexports, reporting conflicts, - // reporting the PRIVATE_IN_PUBLIC lint, and reporting unresolved imports. + // Miscellaneous post-processing, including recording reexports, + // reporting conflicts, and reporting unresolved imports. fn finalize_resolutions_in(&mut self, module: Module<'b>) { // Since import resolution is finished, globs will not define any more names. *module.globs.borrow_mut() = Vec::new(); @@ -838,13 +830,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } match binding.kind { - NameBindingKind::Import { binding: orig_binding, directive, .. } => { + NameBindingKind::Import { binding: orig_binding, .. } => { if ns == TypeNS && orig_binding.is_variant() && !orig_binding.vis.is_at_least(binding.vis, &*self) { - let msg = format!("variant `{}` is private, and cannot be reexported \ - (error E0364), consider declaring its enum as `pub`", - ident); - self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg); + let msg = format!("variant `{}` is private, and cannot be reexported, \ + consider declaring its enum as `pub`", ident); + self.session.span_err(binding.span, &msg); } } NameBindingKind::Ambiguity { b1, b2, .. } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fb3bcd31e21fc..d7813efdd2fba 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -54,7 +54,6 @@ There are some shortcomings in this design: */ use astconv::{AstConv, Bounds}; -use lint; use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; @@ -897,12 +896,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if !allow_defaults && p.default.is_some() { if !tcx.sess.features.borrow().default_type_parameter_fallback { - tcx.sess.add_lint( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - p.id, - p.span, - format!("defaults for type parameters are only allowed in `struct`, \ - `enum`, `type`, or `trait` definitions.")); + tcx.sess.span_err(p.span, "defaults for type parameters are only allowed in \ + `struct`, `enum`, `type`, or `trait` definitions."); } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 837c3eb0100c6..a0d1785c6ff14 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -231,20 +231,12 @@ fn mk_reexport_mod(cx: &mut TestCtxt, -> (P, Ident) { let super_ = Ident::from_str("super"); - // Generate imports with `#[allow(private_in_public)]` to work around issue #36768. - let allow_private_in_public = cx.ext_cx.attribute(DUMMY_SP, cx.ext_cx.meta_list( - DUMMY_SP, - Symbol::intern("allow"), - vec![cx.ext_cx.meta_list_item_word(DUMMY_SP, Symbol::intern("private_in_public"))], - )); let items = tests.into_iter().map(|r| { cx.ext_cx.item_use_simple(DUMMY_SP, ast::Visibility::Public, cx.ext_cx.path(DUMMY_SP, vec![super_, r])) - .map_attrs(|_| vec![allow_private_in_public.clone()]) }).chain(tested_submods.into_iter().map(|(r, sym)| { let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]); cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Visibility::Public, r, path) - .map_attrs(|_| vec![allow_private_in_public.clone()]) })).collect(); let reexport_mod = ast::Mod { diff --git a/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs b/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs index 7d04372088b76..9ba5045f2a053 100644 --- a/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs +++ b/src/test/compile-fail/associated-types/bound-lifetime-constrained.rs @@ -12,7 +12,6 @@ #![allow(dead_code)] #![feature(rustc_attrs)] -#![allow(hr_lifetime_in_assoc_type)] trait Foo<'a> { type Item; diff --git a/src/test/compile-fail/associated-types/bound-lifetime-in-return-only.rs b/src/test/compile-fail/associated-types/bound-lifetime-in-return-only.rs index 7c1fbfa53d965..b9b1317cef50f 100644 --- a/src/test/compile-fail/associated-types/bound-lifetime-in-return-only.rs +++ b/src/test/compile-fail/associated-types/bound-lifetime-in-return-only.rs @@ -13,7 +13,6 @@ #![allow(dead_code)] #![feature(rustc_attrs)] #![feature(unboxed_closures)] -#![deny(hr_lifetime_in_assoc_type)] trait Foo { type Item; diff --git a/src/test/compile-fail/extern-crate-visibility.rs b/src/test/compile-fail/extern-crate-visibility.rs index 81e0cb249f382..6bb88e409105a 100644 --- a/src/test/compile-fail/extern-crate-visibility.rs +++ b/src/test/compile-fail/extern-crate-visibility.rs @@ -8,21 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(unused)] - mod foo { extern crate core; } // Check that private crates can be used from outside their modules, albeit with warnings -use foo::core; //~ WARN extern crate `core` is private -//~^ WARN this was previously accepted by the compiler but is being phased out use foo::core::cell; //~ ERROR extern crate `core` is private -//~^ WARN this was previously accepted by the compiler but is being phased out fn f() { foo::core::cell::Cell::new(0); //~ ERROR extern crate `core` is private - //~^ WARN this was previously accepted by the compiler but is being phased out use foo::*; mod core {} // Check that private crates are not glob imported diff --git a/src/test/run-pass/issue-37020.rs b/src/test/compile-fail/future-incompatible-lint-group.rs similarity index 62% rename from src/test/run-pass/issue-37020.rs rename to src/test/compile-fail/future-incompatible-lint-group.rs index 7d0d20269aba7..e6a39f95e660d 100644 --- a/src/test/run-pass/issue-37020.rs +++ b/src/test/compile-fail/future-incompatible-lint-group.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,18 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(private_in_public)] +#![deny(future_incompatible)] -mod foo { - pub mod bar { - extern crate core; - } +trait Tr { + fn f(u8) {} //~ ERROR use of deprecated anonymous parameter + //~^ WARN this was previously accepted } -mod baz { - pub use foo::bar::core; -} - -fn main() { - baz::core::cell::Cell::new(0u32); -} +fn main() {} diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs index 5fa429445a35e..3f5f7bb3a53ea 100644 --- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs @@ -13,7 +13,7 @@ use std::marker; struct Foo( marker::PhantomData<(A,B,C)>); -impl Foo { +impl Foo { fn new() -> Foo {Foo(marker::PhantomData)} } diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs index d3babb8982ddc..3141199208965 100644 --- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs @@ -15,7 +15,7 @@ struct Heap; struct Vec( marker::PhantomData<(T,A)>); -impl Vec { +impl Vec { fn new() -> Vec {Vec(marker::PhantomData)} } diff --git a/src/test/compile-fail/issue-1920-1.rs b/src/test/compile-fail/issue-1920-1.rs index 8fbe4432204a4..f829d4645a089 100644 --- a/src/test/compile-fail/issue-1920-1.rs +++ b/src/test/compile-fail/issue-1920-1.rs @@ -11,7 +11,7 @@ //! Test that absolute path names are correct when a crate is not linked into the root namespace mod foo { - extern crate core; + pub extern crate core; } fn assert_clone() where T : Clone { } diff --git a/src/test/compile-fail/issue-1920-3.rs b/src/test/compile-fail/issue-1920-3.rs index dfec48e0a83c1..2f5da907b95f6 100644 --- a/src/test/compile-fail/issue-1920-3.rs +++ b/src/test/compile-fail/issue-1920-3.rs @@ -11,7 +11,7 @@ //! Test that when a crate is linked multiple times that the shortest absolute path name is used mod foo { - extern crate core; + pub extern crate core; } extern crate core; diff --git a/src/test/compile-fail/issue-6804.rs b/src/test/compile-fail/issue-6804.rs index f7d3ce60c66cc..2a97945f26648 100644 --- a/src/test/compile-fail/issue-6804.rs +++ b/src/test/compile-fail/issue-6804.rs @@ -19,13 +19,11 @@ fn main() { let x = NAN; match x { NAN => {}, //~ ERROR floating point constants cannot be used - //~| WARNING hard error _ => {}, }; match [x, 1.0] { [NAN, _] => {}, //~ ERROR floating point constants cannot be used - //~| WARNING hard error _ => {}, }; } diff --git a/src/test/compile-fail/lifetime-underscore.rs b/src/test/compile-fail/lifetime-underscore.rs index b768009132ca9..5b518a4931da8 100644 --- a/src/test/compile-fail/lifetime-underscore.rs +++ b/src/test/compile-fail/lifetime-underscore.rs @@ -9,17 +9,13 @@ // except according to those terms. fn _f<'_>() //~ ERROR invalid lifetime name `'_` -//~^ WARN this was previously accepted -> &'_ u8 //~ ERROR invalid lifetime name `'_` - //~^ WARN this was previously accepted { panic!(); } fn main() { '_: loop { //~ ERROR invalid label name `'_` - //~^ WARN this was previously accepted break '_ //~ ERROR invalid label name `'_` - //~^ WARN this was previously accepted } } diff --git a/src/test/compile-fail/match-argm-statics-2.rs b/src/test/compile-fail/match-argm-statics-2.rs index 40dcf3d0f12cc..70e148627c47e 100644 --- a/src/test/compile-fail/match-argm-statics-2.rs +++ b/src/test/compile-fail/match-argm-statics-2.rs @@ -10,8 +10,10 @@ use self::Direction::{North, East, South, West}; +#[derive(PartialEq, Eq)] struct NewBool(bool); +#[derive(PartialEq, Eq)] enum Direction { North, East, diff --git a/src/test/compile-fail/privacy/restricted/struct-literal-field.rs b/src/test/compile-fail/privacy/restricted/struct-literal-field.rs index 68458fe3f04ba..21d90dfea4b6c 100644 --- a/src/test/compile-fail/privacy/restricted/struct-literal-field.rs +++ b/src/test/compile-fail/privacy/restricted/struct-literal-field.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(private_in_public)] #![allow(warnings)] mod foo { diff --git a/src/test/compile-fail/privacy/restricted/test.rs b/src/test/compile-fail/privacy/restricted/test.rs index 12697d51042ed..2e065ac051b20 100644 --- a/src/test/compile-fail/privacy/restricted/test.rs +++ b/src/test/compile-fail/privacy/restricted/test.rs @@ -10,7 +10,6 @@ // aux-build:pub_restricted.rs -#![deny(private_in_public)] #![allow(warnings)] extern crate pub_restricted; diff --git a/src/test/compile-fail/private-in-public-lint.rs b/src/test/compile-fail/private-in-public-lint.rs index 030fbfc491449..fd92300cd1526 100644 --- a/src/test/compile-fail/private-in-public-lint.rs +++ b/src/test/compile-fail/private-in-public-lint.rs @@ -18,8 +18,6 @@ mod m1 { } mod m2 { - #![deny(future_incompatible)] - pub struct Pub; struct Priv; diff --git a/src/test/compile-fail/private-variant-and-crate-reexport.rs b/src/test/compile-fail/private-variant-reexport.rs similarity index 73% rename from src/test/compile-fail/private-variant-and-crate-reexport.rs rename to src/test/compile-fail/private-variant-reexport.rs index dce533e73feea..c77a7532e34a2 100644 --- a/src/test/compile-fail/private-variant-and-crate-reexport.rs +++ b/src/test/compile-fail/private-variant-reexport.rs @@ -8,31 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(private_in_public)] -#![allow(dead_code)] - -extern crate core; -pub use core as reexported_core; //~ ERROR extern crate `core` is private, and cannot be reexported -//~^ WARNING hard error - mod m1 { pub use ::E::V; //~ ERROR variant `V` is private, and cannot be reexported - //~^ WARNING hard error } mod m2 { pub use ::E::{V}; //~ ERROR variant `V` is private, and cannot be reexported - //~^ WARNING hard error } mod m3 { pub use ::E::V::{self}; //~ ERROR variant `V` is private, and cannot be reexported - //~^ WARNING hard error } mod m4 { pub use ::E::*; //~ ERROR variant `V` is private, and cannot be reexported - //~^ WARNING hard error } enum E { V } diff --git a/src/test/compile-fail/pub-reexport-priv-extern-crate.rs b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs new file mode 100644 index 0000000000000..1249ba774a8ba --- /dev/null +++ b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs @@ -0,0 +1,31 @@ +// 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. + +#![allow(unused)] + +extern crate core; +pub use core as reexported_core; //~ ERROR `core` is private, and cannot be reexported + +mod foo1 { + extern crate core; +} + +mod foo2 { + use foo1::core; //~ ERROR `core` is private, and cannot be reexported + pub mod bar { + extern crate core; + } +} + +mod baz { + pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be reexported +} + +fn main() {} diff --git a/src/test/compile-fail/resolve-self-in-impl.rs b/src/test/compile-fail/resolve-self-in-impl.rs index 710d8e11ff034..55ae37404a9fa 100644 --- a/src/test/compile-fail/resolve-self-in-impl.rs +++ b/src/test/compile-fail/resolve-self-in-impl.rs @@ -17,7 +17,6 @@ trait Tr { impl Tr for S {} // OK impl> Tr for S {} // OK -impl Tr for S {} // OK impl Tr for S where Self: Copy {} // OK impl Tr for S where S: Copy {} // OK impl Tr for S where Self::A: Copy {} // OK diff --git a/src/test/compile-fail/rfc1445/feature-gate.rs b/src/test/compile-fail/rfc1445/feature-gate.rs index b51ee3d8b5ed8..f729220eabbc3 100644 --- a/src/test/compile-fail/rfc1445/feature-gate.rs +++ b/src/test/compile-fail/rfc1445/feature-gate.rs @@ -16,8 +16,7 @@ // gate-test-structural_match -#![allow(dead_code)] -#![deny(future_incompatible)] +#![allow(unused)] #![feature(rustc_attrs)] #![cfg_attr(with_gate, feature(structural_match))] diff --git a/src/test/compile-fail/rfc1445/match-forbidden-without-eq.rs b/src/test/compile-fail/rfc1445/match-forbidden-without-eq.rs index c573e3e8e28b2..679be9ce219fe 100644 --- a/src/test/compile-fail/rfc1445/match-forbidden-without-eq.rs +++ b/src/test/compile-fail/rfc1445/match-forbidden-without-eq.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] -#![deny(future_incompatible)] - use std::f32; #[derive(PartialEq)] @@ -25,7 +22,6 @@ fn main() { match y { FOO => { } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` - //~| WARNING will become a hard error _ => { } } @@ -33,7 +29,6 @@ fn main() { match x { f32::INFINITY => { } //~^ ERROR floating point constants cannot be used in patterns - //~| WARNING will become a hard error _ => { } } } diff --git a/src/test/compile-fail/rfc1445/match-requires-both-partialeq-and-eq.rs b/src/test/compile-fail/rfc1445/match-requires-both-partialeq-and-eq.rs index 029df08ebc37a..e02f9153e7ead 100644 --- a/src/test/compile-fail/rfc1445/match-requires-both-partialeq-and-eq.rs +++ b/src/test/compile-fail/rfc1445/match-requires-both-partialeq-and-eq.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] -#![deny(future_incompatible)] - #[derive(Eq)] struct Foo { x: u32 @@ -29,7 +26,6 @@ fn main() { match y { FOO => { } //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` - //~| WARNING will become a hard error _ => { } } } diff --git a/src/test/compile-fail/type-parameter-invalid-lint.rs b/src/test/compile-fail/type-parameter-invalid-lint.rs index a2c8116c9ba1c..eea6f22644b69 100644 --- a/src/test/compile-fail/type-parameter-invalid-lint.rs +++ b/src/test/compile-fail/type-parameter-invalid-lint.rs @@ -10,16 +10,11 @@ // gate-test-default_type_parameter_fallback -#![deny(future_incompatible)] -#![allow(dead_code)] - fn avg(_: T) {} //~^ ERROR defaults for type parameters are only allowed -//~| WARNING hard error struct S(T); impl S {} //~^ ERROR defaults for type parameters are only allowed -//~| WARNING hard error fn main() {} diff --git a/src/test/compile-fail/use-super-global-path.rs b/src/test/compile-fail/use-super-global-path.rs index 3fa0712fb4ca3..4162e037cf32e 100644 --- a/src/test/compile-fail/use-super-global-path.rs +++ b/src/test/compile-fail/use-super-global-path.rs @@ -15,11 +15,9 @@ struct Z; mod foo { use ::super::{S, Z}; //~ ERROR global paths cannot start with `super` - //~^ WARN this was previously accepted by the compiler but is being phased out pub fn g() { use ::super::main; //~ ERROR global paths cannot start with `super` - //~^ WARN this was previously accepted by the compiler but is being phased out main(); } } From d73a0fef381f5c6f4720c152bb7235fe02e502fd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 21 May 2017 15:50:38 +0300 Subject: [PATCH 08/15] Turn public reexporting of private extern crates into a lint again --- src/librustc_resolve/resolve_imports.rs | 12 ++++++++++-- .../compile-fail/pub-reexport-priv-extern-crate.rs | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 8745e51f5b45a..a892f9df6a646 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -18,6 +18,7 @@ use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc::ty; +use rustc::lint::builtin::PRIVATE_IN_PUBLIC; use rustc::hir::def_id::DefId; use rustc::hir::def::*; use rustc::util::nodemap::FxHashMap; @@ -294,7 +295,8 @@ impl<'a> Resolver<'a> { // return the corresponding binding defined by the import directive. pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) -> &'a NameBinding<'a> { - let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) { + let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || + !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC` directive.vis.get() } else { binding.pseudo_vis() @@ -718,7 +720,13 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // All namespaces must be re-exported with extra visibility for an error to occur. if !any_successful_reexport { - if reexport_error.unwrap().0 == TypeNS { + let (ns, binding) = reexport_error.unwrap(); + if ns == TypeNS && binding.is_extern_crate() { + let msg = format!("extern crate `{}` is private, and cannot be reexported \ + (error E0365), consider declaring with `pub`", + ident); + self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg); + } else if ns == TypeNS { struct_span_err!(self.session, directive.span, E0365, "`{}` is private, and cannot be reexported", ident) .span_label(directive.span, format!("reexport of private `{}`", ident)) diff --git a/src/test/compile-fail/pub-reexport-priv-extern-crate.rs b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs index 1249ba774a8ba..185da379694bc 100644 --- a/src/test/compile-fail/pub-reexport-priv-extern-crate.rs +++ b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs @@ -9,9 +9,11 @@ // except according to those terms. #![allow(unused)] +#![deny(private_in_public)] extern crate core; pub use core as reexported_core; //~ ERROR `core` is private, and cannot be reexported + //~^ WARN this was previously accepted mod foo1 { extern crate core; @@ -19,6 +21,7 @@ mod foo1 { mod foo2 { use foo1::core; //~ ERROR `core` is private, and cannot be reexported + //~^ WARN this was previously accepted pub mod bar { extern crate core; } @@ -26,6 +29,7 @@ mod foo2 { mod baz { pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be reexported + //~^ WARN this was previously accepted } fn main() {} From 26d5c0e20cbdd27af12a756ddfb1758d0888aad3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 May 2017 01:52:25 +0300 Subject: [PATCH 09/15] Turn `invalid_type_param_default` into a lint again --- src/librustc/lint/builtin.rs | 7 +++++++ src/librustc_lint/lib.rs | 6 ++++-- src/librustc_typeck/collect.rs | 9 +++++++-- src/test/compile-fail/type-parameter-invalid-lint.rs | 5 +++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 5a88731f16c38..736c3b289e198 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -130,6 +130,12 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation" } +declare_lint! { + pub INVALID_TYPE_PARAM_DEFAULT, + Deny, + "type parameter default erroneously allowed in invalid location" +} + declare_lint! { pub RENAMED_AND_REMOVED_LINTS, Warn, @@ -224,6 +230,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, + INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, RESOLVE_TRAIT_ON_DEFAULTED_UNIT, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index a5b1d39dd869e..9870842a28e38 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -196,6 +196,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", }, + FutureIncompatibleInfo { + id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), + reference: "issue #36887 ", + }, FutureIncompatibleInfo { id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL), reference: "issue #37166 ", @@ -251,8 +255,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/33685"); store.register_removed("inaccessible_extern_crate", "converted into hard error, see https://github.com/rust-lang/rust/issues/36886"); - store.register_removed("invalid_type_param_default", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36887"); store.register_removed("super_or_self_in_global_path", "converted into hard error, see https://github.com/rust-lang/rust/issues/36888"); store.register_removed("overlapping_inherent_impls", diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d7813efdd2fba..fb3bcd31e21fc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -54,6 +54,7 @@ There are some shortcomings in this design: */ use astconv::{AstConv, Bounds}; +use lint; use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; @@ -896,8 +897,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if !allow_defaults && p.default.is_some() { if !tcx.sess.features.borrow().default_type_parameter_fallback { - tcx.sess.span_err(p.span, "defaults for type parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions."); + tcx.sess.add_lint( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + p.id, + p.span, + format!("defaults for type parameters are only allowed in `struct`, \ + `enum`, `type`, or `trait` definitions.")); } } diff --git a/src/test/compile-fail/type-parameter-invalid-lint.rs b/src/test/compile-fail/type-parameter-invalid-lint.rs index eea6f22644b69..c7a1197372dee 100644 --- a/src/test/compile-fail/type-parameter-invalid-lint.rs +++ b/src/test/compile-fail/type-parameter-invalid-lint.rs @@ -10,11 +10,16 @@ // gate-test-default_type_parameter_fallback +#![deny(invalid_type_param_default)] +#![allow(unused)] + fn avg(_: T) {} //~^ ERROR defaults for type parameters are only allowed +//~| WARN this was previously accepted struct S(T); impl S {} //~^ ERROR defaults for type parameters are only allowed +//~| WARN this was previously accepted fn main() {} From 62989c1a0cf0840315becf2ba0a141b9b3a1c62b Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 30 May 2017 22:21:00 -0700 Subject: [PATCH 10/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 11/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 12/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 13/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 14/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; +} From bcd1fe56c750b2549d633f161280e13dd348a095 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 31 May 2017 23:01:55 -0400 Subject: [PATCH 15/15] Rewrite doc examples for `Receiver::recv_timeout`. --- src/libstd/sync/mpsc/mod.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 69507cada2b4e..744868e2e2396 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1252,14 +1252,43 @@ impl Receiver { /// /// # Examples /// + /// Successfully receiving value before encountering timeout: + /// + /// ```no_run + /// use std::thread; + /// use std::time::Duration; + /// use std::sync::mpsc; + /// + /// let (send, recv) = mpsc::channel(); + /// + /// thread::spawn(move || { + /// send.send('a').unwrap(); + /// }); + /// + /// assert_eq!( + /// recv.recv_timeout(Duration::from_millis(400)), + /// Ok('a') + /// ); + /// ``` + /// + /// Receiving an error upon reaching timeout: + /// /// ```no_run - /// use std::sync::mpsc::{self, RecvTimeoutError}; + /// use std::thread; /// use std::time::Duration; + /// use std::sync::mpsc; + /// + /// let (send, recv) = mpsc::channel(); /// - /// let (send, recv) = mpsc::channel::<()>(); + /// thread::spawn(move || { + /// thread::sleep(Duration::from_millis(800)); + /// send.send('a').unwrap(); + /// }); /// - /// let timeout = Duration::from_millis(100); - /// assert_eq!(Err(RecvTimeoutError::Timeout), recv.recv_timeout(timeout)); + /// assert_eq!( + /// recv.recv_timeout(Duration::from_millis(400)), + /// Err(mpsc::RecvTimeoutError::Timeout) + /// ); /// ``` #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] pub fn recv_timeout(&self, timeout: Duration) -> Result {