Auto merge of #65169 - tmandry:rollup-qxjj8xp, r=tmandry
Rollup of 5 pull requests Successful merges: - #65095 (Sort error codes in librustc_passes) - #65101 (Upgrade librustc_macros dependencies) - #65142 (Ensure that associated `async fn`s have unique fresh param names) - #65155 (Use shorthand initialization in rustdoc) - #65158 (Remove dead module) Failed merges: r? @ghost
This commit is contained in:
commit
09868a56c9
9 changed files with 221 additions and 391 deletions
24
Cargo.lock
24
Cargo.lock
|
|
@ -993,7 +993,7 @@ dependencies = [
|
|||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.12",
|
||||
"syn 0.15.35",
|
||||
"synstructure",
|
||||
"synstructure 0.10.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3165,7 +3165,7 @@ dependencies = [
|
|||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.12",
|
||||
"syn 0.15.35",
|
||||
"synstructure",
|
||||
"synstructure 0.10.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3546,10 +3546,10 @@ name = "rustc_macros"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"itertools 0.8.0",
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.12",
|
||||
"syn 0.15.35",
|
||||
"synstructure",
|
||||
"proc-macro2 1.0.3",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.5",
|
||||
"synstructure 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4244,6 +4244,18 @@ dependencies = [
|
|||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.5",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntax"
|
||||
version = "0.0.0"
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ impl<'a> LoweringContext<'a> {
|
|||
/// header, we convert it to an in-band lifetime.
|
||||
fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
|
||||
assert!(self.is_collecting_in_band_lifetimes);
|
||||
let index = self.lifetimes_to_define.len();
|
||||
let index = self.lifetimes_to_define.len() + self.in_scope_lifetimes.len();
|
||||
let hir_name = ParamName::Fresh(index);
|
||||
self.lifetimes_to_define.push((span, hir_name));
|
||||
hir_name
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ edition = "2018"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
synstructure = "0.10.2"
|
||||
syn = { version = "0.15.22", features = ["full"] }
|
||||
proc-macro2 = "0.4.24"
|
||||
quote = "0.6.10"
|
||||
synstructure = "0.12.1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
itertools = "0.8"
|
||||
|
|
|
|||
|
|
@ -15,22 +15,22 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
|
|||
};
|
||||
for attr in &field.attrs {
|
||||
if let Ok(meta) = attr.parse_meta() {
|
||||
if &meta.name().to_string() != "stable_hasher" {
|
||||
if !meta.path().is_ident("stable_hasher") {
|
||||
continue;
|
||||
}
|
||||
let mut any_attr = false;
|
||||
if let Meta::List(list) = meta {
|
||||
for nested in list.nested.iter() {
|
||||
if let NestedMeta::Meta(meta) = nested {
|
||||
if &meta.name().to_string() == "ignore" {
|
||||
if meta.path().is_ident("ignore") {
|
||||
attrs.ignore = true;
|
||||
any_attr = true;
|
||||
}
|
||||
if &meta.name().to_string() == "project" {
|
||||
if meta.path().is_ident("project") {
|
||||
if let Meta::List(list) = meta {
|
||||
if let Some(nested) = list.nested.iter().next() {
|
||||
if let NestedMeta::Meta(meta) = nested {
|
||||
attrs.project = Some(meta.name());
|
||||
attrs.project = meta.path().get_ident().cloned();
|
||||
any_attr = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,204 +0,0 @@
|
|||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::mir::mono::MonoItem;
|
||||
use rustc::session::config::OptLevel;
|
||||
use rustc::ty::{self, TyCtxt, Instance};
|
||||
use rustc::ty::subst::InternalSubsts;
|
||||
use rustc::ty::print::obsolete::DefPathBasedNames;
|
||||
use syntax::attr::InlineAttr;
|
||||
use std::fmt;
|
||||
use rustc::mir::mono::Linkage;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// Describes how a monomorphization will be instantiated in object files.
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
|
||||
pub enum InstantiationMode {
|
||||
/// There will be exactly one instance of the given MonoItem. It will have
|
||||
/// external linkage so that it can be linked to from other codegen units.
|
||||
GloballyShared {
|
||||
/// In some compilation scenarios we may decide to take functions that
|
||||
/// are typically `LocalCopy` and instead move them to `GloballyShared`
|
||||
/// to avoid codegenning them a bunch of times. In this situation,
|
||||
/// however, our local copy may conflict with other crates also
|
||||
/// inlining the same function.
|
||||
///
|
||||
/// This flag indicates that this situation is occurring, and informs
|
||||
/// symbol name calculation that some extra mangling is needed to
|
||||
/// avoid conflicts. Note that this may eventually go away entirely if
|
||||
/// ThinLTO enables us to *always* have a globally shared instance of a
|
||||
/// function within one crate's compilation.
|
||||
may_conflict: bool,
|
||||
},
|
||||
|
||||
/// Each codegen unit containing a reference to the given MonoItem will
|
||||
/// have its own private copy of the function (with internal linkage).
|
||||
LocalCopy,
|
||||
}
|
||||
|
||||
pub trait MonoItemExt<'tcx>: fmt::Debug {
|
||||
fn as_mono_item(&self) -> &MonoItem<'tcx>;
|
||||
|
||||
fn is_generic_fn(&self) -> bool {
|
||||
match *self.as_mono_item() {
|
||||
MonoItem::Fn(ref instance) => {
|
||||
instance.substs.non_erasable_generics().next().is_some()
|
||||
}
|
||||
MonoItem::Static(..) |
|
||||
MonoItem::GlobalAsm(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
|
||||
match *self.as_mono_item() {
|
||||
MonoItem::Fn(instance) => tcx.symbol_name(instance),
|
||||
MonoItem::Static(def_id) => {
|
||||
tcx.symbol_name(Instance::mono(tcx, def_id))
|
||||
}
|
||||
MonoItem::GlobalAsm(hir_id) => {
|
||||
let def_id = tcx.hir().local_def_id(hir_id);
|
||||
ty::SymbolName {
|
||||
name: InternedString::intern(&format!("global_asm_{:?}", def_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
||||
let inline_in_all_cgus =
|
||||
tcx.sess.opts.debugging_opts.inline_in_all_cgus.unwrap_or_else(|| {
|
||||
tcx.sess.opts.optimize != OptLevel::No
|
||||
}) && !tcx.sess.opts.cg.link_dead_code;
|
||||
|
||||
match *self.as_mono_item() {
|
||||
MonoItem::Fn(ref instance) => {
|
||||
let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id);
|
||||
// If this function isn't inlined or otherwise has explicit
|
||||
// linkage, then we'll be creating a globally shared version.
|
||||
if self.explicit_linkage(tcx).is_some() ||
|
||||
!instance.def.requires_local(tcx) ||
|
||||
Some(instance.def_id()) == entry_def_id
|
||||
{
|
||||
return InstantiationMode::GloballyShared { may_conflict: false }
|
||||
}
|
||||
|
||||
// At this point we don't have explicit linkage and we're an
|
||||
// inlined function. If we're inlining into all CGUs then we'll
|
||||
// be creating a local copy per CGU
|
||||
if inline_in_all_cgus {
|
||||
return InstantiationMode::LocalCopy
|
||||
}
|
||||
|
||||
// Finally, if this is `#[inline(always)]` we're sure to respect
|
||||
// that with an inline copy per CGU, but otherwise we'll be
|
||||
// creating one copy of this `#[inline]` function which may
|
||||
// conflict with upstream crates as it could be an exported
|
||||
// symbol.
|
||||
match tcx.codegen_fn_attrs(instance.def_id()).inline {
|
||||
InlineAttr::Always => InstantiationMode::LocalCopy,
|
||||
_ => {
|
||||
InstantiationMode::GloballyShared { may_conflict: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
MonoItem::Static(..) |
|
||||
MonoItem::GlobalAsm(..) => {
|
||||
InstantiationMode::GloballyShared { may_conflict: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn explicit_linkage(&self, tcx: TyCtxt<'tcx>) -> Option<Linkage> {
|
||||
let def_id = match *self.as_mono_item() {
|
||||
MonoItem::Fn(ref instance) => instance.def_id(),
|
||||
MonoItem::Static(def_id) => def_id,
|
||||
MonoItem::GlobalAsm(..) => return None,
|
||||
};
|
||||
|
||||
let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
|
||||
codegen_fn_attrs.linkage
|
||||
}
|
||||
|
||||
/// Returns `true` if this instance is instantiable - whether it has no unsatisfied
|
||||
/// predicates.
|
||||
///
|
||||
/// In order to codegen an item, all of its predicates must hold, because
|
||||
/// otherwise the item does not make sense. Type-checking ensures that
|
||||
/// the predicates of every item that is *used by* a valid item *do*
|
||||
/// hold, so we can rely on that.
|
||||
///
|
||||
/// However, we codegen collector roots (reachable items) and functions
|
||||
/// in vtables when they are seen, even if they are not used, and so they
|
||||
/// might not be instantiable. For example, a programmer can define this
|
||||
/// public function:
|
||||
///
|
||||
/// pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
|
||||
/// <&mut () as Clone>::clone(&s);
|
||||
/// }
|
||||
///
|
||||
/// That function can't be codegened, because the method `<&mut () as Clone>::clone`
|
||||
/// does not exist. Luckily for us, that function can't ever be used,
|
||||
/// because that would require for `&'a mut (): Clone` to hold, so we
|
||||
/// can just not emit any code, or even a linker reference for it.
|
||||
///
|
||||
/// Similarly, if a vtable method has such a signature, and therefore can't
|
||||
/// be used, we can just not emit it and have a placeholder (a null pointer,
|
||||
/// which will never be accessed) in its place.
|
||||
fn is_instantiable(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
debug!("is_instantiable({:?})", self);
|
||||
let (def_id, substs) = match *self.as_mono_item() {
|
||||
MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
|
||||
MonoItem::Static(def_id) => (def_id, InternalSubsts::empty()),
|
||||
// global asm never has predicates
|
||||
MonoItem::GlobalAsm(..) => return true
|
||||
};
|
||||
|
||||
tcx.substitute_normalize_and_test_predicates((def_id, &substs))
|
||||
}
|
||||
|
||||
fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
|
||||
return match *self.as_mono_item() {
|
||||
MonoItem::Fn(instance) => {
|
||||
to_string_internal(tcx, "fn ", instance, debug)
|
||||
},
|
||||
MonoItem::Static(def_id) => {
|
||||
let instance = Instance::new(def_id, tcx.intern_substs(&[]));
|
||||
to_string_internal(tcx, "static ", instance, debug)
|
||||
},
|
||||
MonoItem::GlobalAsm(..) => {
|
||||
"global_asm".to_string()
|
||||
}
|
||||
};
|
||||
|
||||
fn to_string_internal<'a, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
prefix: &str,
|
||||
instance: Instance<'tcx>,
|
||||
debug: bool,
|
||||
) -> String {
|
||||
let mut result = String::with_capacity(32);
|
||||
result.push_str(prefix);
|
||||
let printer = DefPathBasedNames::new(tcx, false, false);
|
||||
printer.push_instance_as_string(instance, &mut result, debug);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
|
||||
match *self.as_mono_item() {
|
||||
MonoItem::Fn(Instance { def, .. }) => {
|
||||
tcx.hir().as_local_hir_id(def.def_id())
|
||||
}
|
||||
MonoItem::Static(def_id) => {
|
||||
tcx.hir().as_local_hir_id(def_id)
|
||||
}
|
||||
MonoItem::GlobalAsm(hir_id) => {
|
||||
Some(hir_id)
|
||||
}
|
||||
}.map(|hir_id| tcx.hir().span(hir_id))
|
||||
}
|
||||
}
|
||||
|
||||
impl MonoItemExt<'tcx> for MonoItem<'tcx> {
|
||||
fn as_mono_item(&self) -> &MonoItem<'tcx> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -53,6 +53,67 @@ extern {
|
|||
```
|
||||
"##,
|
||||
|
||||
// This shouldn't really ever trigger since the repeated value error comes first
|
||||
E0136: r##"
|
||||
A binary can only have one entry point, and by default that entry point is the
|
||||
function `main()`. If there are multiple such functions, please rename one.
|
||||
"##,
|
||||
|
||||
E0137: r##"
|
||||
More than one function was declared with the `#[main]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0137
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn foo() {}
|
||||
|
||||
#[main]
|
||||
fn f() {} // error: multiple functions with a `#[main]` attribute
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[main]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn f() {} // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0138: r##"
|
||||
More than one function was declared with the `#[start]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0138
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize {}
|
||||
|
||||
#[start]
|
||||
fn f(argc: isize, argv: *const *const u8) -> isize {}
|
||||
// error: multiple 'start' functions
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[start]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0197: r##"
|
||||
Inherent implementations (one that do not implement a trait but provide
|
||||
methods associated with a type) are always safe because they are not
|
||||
|
|
@ -198,20 +259,30 @@ impl Foo for Bar {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0512: r##"
|
||||
Transmute with two differently sized types was attempted. Erroneous code
|
||||
example:
|
||||
|
||||
E0590: r##"
|
||||
`break` or `continue` must include a label when used in the condition of a
|
||||
`while` loop.
|
||||
```compile_fail,E0512
|
||||
fn takes_u8(_: u8) {}
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
while break {}
|
||||
fn main() {
|
||||
unsafe { takes_u8(::std::mem::transmute(0u16)); }
|
||||
// error: cannot transmute between types of different sizes,
|
||||
// or dependently-sized types
|
||||
}
|
||||
```
|
||||
|
||||
To fix this, add a label specifying which loop is being broken out of:
|
||||
Please use types with same size or use the expected type directly. Example:
|
||||
|
||||
```
|
||||
'foo: while break 'foo {}
|
||||
fn takes_u8(_: u8) {}
|
||||
|
||||
fn main() {
|
||||
unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!
|
||||
// or:
|
||||
unsafe { takes_u8(0u8); } // ok!
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
|
|
@ -249,153 +320,22 @@ let result = loop { // ok!
|
|||
```
|
||||
"##,
|
||||
|
||||
E0642: r##"
|
||||
Trait methods currently cannot take patterns as arguments.
|
||||
E0590: r##"
|
||||
`break` or `continue` must include a label when used in the condition of a
|
||||
`while` loop.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0642
|
||||
trait Foo {
|
||||
fn foo((x, y): (i32, i32)); // error: patterns aren't allowed
|
||||
// in trait methods
|
||||
}
|
||||
```compile_fail
|
||||
while break {}
|
||||
```
|
||||
|
||||
You can instead use a single name for the argument:
|
||||
|
||||
To fix this, add a label specifying which loop is being broken out of:
|
||||
```
|
||||
trait Foo {
|
||||
fn foo(x_and_y: (i32, i32)); // ok!
|
||||
}
|
||||
'foo: while break 'foo {}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0695: r##"
|
||||
A `break` statement without a label appeared inside a labeled block.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0695
|
||||
# #![feature(label_break_value)]
|
||||
loop {
|
||||
'a: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to always label the `break`:
|
||||
|
||||
```
|
||||
# #![feature(label_break_value)]
|
||||
'l: loop {
|
||||
'a: {
|
||||
break 'l;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or if you want to `break` the labeled block:
|
||||
|
||||
```
|
||||
# #![feature(label_break_value)]
|
||||
loop {
|
||||
'a: {
|
||||
break 'a;
|
||||
}
|
||||
break;
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0670: r##"
|
||||
Rust 2015 does not permit the use of `async fn`.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0670
|
||||
async fn foo() {}
|
||||
```
|
||||
|
||||
Switch to the Rust 2018 edition to use `async fn`.
|
||||
"##,
|
||||
|
||||
// This shouldn't really ever trigger since the repeated value error comes first
|
||||
E0136: r##"
|
||||
A binary can only have one entry point, and by default that entry point is the
|
||||
function `main()`. If there are multiple such functions, please rename one.
|
||||
"##,
|
||||
|
||||
E0137: r##"
|
||||
More than one function was declared with the `#[main]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0137
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn foo() {}
|
||||
|
||||
#[main]
|
||||
fn f() {} // error: multiple functions with a `#[main]` attribute
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[main]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn f() {} // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0138: r##"
|
||||
More than one function was declared with the `#[start]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0138
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize {}
|
||||
|
||||
#[start]
|
||||
fn f(argc: isize, argv: *const *const u8) -> isize {}
|
||||
// error: multiple 'start' functions
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[start]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0601: r##"
|
||||
No `main` function was found in a binary crate. To fix this error, 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/
|
||||
"##,
|
||||
|
||||
E0591: r##"
|
||||
Per [RFC 401][rfc401], if you have a function declaration `foo`:
|
||||
|
||||
|
|
@ -474,31 +414,90 @@ makes a difference in practice.)
|
|||
[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
|
||||
"##,
|
||||
|
||||
E0512: r##"
|
||||
Transmute with two differently sized types was attempted. Erroneous code
|
||||
example:
|
||||
|
||||
```compile_fail,E0512
|
||||
fn takes_u8(_: u8) {}
|
||||
E0601: r##"
|
||||
No `main` function was found in a binary crate. To fix this error, add a
|
||||
`main` function. For example:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
unsafe { takes_u8(::std::mem::transmute(0u16)); }
|
||||
// error: cannot transmute between types of different sizes,
|
||||
// or dependently-sized types
|
||||
// Your program will start here.
|
||||
println!("Hello world!");
|
||||
}
|
||||
```
|
||||
|
||||
Please use types with same size or use the expected type directly. Example:
|
||||
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/
|
||||
"##,
|
||||
|
||||
```
|
||||
fn takes_u8(_: u8) {}
|
||||
E0642: r##"
|
||||
Trait methods currently cannot take patterns as arguments.
|
||||
|
||||
fn main() {
|
||||
unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!
|
||||
// or:
|
||||
unsafe { takes_u8(0u8); } // ok!
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0642
|
||||
trait Foo {
|
||||
fn foo((x, y): (i32, i32)); // error: patterns aren't allowed
|
||||
// in trait methods
|
||||
}
|
||||
```
|
||||
|
||||
You can instead use a single name for the argument:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn foo(x_and_y: (i32, i32)); // ok!
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0695: r##"
|
||||
A `break` statement without a label appeared inside a labeled block.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0695
|
||||
# #![feature(label_break_value)]
|
||||
loop {
|
||||
'a: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to always label the `break`:
|
||||
|
||||
```
|
||||
# #![feature(label_break_value)]
|
||||
'l: loop {
|
||||
'a: {
|
||||
break 'l;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or if you want to `break` the labeled block:
|
||||
|
||||
```
|
||||
# #![feature(label_break_value)]
|
||||
loop {
|
||||
'a: {
|
||||
break 'a;
|
||||
}
|
||||
break;
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0670: r##"
|
||||
Rust 2015 does not permit the use of `async fn`.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0670
|
||||
async fn foo() {}
|
||||
```
|
||||
|
||||
Switch to the Rust 2018 edition to use `async fn`.
|
||||
"##,
|
||||
|
||||
;
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
|||
Item {
|
||||
source: Span::empty(),
|
||||
name: Some(kw.clone()),
|
||||
attrs: attrs,
|
||||
attrs,
|
||||
visibility: Public,
|
||||
stability: get_stability(cx, def_id),
|
||||
deprecation: get_deprecation(cx, def_id),
|
||||
|
|
@ -1570,7 +1570,7 @@ impl Clean<GenericParamDef> for hir::GenericParam {
|
|||
did: cx.tcx.hir().local_def_id(self.hir_id),
|
||||
bounds: self.bounds.clean(cx),
|
||||
default: default.clean(cx),
|
||||
synthetic: synthetic,
|
||||
synthetic,
|
||||
})
|
||||
}
|
||||
hir::GenericParamKind::Const { ref ty } => {
|
||||
|
|
@ -2213,7 +2213,7 @@ impl Clean<Item> for doctree::Trait<'_> {
|
|||
let is_spotlight = attrs.has_doc_flag(sym::spotlight);
|
||||
Item {
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs: attrs,
|
||||
attrs,
|
||||
source: self.whence.clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id),
|
||||
visibility: self.vis.clean(cx),
|
||||
|
|
@ -2844,7 +2844,7 @@ impl Clean<Type> for hir::Ty {
|
|||
} else {
|
||||
Some(l.clean(cx))
|
||||
};
|
||||
BorrowedRef {lifetime: lifetime, mutability: m.mutbl.clean(cx),
|
||||
BorrowedRef {lifetime, mutability: m.mutbl.clean(cx),
|
||||
type_: box m.ty.clean(cx)}
|
||||
}
|
||||
TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
|
||||
|
|
@ -3102,9 +3102,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
let path = external_path(cx, cx.tcx.item_name(did),
|
||||
None, false, vec![], InternalSubsts::empty());
|
||||
ResolvedPath {
|
||||
path: path,
|
||||
path,
|
||||
param_names: None,
|
||||
did: did,
|
||||
did,
|
||||
is_generic: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -4274,7 +4274,7 @@ fn resolve_type(cx: &DocContext<'_>,
|
|||
_ => false,
|
||||
};
|
||||
let did = register_res(&*cx, path.res);
|
||||
ResolvedPath { path: path, param_names: None, did: did, is_generic: is_generic }
|
||||
ResolvedPath { path, param_names: None, did, is_generic }
|
||||
}
|
||||
|
||||
pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
|
||||
|
|
|
|||
|
|
@ -486,8 +486,8 @@ where R: 'static + Send,
|
|||
krate.version = crate_version;
|
||||
|
||||
f(Output {
|
||||
krate: krate,
|
||||
renderinfo: renderinfo,
|
||||
krate,
|
||||
renderinfo,
|
||||
renderopts,
|
||||
})
|
||||
});
|
||||
|
|
|
|||
23
src/test/ui/async-await/async-assoc-fn-anon-lifetimes.rs
Normal file
23
src/test/ui/async-await/async-assoc-fn-anon-lifetimes.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// check-pass
|
||||
// Check that the anonymous lifetimes used here aren't considered to shadow one
|
||||
// another. Note that `async fn` is different to `fn` here because the lifetimes
|
||||
// are numbered by HIR lowering, rather than lifetime resolution.
|
||||
|
||||
// edition:2018
|
||||
|
||||
struct A<'a, 'b>(&'a &'b i32);
|
||||
struct B<'a>(&'a i32);
|
||||
|
||||
impl A<'_, '_> {
|
||||
async fn assoc(x: &u32, y: B<'_>) {
|
||||
async fn nested(x: &u32, y: A<'_, '_>) {}
|
||||
}
|
||||
|
||||
async fn assoc2(x: &u32, y: A<'_, '_>) {
|
||||
impl A<'_, '_> {
|
||||
async fn nested_assoc(x: &u32, y: B<'_>) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue