mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-27 07:03:45 +00:00
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:
commit
a19f93410d
10
Cargo.lock
10
Cargo.lock
@ -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",
|
||||
]
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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)
|
||||
|
82
src/doc/rustdoc/src/how-to-write-documentation.md
Normal file
82
src/doc/rustdoc/src/how-to-write-documentation.md
Normal 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
|
119
src/doc/rustdoc/src/lints.md
Normal file
119
src/doc/rustdoc/src/lints.md
Normal 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 | | /// ```
|
||||
| |___________^
|
||||
```
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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()?;
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)),
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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]`",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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 {}
|
||||
|
@ -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)]
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user