Auto merge of #42348 - frewsxcv:rollup, r=frewsxcv
Rollup of 9 pull requests - Successful merges: #42136, #42275, #42286, #42297, #42302, #42306, #42314, #42324, #42347 - Failed merges:
This commit is contained in:
commit
38efb2e1cc
75 changed files with 662 additions and 525 deletions
|
|
@ -914,6 +914,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"));
|
||||
|
|
@ -923,11 +925,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");
|
||||
|
|
@ -941,6 +949,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);
|
||||
|
|
@ -964,6 +974,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))
|
||||
|
|
@ -978,11 +990,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")));
|
||||
|
|
@ -1056,6 +1076,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)
|
||||
|
|
@ -1079,6 +1119,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);
|
||||
|
|
@ -1096,6 +1138,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());
|
||||
|
|
@ -1118,6 +1162,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") {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
50
src/doc/unstable-book/src/library-features/try-trait.md
Normal file
50
src/doc/unstable-book/src/library-features/try-trait.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# `try_trait`
|
||||
|
||||
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<T> ops::Try for Option<T> {
|
||||
type Ok = T;
|
||||
type Error = None;
|
||||
|
||||
fn into_result(self) -> Result<T, None> {
|
||||
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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@
|
|||
<Directory Id="Docs" Name="." />
|
||||
<Directory Id="Cargo" Name="." />
|
||||
<Directory Id="Std" Name="." />
|
||||
<Directory Id="Rls" Name="." />
|
||||
<Directory Id="Analysis" Name="." />
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
|
|
@ -273,6 +275,14 @@
|
|||
<ComponentRef Id="PathEnvPerMachine" />
|
||||
<ComponentRef Id="PathEnvPerUser" />
|
||||
</Feature>
|
||||
<Feature Id="RLS"
|
||||
Title="RLS, the Rust Language Server"
|
||||
Display="7"
|
||||
Level="2"
|
||||
AllowAdvertise="no">
|
||||
<ComponentGroupRef Id="RlsGroup" />
|
||||
<ComponentGroupRef Id="AnalysisGroup" />
|
||||
</Feature>
|
||||
|
||||
<UIRef Id="RustUI" />
|
||||
</Product>
|
||||
|
|
|
|||
|
|
@ -12,59 +12,70 @@
|
|||
</volume-check>
|
||||
<choices-outline>
|
||||
<line choice="install">
|
||||
<line choice="rustc"/>
|
||||
<line choice="rust-std"/>
|
||||
<line choice="cargo"/>
|
||||
<line choice="rust-docs"/>
|
||||
<line choice="rustc"/>
|
||||
<line choice="rust-std"/>
|
||||
<line choice="cargo"/>
|
||||
<line choice="rust-docs"/>
|
||||
<line choice="rls"/>
|
||||
</line>
|
||||
<line choice="uninstall" />
|
||||
</choices-outline>
|
||||
<!--
|
||||
These 'selected' scripts ensure that install and uninstall can never be selected at
|
||||
the same time. Exectly how they work is pretty mysterious, tied to the unspecified algorithm
|
||||
the installer uses to traverse the options after one is toggled.
|
||||
These 'selected' scripts ensure that install and uninstall can never be selected at
|
||||
the same time. Exectly how they work is pretty mysterious, tied to the unspecified algorithm
|
||||
the installer uses to traverse the options after one is toggled.
|
||||
-->
|
||||
<choice id="install" visible="true"
|
||||
title="Install Rust" description="Install the Rust compiler, package manager and documentation."
|
||||
customLocation="/usr/local"
|
||||
selected="!choices.uninstall.selected"
|
||||
/>
|
||||
title="Install Rust" description="Install the Rust compiler, package manager and documentation."
|
||||
customLocation="/usr/local"
|
||||
selected="!choices.uninstall.selected"
|
||||
/>
|
||||
<choice id="uninstall" visible="true"
|
||||
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"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.uninstall" />
|
||||
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"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.uninstall"/>
|
||||
</choice>
|
||||
<choice id="rustc" visible="true"
|
||||
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="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)"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.rustc"/>
|
||||
</choice>
|
||||
<choice id="cargo" visible="true"
|
||||
title="Cargo" description="cargo, the Rust package manager."
|
||||
selected="(!choices.uninstall.selected && choices.cargo.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)"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.cargo"/>
|
||||
</choice>
|
||||
<choice id="rust-std" visible="true"
|
||||
title="Standard Library" description="The Rust standard library."
|
||||
selected="(!choices.uninstall.selected && choices['rust-std'].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)"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.rust-std"/>
|
||||
</choice>
|
||||
<choice id="rust-docs" visible="true"
|
||||
title="Documentation" description="HTML documentation."
|
||||
selected="(!choices.uninstall.selected && choices['rust-docs'].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)"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.rust-docs"/>
|
||||
</choice>
|
||||
<choice id="rls" visible="true"
|
||||
title="RLS" description="RLS, the Rust Language Server"
|
||||
selected="(!choices.uninstall.selected && choices['rls'].selected) || (choices.uninstall.selected && choices.install.selected)"
|
||||
start_selected="false"
|
||||
>
|
||||
<pkg-ref id="org.rust-lang.rls"/>
|
||||
<pkg-ref id="org.rust-lang.rust-analysis"/>
|
||||
</choice>
|
||||
<pkg-ref id="org.rust-lang.rustc" version="0" onConclusion="none">rustc.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.cargo" version="0" onConclusion="none">cargo.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.rust-docs" version="0" onConclusion="none">rust-docs.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.rust-std" version="0" onConclusion="none">rust-std.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.rls" version="0" onConclusion="none">rls.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.rust-analysis" version="0" onConclusion="none">rust-analysis.pkg</pkg-ref>
|
||||
<pkg-ref id="org.rust-lang.uninstall" version="0" onConclusion="none">uninstall.pkg</pkg-ref>
|
||||
<background file="rust-logo.png" mime-type="image/png"
|
||||
alignment="bottomleft"/>
|
||||
|
|
|
|||
|
|
@ -2918,15 +2918,9 @@ pub trait BoxPlace<Data: ?Sized> : Place<Data> {
|
|||
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<T>(self) -> T where T: Carrier<Success=Self::Success, Error=Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
#[unstable(feature = "question_mark_carrier", issue = "31436")]
|
||||
impl<U, V> Carrier for Result<U, V> {
|
||||
type Success = U;
|
||||
|
|
@ -2970,21 +2965,57 @@ impl<U, V> Carrier for Result<U, V> {
|
|||
|
||||
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<Self::Ok, Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn from_ok(_: ()) -> _DummyErrorType {
|
||||
_DummyErrorType
|
||||
}
|
||||
|
||||
fn from_error(_: ()) -> _DummyErrorType {
|
||||
_DummyErrorType
|
||||
}
|
||||
|
||||
fn translate<T>(self) -> T
|
||||
where T: Carrier<Success=(), Error=()>
|
||||
{
|
||||
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 = "42327")]
|
||||
pub trait Try {
|
||||
/// The type of this value when viewed as successful.
|
||||
#[unstable(feature = "try_trait", issue = "42327")]
|
||||
type Ok;
|
||||
/// The type of this value when viewed as failed.
|
||||
#[unstable(feature = "try_trait", issue = "42327")]
|
||||
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 = "42327")]
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// 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 = "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 = "42327")]
|
||||
fn from_ok(v: Self::Ok) -> Self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_trait", issue = "42327")]
|
||||
impl<T,E> ops::Try for Result<T, E> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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<F: Fn()>(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/
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2265,23 +2265,23 @@ impl<'a> LoweringContext<'a> {
|
|||
ExprKind::Try(ref sub_expr) => {
|
||||
// to:
|
||||
//
|
||||
// match Carrier::translate(<expr>) {
|
||||
// match Try::into_result(<expr>) {
|
||||
// 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(<expr>)
|
||||
// Try::into_result(<expr>)
|
||||
let discr = {
|
||||
// expand <expr>
|
||||
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]))
|
||||
};
|
||||
|
|
@ -2327,7 +2327,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]))
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> 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<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,68 +130,18 @@ 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 +230,9 @@ 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,
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -158,14 +158,14 @@ impl Session {
|
|||
pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'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<MultiSpan>>(&'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<MultiSpan>>(&'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<MultiSpan>>(&'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<MultiSpan>>(&'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<MultiSpan>>(&'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> {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1323,7 +1323,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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1051,8 +1051,8 @@ pub struct ProjectionPredicate<'tcx> {
|
|||
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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<ty::ProjectionTy<'tcx>> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
|
|
|
|||
|
|
@ -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<MultiSpan>>(&'a self,
|
||||
sp: S,
|
||||
msg: &str)
|
||||
|
|
|
|||
|
|
@ -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,49 +189,17 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(INACCESSIBLE_EXTERN_CRATE),
|
||||
reference: "issue #36886 <https://github.com/rust-lang/rust/issues/36886>",
|
||||
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
||||
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(SAFE_EXTERN_STATICS),
|
||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
|
||||
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH),
|
||||
reference: "issue #36888 <https://github.com/rust-lang/rust/issues/36888>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN),
|
||||
reference: "issue #36890 <https://github.com/rust-lang/rust/issues/36890>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
|
||||
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN),
|
||||
reference: "issue #36891 <https://github.com/rust-lang/rust/issues/36891>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(HR_LIFETIME_IN_ASSOC_TYPE),
|
||||
reference: "issue #33685 <https://github.com/rust-lang/rust/issues/33685>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(LIFETIME_UNDERSCORE),
|
||||
reference: "issue #36892 <https://github.com/rust-lang/rust/issues/36892>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
|
||||
reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(SAFE_EXTERN_STATICS),
|
||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
||||
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL),
|
||||
reference: "issue #37166 <https://github.com/rust-lang/rust/issues/37166>",
|
||||
|
|
@ -248,18 +216,26 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
|
||||
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
|
||||
reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
|
||||
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
|
||||
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
|
||||
id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
|
||||
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(ANONYMOUS_PARAMETERS),
|
||||
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
|
||||
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
|
||||
}
|
||||
]);
|
||||
|
||||
// Register renamed and removed lints
|
||||
|
|
@ -275,5 +251,18 @@ 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("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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
|||
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`",
|
||||
(error E0365), consider declaring with `pub`",
|
||||
ident);
|
||||
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
|
||||
} else if ns == TypeNS {
|
||||
|
|
@ -792,8 +792,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 +838,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, .. }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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, &[]);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 `<T as SomeTrait<'a>>::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)",
|
||||
|
|
|
|||
|
|
@ -955,7 +955,7 @@ impl<'tcx> Clean<Type> 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_
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<String>)> {
|
|||
/// 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, "<a class=\"mod\" href=\"{}index.html\">{}</a>::",
|
||||
root,
|
||||
seg.name)?;
|
||||
} else {
|
||||
write!(w, "{}::", seg.name)?;
|
||||
}
|
||||
write!(w, "<a class=\"mod\" href=\"{}index.html\">{}</a>::",
|
||||
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<Vec<clean::TyParamBound>>,
|
||||
need_paren: bool) -> fmt::Result {
|
||||
typarams: &Option<Vec<clean::TyParamBound>>) -> 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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -1252,14 +1252,43 @@ impl<T> Receiver<T> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Successfully receiving value before encountering 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();
|
||||
///
|
||||
/// let timeout = Duration::from_millis(100);
|
||||
/// assert_eq!(Err(RecvTimeoutError::Timeout), recv.recv_timeout(timeout));
|
||||
/// 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::thread;
|
||||
/// use std::time::Duration;
|
||||
/// use std::sync::mpsc;
|
||||
///
|
||||
/// let (send, recv) = mpsc::channel();
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// thread::sleep(Duration::from_millis(800));
|
||||
/// send.send('a').unwrap();
|
||||
/// });
|
||||
///
|
||||
/// 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<T, RecvTimeoutError> {
|
||||
|
|
|
|||
|
|
@ -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)*) => ({
|
||||
|
|
|
|||
|
|
@ -231,20 +231,12 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
|
|||
-> (P<ast::Item>, 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 {
|
||||
|
|
|
|||
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T: Foo> Bar for T {
|
||||
const FROM: &'static str = "foo";
|
||||
//~^ ERROR the trait bound `T: Foo` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#![allow(dead_code)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(hr_lifetime_in_assoc_type)]
|
||||
|
||||
trait Foo<'a> {
|
||||
type Item;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#![allow(dead_code)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![deny(hr_lifetime_in_assoc_type)]
|
||||
|
||||
trait Foo {
|
||||
type Item;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -13,7 +13,7 @@ use std::marker;
|
|||
struct Foo<A, B, C = (A, B)>(
|
||||
marker::PhantomData<(A,B,C)>);
|
||||
|
||||
impl<A, B, C = (A, B)> Foo<A, B, C> {
|
||||
impl<A, B, C> Foo<A, B, C> {
|
||||
fn new() -> Foo<A, B, C> {Foo(marker::PhantomData)}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct Heap;
|
|||
struct Vec<T, A = Heap>(
|
||||
marker::PhantomData<(T,A)>);
|
||||
|
||||
impl<T, A = Heap> Vec<T, A> {
|
||||
impl<T, A> Vec<T, A> {
|
||||
fn new() -> Vec<T, A> {Vec(marker::PhantomData)}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<T>() where T : Clone { }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@
|
|||
|
||||
use self::Direction::{North, East, South, West};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct NewBool(bool);
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Direction {
|
||||
North,
|
||||
East,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
// aux-build:pub_restricted.rs
|
||||
|
||||
#![deny(private_in_public)]
|
||||
#![allow(warnings)]
|
||||
extern crate pub_restricted;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ mod m1 {
|
|||
}
|
||||
|
||||
mod m2 {
|
||||
#![deny(future_incompatible)]
|
||||
|
||||
pub struct Pub;
|
||||
struct Priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
35
src/test/compile-fail/pub-reexport-priv-extern-crate.rs
Normal file
35
src/test/compile-fail/pub-reexport-priv-extern-crate.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// 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;
|
||||
}
|
||||
|
||||
mod foo2 {
|
||||
use foo1::core; //~ ERROR `core` is private, and cannot be reexported
|
||||
//~^ WARN this was previously accepted
|
||||
pub mod bar {
|
||||
extern crate core;
|
||||
}
|
||||
}
|
||||
|
||||
mod baz {
|
||||
pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be reexported
|
||||
//~^ WARN this was previously accepted
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -17,7 +17,6 @@ trait Tr<T = u8> {
|
|||
|
||||
impl Tr<Self> for S {} // OK
|
||||
impl<T: Tr<Self>> Tr<T> for S {} // OK
|
||||
impl<T = Self> Tr<T> for S {} // OK
|
||||
impl Tr for S where Self: Copy {} // OK
|
||||
impl Tr for S where S<Self>: Copy {} // OK
|
||||
impl Tr for S where Self::A: Copy {} // OK
|
||||
|
|
|
|||
|
|
@ -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))]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@
|
|||
|
||||
// gate-test-default_type_parameter_fallback
|
||||
|
||||
#![deny(future_incompatible)]
|
||||
#![allow(dead_code)]
|
||||
#![deny(invalid_type_param_default)]
|
||||
#![allow(unused)]
|
||||
|
||||
fn avg<T=i32>(_: T) {}
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~| WARNING hard error
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
struct S<T>(T);
|
||||
impl<T=i32> S<T> {}
|
||||
//~^ ERROR defaults for type parameters are only allowed
|
||||
//~| WARNING hard error
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<T, U> {
|
||||
Awesome(T),
|
||||
Terrible(U)
|
||||
}
|
||||
|
||||
impl<U, V> Carrier for MyResult<U, V> {
|
||||
type Success = U;
|
||||
impl<U, V> Try for MyResult<U, V> {
|
||||
type Ok = U;
|
||||
type Error = V;
|
||||
|
||||
fn from_success(u: U) -> MyResult<U, V> {
|
||||
fn from_ok(u: U) -> MyResult<U, V> {
|
||||
MyResult::Awesome(u)
|
||||
}
|
||||
|
||||
|
|
@ -29,12 +29,10 @@ impl<U, V> Carrier for MyResult<U, V> {
|
|||
MyResult::Terrible(e)
|
||||
}
|
||||
|
||||
fn translate<T>(self) -> T
|
||||
where T: Carrier<Success=U, Error=V>
|
||||
{
|
||||
fn into_result(self) -> Result<U, V> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue