Auto merge of #66323 - JohnTitor:rollup-jl8xdk4, r=JohnTitor

Rollup of 11 pull requests

Successful merges:

 - #65965 (Clean up librustc_typeck error_codes file)
 - #66230 (remove vestigial comments referring to defunct numeric trait hierarchy)
 - #66241 (bump openssl version)
 - #66257 (Drop long-section-names linker workaround for windows-gnu)
 - #66263 (make the error message more readable)
 - #66267 (Add rustdoc doc)
 - #66276 (Move lock into CodeStats)
 - #66278 (Fix error message about exported symbols from proc-macro crates)
 - #66280 (Fix HashSet::union performance)
 - #66299 (support issue = "none" in unstable attributes )
 - #66309 (Tiny cleanup to size assertions)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-11-12 08:23:32 +00:00
commit a19f93410d
29 changed files with 458 additions and 190 deletions

View File

@ -2252,9 +2252,9 @@ dependencies = [
[[package]]
name = "openssl"
version = "0.10.16"
version = "0.10.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9"
checksum = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449"
dependencies = [
"bitflags",
"cfg-if",
@ -2281,15 +2281,15 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.43"
version = "0.9.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d"
checksum = "c977d08e1312e2f7e4b86f9ebaa0ed3b19d1daff75fae88bbb88108afbd801fc"
dependencies = [
"autocfg",
"cc",
"libc",
"openssl-src",
"pkg-config",
"rustc_version",
"vcpkg",
]

View File

@ -448,12 +448,12 @@ Arguments:
Flags {
verbose: matches.opt_count("verbose"),
stage: matches.opt_str("stage").map(|j| j.parse().unwrap()),
stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")),
dry_run: matches.opt_present("dry-run"),
on_fail: matches.opt_str("on-fail"),
rustc_error_format: matches.opt_str("error-format"),
keep_stage: matches.opt_strs("keep-stage")
.into_iter().map(|j| j.parse().unwrap())
.into_iter().map(|j| j.parse().expect("`keep-stage` should be a number"))
.collect(),
host: split(&matches.opt_strs("host"))
.into_iter()
@ -464,7 +464,7 @@ Arguments:
.map(|x| INTERNER.intern_string(x))
.collect::<Vec<_>>(),
config: cfg_file,
jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")),
cmd,
incremental: matches.opt_present("incremental"),
exclude: split(&matches.opt_strs("exclude"))

View File

@ -1,8 +1,10 @@
# The Rustdoc Book
- [What is rustdoc?](what-is-rustdoc.md)
- [How to write documentation](how-to-write-documentation.md)
- [Command-line arguments](command-line-arguments.md)
- [The `#[doc]` attribute](the-doc-attribute.md)
- [Documentation tests](documentation-tests.md)
- [Lints](lints.md)
- [Passes](passes.md)
- [Unstable features](unstable-features.md)

View File

@ -0,0 +1,82 @@
# How to write documentation
This chapter covers not only how to write documentation but specifically
how to write **good** documentation. Something to keep in mind when
writing documentation is that your audience is not just yourself but others
who simply don't have the context you do. It is important to be as clear
as you can, and as complete as possible. As a rule of thumb: the more
documentation you write for your crate the better. If an item is public
then it should be documented.
## Basic structure
It is recommended that each item's documentation follows this basic structure:
```text
[short sentence explaining what it is]
[more detailed explanation]
[at least one code example that users can copy/paste to try it]
[even more advanced explanations if necessary]
```
This basic structure should be straightforward to follow when writing your
documentation and, while you might think that a code example is trivial,
the examples are really important because they can help your users to
understand what an item is, how it is used, and for what purpose it exists.
Let's see an example coming from the [standard library] by taking a look at the
[`std::env::args()`][env::args] function:
``````text
Returns the arguments which this program was started with (normally passed
via the command line).
The first element is traditionally the path of the executable, but it can be
set to arbitrary text, and may not even exist. This means this property should
not be relied upon for security purposes.
On Unix systems shell usually expands unquoted arguments with glob patterns
(such as `*` and `?`). On Windows this is not done, and such arguments are
passed as-is.
# Panics
The returned iterator will panic during iteration if any argument to the
process is not valid unicode. If this is not desired,
use the [`args_os`] function instead.
# Examples
```
use std::env;
// Prints each argument on a separate line
for argument in env::args() {
println!("{}", argument);
}
```
[`args_os`]: ./fn.args_os.html
``````
As you can see, it follows the structure detailed above: it starts with a short
sentence explaining what the functions does, then it provides more information
and finally provides a code example.
## Markdown
`rustdoc` is using the [commonmark markdown specification]. You might be
interested into taking a look at their website to see what's possible to do.
## Lints
To be sure that you didn't miss any item without documentation or code examples,
you can take a look at the rustdoc lints [here][rustdoc-lints].
[standard library]: https://doc.rust-lang.org/stable/std/index.html
[env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html
[commonmark markdown specification]: https://commonmark.org/
[rustdoc-lints]: lints.md

View File

@ -0,0 +1,119 @@
# Lints
`rustdoc` provides lints to help you writing and testing your documentation. You
can use them like any other lints by doing this:
```rust,ignore
#![allow(missing_docs)] // allowing the lint, no message
#![warn(missing_docs)] // warn if there is missing docs
#![deny(missing_docs)] // rustdoc will fail if there is missing docs
```
Here is the list of the lints provided by `rustdoc`:
## intra_doc_link_resolution_failure
This lint **warns by default** and is **nightly-only**. This lint detects when
an intra-doc link fails to get resolved. For example:
```rust
/// I want to link to [`Inexistent`] but it doesn't exist!
pub fn foo() {}
```
You'll get a warning saying:
```text
error: `[`Inexistent`]` cannot be resolved, ignoring it...
```
## missing_docs
This lint is **allowed by default**. It detects items missing documentation.
For example:
```rust
#![warn(missing_docs)]
pub fn undocumented() {}
# fn main() {}
```
The `undocumented` function will then have the following warning:
```text
warning: missing documentation for a function
--> your-crate/lib.rs:3:1
|
3 | pub fn undocumented() {}
| ^^^^^^^^^^^^^^^^^^^^^
```
## missing_doc_code_examples
This lint is **allowed by default**. It detects when a documentation block
is missing a code example. For example:
```rust
#![warn(missing_doc_code_examples)]
/// There is no code example!
pub fn no_code_example() {}
# fn main() {}
```
The `no_code_example` function will then have the following warning:
```text
warning: Missing code example in this documentation
--> your-crate/lib.rs:3:1
|
LL | /// There is no code example!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
To fix the lint, you need to add a code example into the documentation block:
```rust
/// There is no code example!
///
/// ```
/// println!("calling no_code_example...");
/// no_code_example();
/// println!("we called no_code_example!");
/// ```
pub fn no_code_example() {}
```
## private_doc_tests
This lint is **allowed by default**. It detects documentation tests when they
are on a private item. For example:
```rust
#![warn(private_doc_tests)]
mod foo {
/// private doc test
///
/// ```
/// assert!(false);
/// ```
fn bar() {}
}
# fn main() {}
```
Which will give:
```text
warning: Documentation test in private item
--> your-crate/lib.rs:4:1
|
4 | / /// private doc test
5 | | ///
6 | | /// ```
7 | | /// assert!(false);
8 | | /// ```
| |___________^
```

View File

@ -235,7 +235,6 @@ depending on the target pointer size.
"}
}
// `Int` + `SignedInt` implemented for signed integers
macro_rules! int_impl {
($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
$EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
@ -2303,7 +2302,6 @@ impl isize {
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
}
// `Int` + `UnsignedInt` implemented for unsigned integers
macro_rules! uint_impl {
($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr,
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,

View File

@ -22,8 +22,9 @@ use syntax::attr::{self, Stability, Deprecation, RustcDeprecation};
use crate::ty::{self, TyCtxt};
use crate::util::nodemap::{FxHashSet, FxHashMap};
use std::mem::replace;
use std::cmp::Ordering;
use std::mem::replace;
use std::num::NonZeroU32;
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum StabilityLevel {
@ -441,7 +442,7 @@ impl<'tcx> Index<'tcx> {
let stability = tcx.intern_stability(Stability {
level: attr::StabilityLevel::Unstable {
reason: Some(Symbol::intern(reason)),
issue: 27812,
issue: NonZeroU32::new(27812),
is_soft: false,
},
feature: sym::rustc_private,
@ -488,7 +489,7 @@ pub fn report_unstable(
sess: &Session,
feature: Symbol,
reason: Option<Symbol>,
issue: u32,
issue: Option<NonZeroU32>,
is_soft: bool,
span: Span,
soft_handler: impl FnOnce(&'static lint::Lint, Span, &str),
@ -520,7 +521,7 @@ pub fn report_unstable(
soft_handler(lint::builtin::SOFT_UNSTABLE, span, &msg)
} else {
emit_feature_err(
&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg
);
}
}
@ -637,7 +638,7 @@ pub enum EvalResult {
Deny {
feature: Symbol,
reason: Option<Symbol>,
issue: u32,
issue: Option<NonZeroU32>,
is_soft: bool,
},
/// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
@ -758,7 +759,7 @@ impl<'tcx> TyCtxt<'tcx> {
// the `-Z force-unstable-if-unmarked` flag present (we're
// compiling a compiler crate), then let this missing feature
// annotation slide.
if feature == sym::rustc_private && issue == 27812 {
if feature == sym::rustc_private && issue == NonZeroU32::new(27812) {
if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
return EvalResult::Allow;
}

View File

@ -1,6 +1,7 @@
use rustc_target::abi::{Align, Size};
use rustc_data_structures::fx::{FxHashSet};
use std::cmp::{self, Ordering};
use rustc_data_structures::sync::Lock;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct VariantInfo {
@ -44,13 +45,13 @@ pub struct TypeSizeInfo {
pub variants: Vec<VariantInfo>,
}
#[derive(PartialEq, Eq, Debug, Default)]
#[derive(Default)]
pub struct CodeStats {
type_sizes: FxHashSet<TypeSizeInfo>,
type_sizes: Lock<FxHashSet<TypeSizeInfo>>,
}
impl CodeStats {
pub fn record_type_size<S: ToString>(&mut self,
pub fn record_type_size<S: ToString>(&self,
kind: DataTypeKind,
type_desc: S,
align: Align,
@ -73,11 +74,12 @@ impl CodeStats {
opt_discr_size: opt_discr_size.map(|s| s.bytes()),
variants,
};
self.type_sizes.insert(info);
self.type_sizes.borrow_mut().insert(info);
}
pub fn print_type_sizes(&self) {
let mut sorted: Vec<_> = self.type_sizes.iter().collect();
let type_sizes = self.type_sizes.borrow();
let mut sorted: Vec<_> = type_sizes.iter().collect();
// Primary sort: large-to-small.
// Secondary sort: description (dictionary order)

View File

@ -41,6 +41,7 @@ use std::cell::{self, RefCell};
use std::env;
use std::fmt;
use std::io::Write;
use std::num::NonZeroU32;
use std::path::PathBuf;
use std::time::Duration;
use std::sync::Arc;
@ -124,7 +125,7 @@ pub struct Session {
pub perf_stats: PerfStats,
/// Data about code being compiled, gathered during compilation.
pub code_stats: Lock<CodeStats>,
pub code_stats: CodeStats,
/// If `-zfuel=crate=n` is specified, `Some(crate)`.
optimization_fuel_crate: Option<String>,
@ -183,7 +184,7 @@ enum DiagnosticBuilderMethod {
pub enum DiagnosticMessageId {
ErrorId(u16), // EXXXX error code as integer
LintId(lint::LintId),
StabilityId(u32), // issue number
StabilityId(Option<NonZeroU32>), // issue number
}
impl From<&'static lint::Lint> for DiagnosticMessageId {

View File

@ -1614,13 +1614,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// (delay format until we actually need it)
let record = |kind, packed, opt_discr_size, variants| {
let type_desc = format!("{:?}", layout.ty);
self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
type_desc,
layout.align.abi,
layout.size,
packed,
opt_discr_size,
variants);
self.tcx.sess.code_stats.record_type_size(kind,
type_desc,
layout.align.abi,
layout.size,
packed,
opt_discr_size,
variants);
};
let adt_def = match layout.ty.kind {

View File

@ -393,7 +393,7 @@ pub fn run_compiler(
mem::drop(compiler.global_ctxt()?.take());
if sess.opts.debugging_opts.print_type_sizes {
sess.code_stats.borrow().print_type_sizes();
sess.code_stats.print_type_sizes();
}
compiler.link()?;

View File

@ -15,8 +15,6 @@ use Level::*;
use emitter::{Emitter, EmitterWriter, is_case_difference};
use registry::Registry;
#[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size;
use rustc_data_structures::sync::{self, Lrc, Lock};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::StableHasher;
@ -54,7 +52,7 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
// (See also the comment on `DiagnosticBuilderInner`.)
#[cfg(target_arch = "x86_64")]
static_assert_size!(PResult<'_, bool>, 16);
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
/// Indicates the confidence in the correctness of a suggestion.
///

View File

@ -4,33 +4,6 @@ use std::default::Default;
pub fn opts() -> TargetOptions {
let mut pre_link_args = LinkArgs::new();
pre_link_args.insert(LinkerFlavor::Gcc, vec![
// And here, we see obscure linker flags #45. On windows, it has been
// found to be necessary to have this flag to compile liblibc.
//
// First a bit of background. On Windows, the file format is not ELF,
// but COFF (at least according to LLVM). COFF doesn't officially allow
// for section names over 8 characters, apparently. Our metadata
// section, ".note.rustc", you'll note is over 8 characters.
//
// On more recent versions of gcc on mingw, apparently the section name
// is *not* truncated, but rather stored elsewhere in a separate lookup
// table. On older versions of gcc, they apparently always truncated th
// section names (at least in some cases). Truncating the section name
// actually creates "invalid" objects [1] [2], but only for some
// introspection tools, not in terms of whether it can be loaded.
//
// Long story short, passing this flag forces the linker to *not*
// truncate section names (so we can find the metadata section after
// it's compiled). The real kicker is that rust compiled just fine on
// windows for quite a long time *without* this flag, so I have no idea
// why it suddenly started failing for liblibc. Regardless, we
// definitely don't want section name truncation, so we're keeping this
// flag for windows.
//
// [1] - https://sourceware.org/bugzilla/show_bug.cgi?id=13130
// [2] - https://code.google.com/p/go/issues/detail?id=2139
"-Wl,--enable-long-section-names".to_string(),
// Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways.
"-fno-use-linker-plugin".to_string(),

View File

@ -3,9 +3,9 @@
syntax::register_diagnostics! {
E0023: r##"
A pattern used to match against an enum variant must provide a sub-pattern for
each field of the enum variant. This error indicates that a pattern attempted to
extract an incorrect number of fields from a variant.
A pattern attempted to extract an incorrect number of fields from a variant.
Erroneous code example:
```
enum Fruit {
@ -14,6 +14,9 @@ enum Fruit {
}
```
A pattern used to match against an enum variant must provide a sub-pattern for
each field of the enum variant.
Here the `Apple` variant has two fields, and should be matched against like so:
```
@ -53,8 +56,9 @@ uses the same number.
"##,
E0025: r##"
Each field of a struct can only be bound once in a pattern. Erroneous code
example:
Each field of a struct can only be bound once in a pattern.
Erroneous code example:
```compile_fail,E0025
struct Foo {
@ -89,65 +93,47 @@ fn main(){
"##,
E0026: r##"
This error indicates that a struct pattern attempted to extract a non-existent
field from a struct. Struct fields are identified by the name used before the
colon `:` so struct patterns should resemble the declaration of the struct type
being matched.
A struct pattern attempted to extract a non-existent field from a struct.
```
// Correct matching.
struct Thing {
x: u32,
y: u32
}
let thing = Thing { x: 1, y: 2 };
match thing {
Thing { x: xfield, y: yfield } => {}
}
```
If you are using shorthand field patterns but want to refer to the struct field
by a different name, you should rename it explicitly.
Change this:
Erroneous code example:
```compile_fail,E0026
struct Thing {
x: u32,
y: u32
y: u32,
}
let thing = Thing { x: 0, y: 0 };
match thing {
Thing { x, z } => {}
Thing { x, z } => {} // error: `Thing::z` field doesn't exist
}
```
To this:
If you are using shorthand field patterns but want to refer to the struct field
by a different name, you should rename it explicitly. Struct fields are
identified by the name used before the colon `:` so struct patterns should
resemble the declaration of the struct type being matched.
```
struct Thing {
x: u32,
y: u32
y: u32,
}
let thing = Thing { x: 0, y: 0 };
match thing {
Thing { x, y: z } => {}
Thing { x, y: z } => {} // we renamed `y` to `z`
}
```
"##,
E0027: r##"
This error indicates that a pattern for a struct fails to specify a sub-pattern
for every one of the struct's fields. Ensure that each field from the struct's
definition is mentioned in the pattern, or use `..` to ignore unwanted fields.
A pattern for a struct fails to specify a sub-pattern for every one of the
struct's fields.
For example:
Erroneous code example:
```compile_fail,E0027
struct Dog {
@ -163,7 +149,8 @@ match d {
}
```
This is correct (explicit):
To fix this error, ensure that each field from the struct's definition is
mentioned in the pattern, or use `..` to ignore unwanted fields. Example:
```
struct Dog {
@ -185,11 +172,9 @@ match d {
"##,
E0029: r##"
In a match expression, only numbers and characters can be matched against a
range. This is because the compiler checks that the range is non-empty at
compile-time, and is unable to evaluate arbitrary comparison functions. If you
want to capture values of an orderable type between two end-points, you can use
a guard.
Something other than numbers and characters has been used for a range.
Erroneous code example:
```compile_fail,E0029
let string = "salutations !";
@ -207,14 +192,18 @@ match string {
_ => {}
}
```
In a match expression, only numbers and characters can be matched against a
range. This is because the compiler checks that the range is non-empty at
compile-time, and is unable to evaluate arbitrary comparison functions. If you
want to capture values of an orderable type between two end-points, you can use
a guard.
"##,
E0033: r##"
This error indicates that a pointer to a trait type cannot be implicitly
dereferenced by a pattern. Every trait defines a type, but because the
size of trait implementers isn't fixed, this type has no compile-time size.
Therefore, all accesses to trait types must be through pointers. If you
encounter this error you should try to avoid dereferencing the pointer.
A trait type has been dereferenced.
Erroneous code example:
```compile_fail,E0033
# trait SomeTrait { fn method_one(&self){} fn method_two(&self){} }
@ -229,6 +218,12 @@ trait_obj.method_one();
trait_obj.method_two();
```
A pointer to a trait type cannot be implicitly dereferenced by a pattern. Every
trait defines a type, but because the size of trait implementers isn't fixed,
this type has no compile-time size. Therefore, all accesses to trait types must
be through pointers. If you encounter this error you should try to avoid
dereferencing the pointer.
You can read more about trait objects in the [Trait Objects] section of the
Reference.
@ -237,7 +232,9 @@ Reference.
E0034: r##"
The compiler doesn't know what method to call because more than one method
has the same prototype. Erroneous code example:
has the same prototype.
Erroneous code example:
```compile_fail,E0034
struct Test;
@ -323,11 +320,9 @@ fn main() {
"##,
E0040: r##"
It is not allowed to manually call destructors in Rust. It is also not
necessary to do this since `drop` is called automatically whenever a value goes
out of scope.
It is not allowed to manually call destructors in Rust.
Here's an example of this error:
Erroneous code example:
```compile_fail,E0040
struct Foo {
@ -345,11 +340,33 @@ fn main() {
x.drop(); // error: explicit use of destructor method
}
```
It is unnecessary to do this since `drop` is called automatically whenever a
value goes out of scope. However, if you really need to drop a value by hand,
you can use the `std::mem::drop` function:
```
struct Foo {
x: i32,
}
impl Drop for Foo {
fn drop(&mut self) {
println!("kaboom");
}
}
fn main() {
let mut x = Foo { x: -7 };
drop(x); // ok!
}
```
"##,
E0044: r##"
You cannot use type or const parameters on foreign items.
Example of erroneous code:
Erroneous code example:
```compile_fail,E0044
extern { fn some_func<T>(x: T); }
@ -365,21 +382,21 @@ extern { fn some_func_i64(x: i64); }
"##,
E0045: r##"
Rust only supports variadic parameters for interoperability with C code in its
FFI. As such, variadic parameters can only be used with functions which are
using the C ABI. Examples of erroneous code:
Variadic parameters have been used on a non-C ABI function.
```compile_fail
Erroneous code example:
```compile_fail,E0045
#![feature(unboxed_closures)]
extern "rust-call" { fn foo(x: u8, ...); }
// or
fn foo(x: u8, ...) {}
extern "rust-call" {
fn foo(x: u8, ...); // error!
}
```
To fix such code, put them in an extern "C" block:
Rust only supports variadic parameters for interoperability with C code in its
FFI. As such, variadic parameters can only be used with functions which are
using the C ABI. To fix such code, put them in an extern "C" block:
```
extern "C" {
@ -389,7 +406,9 @@ extern "C" {
"##,
E0046: r##"
Items are missing in a trait implementation. Erroneous code example:
Items are missing in a trait implementation.
Erroneous code example:
```compile_fail,E0046
trait Foo {
@ -421,11 +440,10 @@ impl Foo for Bar {
"##,
E0049: r##"
This error indicates that an attempted implementation of a trait method
has the wrong number of type or const parameters.
An attempted implementation of a trait method has the wrong number of type or
const parameters.
For example, the trait below has a method `foo` with a type parameter `T`,
but the implementation of `foo` for the type `Bar` is missing this parameter:
Erroneous code example:
```compile_fail,E0049
trait Foo {
@ -440,15 +458,31 @@ impl Foo for Bar {
fn foo(x: bool) -> Self { Bar }
}
```
For example, the `Foo` trait has a method `foo` with a type parameter `T`,
but the implementation of `foo` for the type `Bar` is missing this parameter.
To fix this error, they must have the same type parameters:
```
trait Foo {
fn foo<T: Default>(x: T) -> Self;
}
struct Bar;
impl Foo for Bar {
fn foo<T: Default>(x: T) -> Self { // ok!
Bar
}
}
```
"##,
E0050: r##"
This error indicates that an attempted implementation of a trait method
has the wrong number of function parameters.
An attempted implementation of a trait method has the wrong number of function
parameters.
For example, the trait below has a method `foo` with two function parameters
(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
the `u8` parameter:
Erroneous code example:
```compile_fail,E0050
trait Foo {
@ -463,13 +497,31 @@ impl Foo for Bar {
fn foo(&self) -> bool { true }
}
```
For example, the `Foo` trait has a method `foo` with two function parameters
(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
the `u8` parameter. To fix this error, they must have the same parameters:
```
trait Foo {
fn foo(&self, x: u8) -> bool;
}
struct Bar;
impl Foo for Bar {
fn foo(&self, x: u8) -> bool { // ok!
true
}
}
```
"##,
E0053: r##"
The parameters of any trait method must match between a trait implementation
and the trait definition.
Here are a couple examples of this error:
Erroneous code example:
```compile_fail,E0053
trait Foo {
@ -490,8 +542,9 @@ impl Foo for Bar {
"##,
E0054: r##"
It is not allowed to cast to a bool. If you are trying to cast a numeric type
to a bool, you can compare it with zero instead:
It is not allowed to cast to a bool.
Erroneous code example:
```compile_fail,E0054
let x = 5;
@ -500,6 +553,9 @@ let x = 5;
let x_is_nonzero = x as bool;
```
If you are trying to cast a numeric type to a bool, you can compare it with
zero instead:
```
let x = 5;

View File

@ -39,6 +39,7 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::default::Default;
use std::{mem, slice, vec};
use std::num::NonZeroU32;
use std::iter::FromIterator;
use std::rc::Rc;
use std::cell::RefCell;
@ -4399,7 +4400,7 @@ pub struct Stability {
pub since: String,
pub deprecation: Option<Deprecation>,
pub unstable_reason: Option<String>,
pub issue: Option<u32>,
pub issue: Option<NonZeroU32>,
}
#[derive(Clone, Debug)]
@ -4428,7 +4429,7 @@ impl Clean<Stability> for attr::Stability {
_ => None,
},
issue: match self.level {
attr::Unstable {issue, ..} => Some(issue),
attr::Unstable {issue, ..} => issue,
_ => None,
}
}

View File

@ -551,7 +551,7 @@ impl<T, S> HashSet<T, S>
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
if self.len() <= other.len() {
if self.len() >= other.len() {
Union {
iter: self.iter().chain(other.difference(self)),
}

View File

@ -38,9 +38,6 @@ use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::vec::Idx;
use rustc_serialize::{self, Decoder, Encoder};
#[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size;
use std::fmt;
#[cfg(test)]
@ -1028,7 +1025,7 @@ pub struct Expr {
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(Expr, 96);
rustc_data_structures::static_assert_size!(Expr, 96);
impl Expr {
/// Returns `true` if this expression would be valid somewhere that expects a value;

View File

@ -6,6 +6,7 @@ use crate::print::pprust;
use crate::sess::ParseSess;
use errors::{Applicability, Handler};
use std::num::NonZeroU32;
use syntax_pos::hygiene::Transparency;
use syntax_pos::{symbol::Symbol, symbol::sym, Span};
@ -157,7 +158,7 @@ pub struct Stability {
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
pub enum StabilityLevel {
// Reason for the current stability level and the relevant rust-lang issue
Unstable { reason: Option<Symbol>, issue: u32, is_soft: bool },
Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
Stable { since: Symbol },
}
@ -394,18 +395,28 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
match (feature, reason, issue) {
(Some(feature), reason, Some(issue)) => {
let issue = match &*issue.as_str() {
// FIXME(rossmacarthur): remove "0" because "none" should be used
// See #41260
"none" | "0" => None,
issue => {
if let Ok(num) = issue.parse() {
NonZeroU32::new(num)
} else {
span_err!(
diagnostic,
attr.span,
E0545,
"incorrect 'issue'"
);
continue
}
}
};
stab = Some(Stability {
level: Unstable {
reason,
issue: {
if let Ok(issue) = issue.as_str().parse() {
issue
} else {
span_err!(diagnostic, attr.span, E0545,
"incorrect 'issue'");
continue
}
},
issue,
is_soft,
},
feature,

View File

@ -207,10 +207,10 @@ declare_features! (
/// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
(active, allocator_internals, "1.20.0", None, None),
// no-tracking-issue-end
/// Added for testing E0705; perma-unstable.
(active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
(active, test_2018_feature, "1.31.0", None, Some(Edition::Edition2018)),
// no-tracking-issue-end
// -------------------------------------------------------------------------
// feature-group-end: internal feature gates

View File

@ -18,6 +18,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug;
use std::env;
use std::num::NonZeroU32;
#[derive(Copy, Clone, Debug)]
pub enum Stability {
@ -55,25 +56,28 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
}
fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) {
// FIXME (#28244): enforce that active features have issue numbers
// assert!(info.issue.is_some())
info.issue
// assert!(info.issue().is_some())
info.issue()
} else {
// search in Accepted, Removed, or Stable Removed features
let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
let found = ACCEPTED_FEATURES
.iter()
.chain(REMOVED_FEATURES)
.chain(STABLE_REMOVED_FEATURES)
.find(|t| t.name == feature);
match found {
Some(&Feature { issue, .. }) => issue,
None => panic!("Feature `{}` is not declared anywhere", feature),
Some(found) => found.issue(),
None => panic!("feature `{}` is not declared anywhere", feature),
}
}
}
pub enum GateIssue {
Language,
Library(Option<u32>)
Library(Option<NonZeroU32>)
}
#[derive(Debug, Copy, Clone, PartialEq)]
@ -126,14 +130,11 @@ fn leveled_feature_err<'a, S: Into<MultiSpan>>(
GateStrength::Soft => diag.struct_span_warn(span, explain),
};
match issue {
None | Some(0) => {} // We still accept `0` as a stand-in for backwards compatibility
Some(n) => {
err.note(&format!(
"for more information, see https://github.com/rust-lang/rust/issues/{}",
n,
));
}
if let Some(n) = issue {
err.note(&format!(
"for more information, see https://github.com/rust-lang/rust/issues/{}",
n,
));
}
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable

View File

@ -18,8 +18,9 @@ mod active;
mod builtin_attrs;
mod check;
use std::fmt;
use crate::{edition::Edition, symbol::Symbol};
use std::fmt;
use std::num::NonZeroU32;
use syntax_pos::Span;
#[derive(Clone, Copy)]
@ -46,11 +47,17 @@ pub struct Feature {
state: State,
name: Symbol,
since: &'static str,
issue: Option<u32>,
issue: Option<u32>, // FIXME: once #58732 is done make this an Option<NonZeroU32>
edition: Option<Edition>,
description: &'static str,
}
impl Feature {
fn issue(&self) -> Option<NonZeroU32> {
self.issue.and_then(|i| NonZeroU32::new(i))
}
}
pub use active::{Features, INCOMPLETE_FEATURES};
pub use builtin_attrs::{
AttributeGate, AttributeType, GatedCfg,

View File

@ -14,8 +14,6 @@ use syntax_pos::{self, Span, DUMMY_SP};
use std::fmt;
use std::mem;
#[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size;
use rustc_data_structures::sync::Lrc;
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@ -261,7 +259,7 @@ pub enum TokenKind {
// `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TokenKind, 16);
rustc_data_structures::static_assert_size!(TokenKind, 16);
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
pub struct Token {

View File

@ -16,8 +16,6 @@
use crate::token::{self, DelimToken, Token, TokenKind};
use syntax_pos::{Span, DUMMY_SP};
#[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size;
use rustc_data_structures::sync::Lrc;
use smallvec::{SmallVec, smallvec};
@ -129,7 +127,7 @@ pub type TreeAndJoint = (TokenTree, IsJoint);
// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TokenStream, 8);
rustc_data_structures::static_assert_size!(TokenStream, 8);
#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum IsJoint {

View File

@ -92,10 +92,12 @@ pub fn inject(sess: &ParseSess,
impl<'a> CollectProcMacros<'a> {
fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
if self.is_proc_macro_crate && self.in_root && vis.node.is_pub() {
self.handler.span_err(sp,
"`proc-macro` crate types cannot \
export any items other than functions \
tagged with `#[proc_macro_derive]` currently");
self.handler.span_err(
sp,
"`proc-macro` crate types currently cannot export any items other \
than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, \
or `#[proc_macro_attribute]`",
);
}
}

View File

@ -0,0 +1,13 @@
// Check that an issue value can be explicitly set to "none" instead of "0"
#![crate_type = "lib"]
#![feature(staged_api)]
#![stable(feature = "stable_test_feature", since = "1.0.0")]
#[unstable(feature = "unstable_test_feature", issue = "0")]
fn unstable_issue_0() {}
#[unstable(feature = "unstable_test_feature", issue = "none")]
fn unstable_issue_none() {}
#[unstable(feature = "unstable_test_feature", issue = "something")] //~ ERROR incorrect 'issue'
fn unstable_issue_not_allowed() {}

View File

@ -0,0 +1,8 @@
error[E0545]: incorrect 'issue'
--> $DIR/unstable-attribute-allow-issue-none.rs:12:1
|
LL | #[unstable(feature = "unstable_test_feature", issue = "something")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -1,22 +1,22 @@
error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
--> $DIR/exports.rs:7:1
|
LL | pub fn a() {}
| ^^^^^^^^^^^^^
error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
--> $DIR/exports.rs:8:1
|
LL | pub struct B;
| ^^^^^^^^^^^^^
error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
--> $DIR/exports.rs:9:1
|
LL | pub enum C {}
| ^^^^^^^^^^^^^
error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
--> $DIR/exports.rs:10:1
|
LL | pub mod d {}

View File

@ -5,7 +5,7 @@
extern crate proc_macro;
pub mod a { //~ `proc-macro` crate types cannot export any items
pub mod a { //~ `proc-macro` crate types currently cannot export any items
use proc_macro::TokenStream;
#[proc_macro_derive(B)]

View File

@ -1,4 +1,4 @@
error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
--> $DIR/pub-at-crate-root.rs:8:1
|
LL | / pub mod a {