Auto merge of #62253 - Centril:rollup-115uuuq, r=Centril
Rollup of 8 pull requests Successful merges: - #62062 (Use a more efficient iteration order for forward dataflow) - #62063 (Use a more efficient iteration order for backward dataflow) - #62224 (rustdoc: remove unused derives and variants) - #62228 (Extend the #[must_use] lint to boxed types) - #62235 (Extend the `#[must_use]` lint to arrays) - #62239 (Fix a typo) - #62241 (Always parse 'async unsafe fn' + properly ban in 2015) - #62248 (before_exec actually will only get deprecated with 1.37) Failed merges: r? @ghost
This commit is contained in:
commit
765eebf064
27 changed files with 359 additions and 119 deletions
|
|
@ -309,9 +309,9 @@ Misc
|
|||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [`Command::before_exec` is now deprecated in favor of the
|
||||
unsafe method `Command::pre_exec`.][58059]
|
||||
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
|
||||
- [`Command::before_exec` is being replaced by the unsafe method
|
||||
`Command::pre_exec`][58059] and will be deprecated with Rust 1.37.0.
|
||||
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated][57425] as you
|
||||
can now use `const` functions in `static` variables.
|
||||
|
||||
[58370]: https://github.com/rust-lang/rust/pull/58370/
|
||||
|
|
|
|||
|
|
@ -337,16 +337,16 @@ impl char {
|
|||
/// ```
|
||||
/// // as chars
|
||||
/// let eastern = '東';
|
||||
/// let capitol = '京';
|
||||
/// let capital = '京';
|
||||
///
|
||||
/// // both can be represented as three bytes
|
||||
/// assert_eq!(3, eastern.len_utf8());
|
||||
/// assert_eq!(3, capitol.len_utf8());
|
||||
/// assert_eq!(3, capital.len_utf8());
|
||||
///
|
||||
/// // as a &str, these two are encoded in UTF-8
|
||||
/// let tokyo = "東京";
|
||||
///
|
||||
/// let len = eastern.len_utf8() + capitol.len_utf8();
|
||||
/// let len = eastern.len_utf8() + capital.len_utf8();
|
||||
///
|
||||
/// // we can see that they take six bytes total...
|
||||
/// assert_eq!(6, tokyo.len());
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
}
|
||||
|
||||
let ty = cx.tables.expr_ty(&expr);
|
||||
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "");
|
||||
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false);
|
||||
|
||||
let mut fn_warned = false;
|
||||
let mut op_warned = false;
|
||||
|
|
@ -133,7 +133,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
ty: Ty<'tcx>,
|
||||
expr: &hir::Expr,
|
||||
span: Span,
|
||||
descr_post_path: &str,
|
||||
descr_pre: &str,
|
||||
descr_post: &str,
|
||||
plural: bool,
|
||||
) -> bool {
|
||||
if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
|
||||
cx.tcx.hir().get_module_parent(expr.hir_id), ty)
|
||||
|
|
@ -141,15 +143,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
return true;
|
||||
}
|
||||
|
||||
let plural_suffix = if plural { "s" } else { "" };
|
||||
|
||||
match ty.sty {
|
||||
ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path),
|
||||
ty::Adt(..) if ty.is_box() => {
|
||||
let boxed_ty = ty.boxed_ty();
|
||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
||||
check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
|
||||
}
|
||||
ty::Adt(def, _) => {
|
||||
check_must_use_def(cx, def.did, span, descr_pre, descr_post)
|
||||
}
|
||||
ty::Opaque(def, _) => {
|
||||
let mut has_emitted = false;
|
||||
for (predicate, _) in &cx.tcx.predicates_of(def).predicates {
|
||||
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
|
||||
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
|
||||
let def_id = trait_ref.def_id;
|
||||
if check_must_use_def(cx, def_id, span, "implementer of ", "") {
|
||||
let descr_pre = &format!(
|
||||
"{}implementer{} of ",
|
||||
descr_pre,
|
||||
plural_suffix,
|
||||
);
|
||||
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
|
||||
has_emitted = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -162,7 +178,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
for predicate in binder.skip_binder().iter() {
|
||||
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate {
|
||||
let def_id = trait_ref.def_id;
|
||||
if check_must_use_def(cx, def_id, span, "", " trait object") {
|
||||
let descr_post = &format!(
|
||||
" trait object{}{}",
|
||||
plural_suffix,
|
||||
descr_post,
|
||||
);
|
||||
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
|
||||
has_emitted = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -179,14 +200,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
|||
vec![]
|
||||
};
|
||||
for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
|
||||
let descr_post_path = &format!(" in tuple element {}", i);
|
||||
let descr_post = &format!(" in tuple element {}", i);
|
||||
let span = *spans.get(i).unwrap_or(&span);
|
||||
if check_must_use_ty(cx, ty, expr, span, descr_post_path) {
|
||||
if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) {
|
||||
has_emitted = true;
|
||||
}
|
||||
}
|
||||
has_emitted
|
||||
}
|
||||
ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
|
||||
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
||||
Some(n) if n != 0 => {
|
||||
let descr_pre = &format!(
|
||||
"{}array{} of ",
|
||||
descr_pre,
|
||||
plural_suffix,
|
||||
);
|
||||
check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
|
||||
}
|
||||
// Otherwise, we don't lint, to avoid false positives.
|
||||
_ => false,
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,9 +228,25 @@ where
|
|||
BD: BitDenotation<'tcx>,
|
||||
{
|
||||
fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
|
||||
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
|
||||
WorkQueue::with_all(self.builder.body.basic_blocks().len());
|
||||
let body = self.builder.body;
|
||||
|
||||
// Initialize the dirty queue in reverse post-order. This makes it more likely that the
|
||||
// entry state for each basic block will have the effects of its predecessors applied
|
||||
// before it is processed. In fact, for CFGs without back edges, this guarantees that
|
||||
// dataflow will converge in exactly `N` iterations, where `N` is the number of basic
|
||||
// blocks.
|
||||
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
|
||||
WorkQueue::with_none(body.basic_blocks().len());
|
||||
for (bb, _) in traversal::reverse_postorder(body) {
|
||||
dirty_queue.insert(bb);
|
||||
}
|
||||
|
||||
// Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
|
||||
// be processed after the ones added above.
|
||||
for bb in body.basic_blocks().indices() {
|
||||
dirty_queue.insert(bb);
|
||||
}
|
||||
|
||||
while let Some(bb) = dirty_queue.pop() {
|
||||
let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index());
|
||||
debug_assert!(in_out.words().len() == on_entry.words().len());
|
||||
|
|
|
|||
|
|
@ -75,9 +75,24 @@ pub fn liveness_of_locals<'tcx>(
|
|||
|
||||
let mut bits = LiveVarSet::new_empty(num_live_vars);
|
||||
|
||||
// queue of things that need to be re-processed, and a set containing
|
||||
// the things currently in the queue
|
||||
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(body.basic_blocks().len());
|
||||
// The dirty queue contains the set of basic blocks whose entry sets have changed since they
|
||||
// were last processed. At the start of the analysis, we initialize the queue in post-order to
|
||||
// make it more likely that the entry set for a given basic block will have the effects of all
|
||||
// its successors in the CFG applied before it is processed.
|
||||
//
|
||||
// FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
|
||||
// order when cycles are present, but the overhead of computing the reverse CFG may outweigh
|
||||
// any benefits. Benchmark this and find out.
|
||||
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks().len());
|
||||
for (bb, _) in traversal::postorder(body) {
|
||||
dirty_queue.insert(bb);
|
||||
}
|
||||
|
||||
// Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
|
||||
// be processed after the ones added above.
|
||||
for bb in body.basic_blocks().indices() {
|
||||
dirty_queue.insert(bb);
|
||||
}
|
||||
|
||||
let predecessors = body.predecessors();
|
||||
|
||||
|
|
|
|||
|
|
@ -837,13 +837,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
the relevant `fold_*()` method in `PlaceholderExpander`?");
|
||||
}
|
||||
|
||||
fn visit_fn_header(&mut self, header: &'a FnHeader) {
|
||||
if header.asyncness.node.is_async() && self.session.rust_2015() {
|
||||
struct_span_err!(self.session, header.asyncness.span, E0670,
|
||||
"`async fn` is not permitted in the 2015 edition").emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
|
||||
match ii.node {
|
||||
ImplItemKind::Method(ref sig, _) => {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use syntax_pos::Span;
|
|||
|
||||
use crate::html::escape::Escape;
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Cfg {
|
||||
/// Accepts all configurations.
|
||||
True,
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExternalCrate {
|
||||
pub name: String,
|
||||
pub src: FileName,
|
||||
|
|
@ -355,7 +355,7 @@ impl Clean<ExternalCrate> for CrateNum {
|
|||
/// Anything with a source location and set of attributes and, optionally, a
|
||||
/// name. That is, anything that can be documented. This doesn't correspond
|
||||
/// directly to the AST's concept of an item; it's a strict superset.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone)]
|
||||
pub struct Item {
|
||||
/// Stringified span
|
||||
pub source: Span,
|
||||
|
|
@ -528,7 +528,7 @@ impl Item {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ItemEnum {
|
||||
ExternCrateItem(String, Option<String>),
|
||||
ImportItem(Import),
|
||||
|
|
@ -594,7 +594,7 @@ impl ItemEnum {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Module {
|
||||
pub items: Vec<Item>,
|
||||
pub is_crate: bool,
|
||||
|
|
@ -731,7 +731,7 @@ impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
|
|||
/// Included files are kept separate from inline doc comments so that proper line-number
|
||||
/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
|
||||
/// kept separate because of issue #42760.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum DocFragment {
|
||||
/// A doc fragment created from a `///` or `//!` doc comment.
|
||||
SugaredDoc(usize, syntax_pos::Span, String),
|
||||
|
|
@ -781,7 +781,7 @@ impl<'a> FromIterator<&'a DocFragment> for String {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Attributes {
|
||||
pub doc_strings: Vec<DocFragment>,
|
||||
pub other_attrs: Vec<ast::Attribute>,
|
||||
|
|
@ -1048,7 +1048,7 @@ impl Clean<Attributes> for [ast::Attribute] {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericBound {
|
||||
TraitBound(PolyTrait, hir::TraitBoundModifier),
|
||||
Outlives(Lifetime),
|
||||
|
|
@ -1231,7 +1231,7 @@ impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Lifetime(String);
|
||||
|
||||
impl Lifetime {
|
||||
|
|
@ -1326,7 +1326,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum WherePredicate {
|
||||
BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
|
||||
RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
|
||||
|
|
@ -1464,7 +1464,7 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericParamDefKind {
|
||||
Lifetime,
|
||||
Type {
|
||||
|
|
@ -1498,7 +1498,7 @@ impl GenericParamDefKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct GenericParamDef {
|
||||
pub name: String,
|
||||
|
||||
|
|
@ -1610,7 +1610,7 @@ impl Clean<GenericParamDef> for hir::GenericParam {
|
|||
}
|
||||
|
||||
// maybe use a Generic enum and use Vec<Generic>?
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Default, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
|
||||
pub struct Generics {
|
||||
pub params: Vec<GenericParamDef>,
|
||||
pub where_predicates: Vec<WherePredicate>,
|
||||
|
|
@ -1874,7 +1874,7 @@ pub fn get_all_types(
|
|||
(all_types.into_iter().collect(), ret_types)
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Method {
|
||||
pub generics: Generics,
|
||||
pub decl: FnDecl,
|
||||
|
|
@ -1902,7 +1902,7 @@ impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId,
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TyMethod {
|
||||
pub header: hir::FnHeader,
|
||||
pub decl: FnDecl,
|
||||
|
|
@ -1911,7 +1911,7 @@ pub struct TyMethod {
|
|||
pub ret_types: Vec<Type>,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Function {
|
||||
pub decl: FnDecl,
|
||||
pub generics: Generics,
|
||||
|
|
@ -1952,7 +1952,7 @@ impl Clean<Item> for doctree::Function<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct FnDecl {
|
||||
pub inputs: Arguments,
|
||||
pub output: FunctionRetTy,
|
||||
|
|
@ -1989,7 +1989,7 @@ impl FnDecl {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Arguments {
|
||||
pub values: Vec<Argument>,
|
||||
}
|
||||
|
|
@ -2063,13 +2063,13 @@ impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Argument {
|
||||
pub type_: Type,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum SelfTy {
|
||||
SelfValue,
|
||||
SelfBorrowed(Option<Lifetime>, Mutability),
|
||||
|
|
@ -2093,7 +2093,7 @@ impl Argument {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum FunctionRetTy {
|
||||
Return(Type),
|
||||
DefaultReturn,
|
||||
|
|
@ -2117,7 +2117,7 @@ impl GetDefId for FunctionRetTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Trait {
|
||||
pub auto: bool,
|
||||
pub unsafety: hir::Unsafety,
|
||||
|
|
@ -2153,7 +2153,7 @@ impl Clean<Item> for doctree::Trait<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TraitAlias {
|
||||
pub generics: Generics,
|
||||
pub bounds: Vec<GenericBound>,
|
||||
|
|
@ -2437,7 +2437,7 @@ impl Clean<Item> for ty::AssocItem {
|
|||
}
|
||||
|
||||
/// A trait reference, which may have higher ranked lifetimes.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct PolyTrait {
|
||||
pub trait_: Type,
|
||||
pub generic_params: Vec<GenericParamDef>,
|
||||
|
|
@ -2446,7 +2446,7 @@ pub struct PolyTrait {
|
|||
/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
|
||||
/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
|
||||
/// importantly, it does not preserve mutability or boxes.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum Type {
|
||||
/// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
|
||||
ResolvedPath {
|
||||
|
|
@ -2469,7 +2469,6 @@ pub enum Type {
|
|||
Array(Box<Type>, String),
|
||||
Never,
|
||||
CVarArgs,
|
||||
Unique(Box<Type>),
|
||||
RawPointer(Mutability, Box<Type>),
|
||||
BorrowedRef {
|
||||
lifetime: Option<Lifetime>,
|
||||
|
|
@ -2491,7 +2490,7 @@ pub enum Type {
|
|||
ImplTrait(Vec<GenericBound>),
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
|
||||
pub enum PrimitiveType {
|
||||
Isize, I8, I16, I32, I64, I128,
|
||||
Usize, U8, U16, U32, U64, U128,
|
||||
|
|
@ -2510,7 +2509,7 @@ pub enum PrimitiveType {
|
|||
CVarArgs,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum TypeKind {
|
||||
Enum,
|
||||
Function,
|
||||
|
|
@ -2520,7 +2519,6 @@ pub enum TypeKind {
|
|||
Struct,
|
||||
Union,
|
||||
Trait,
|
||||
Variant,
|
||||
Typedef,
|
||||
Foreign,
|
||||
Macro,
|
||||
|
|
@ -3190,7 +3188,7 @@ impl Clean<Item> for ty::FieldDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Visibility {
|
||||
Public,
|
||||
Inherited,
|
||||
|
|
@ -3219,7 +3217,7 @@ impl Clean<Option<Visibility>> for ty::Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Struct {
|
||||
pub struct_type: doctree::StructType,
|
||||
pub generics: Generics,
|
||||
|
|
@ -3227,7 +3225,7 @@ pub struct Struct {
|
|||
pub fields_stripped: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Union {
|
||||
pub struct_type: doctree::StructType,
|
||||
pub generics: Generics,
|
||||
|
|
@ -3278,7 +3276,7 @@ impl Clean<Item> for doctree::Union<'_> {
|
|||
/// This is a more limited form of the standard Struct, different in that
|
||||
/// it lacks the things most items have (name, id, parameterization). Found
|
||||
/// only as a variant in an enum.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VariantStruct {
|
||||
pub struct_type: doctree::StructType,
|
||||
pub fields: Vec<Item>,
|
||||
|
|
@ -3295,7 +3293,7 @@ impl Clean<VariantStruct> for ::rustc::hir::VariantData {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Enum {
|
||||
pub variants: IndexVec<VariantIdx, Item>,
|
||||
pub generics: Generics,
|
||||
|
|
@ -3321,7 +3319,7 @@ impl Clean<Item> for doctree::Enum<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Variant {
|
||||
pub kind: VariantKind,
|
||||
}
|
||||
|
|
@ -3384,7 +3382,7 @@ impl Clean<Item> for ty::VariantDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VariantKind {
|
||||
CLike,
|
||||
Tuple(Vec<Type>),
|
||||
|
|
@ -3402,7 +3400,7 @@ impl Clean<VariantKind> for hir::VariantData {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Span {
|
||||
pub filename: FileName,
|
||||
pub loline: usize,
|
||||
|
|
@ -3448,7 +3446,7 @@ impl Clean<Span> for syntax_pos::Span {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Path {
|
||||
pub global: bool,
|
||||
pub res: Res,
|
||||
|
|
@ -3471,7 +3469,7 @@ impl Clean<Path> for hir::Path {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericArg {
|
||||
Lifetime(Lifetime),
|
||||
Type(Type),
|
||||
|
|
@ -3488,7 +3486,7 @@ impl fmt::Display for GenericArg {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericArgs {
|
||||
AngleBracketed {
|
||||
args: Vec<GenericArg>,
|
||||
|
|
@ -3528,7 +3526,7 @@ impl Clean<GenericArgs> for hir::GenericArgs {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct PathSegment {
|
||||
pub name: String,
|
||||
pub args: GenericArgs,
|
||||
|
|
@ -3553,7 +3551,6 @@ fn strip_type(ty: Type) -> Type {
|
|||
}
|
||||
Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))),
|
||||
Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s),
|
||||
Type::Unique(inner_ty) => Type::Unique(Box::new(strip_type(*inner_ty))),
|
||||
Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))),
|
||||
Type::BorrowedRef { lifetime, mutability, type_ } => {
|
||||
Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) }
|
||||
|
|
@ -3625,7 +3622,7 @@ impl Clean<String> for InternedString {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Typedef {
|
||||
pub type_: Type,
|
||||
pub generics: Generics,
|
||||
|
|
@ -3649,7 +3646,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Existential {
|
||||
pub bounds: Vec<GenericBound>,
|
||||
pub generics: Generics,
|
||||
|
|
@ -3673,7 +3670,7 @@ impl Clean<Item> for doctree::Existential<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct BareFunctionDecl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub generic_params: Vec<GenericParamDef>,
|
||||
|
|
@ -3695,7 +3692,7 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Static {
|
||||
pub type_: Type,
|
||||
pub mutability: Mutability,
|
||||
|
|
@ -3725,7 +3722,7 @@ impl Clean<Item> for doctree::Static<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Constant {
|
||||
pub type_: Type,
|
||||
pub expr: String,
|
||||
|
|
@ -3749,7 +3746,7 @@ impl Clean<Item> for doctree::Constant<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
|
||||
pub enum Mutability {
|
||||
Mutable,
|
||||
Immutable,
|
||||
|
|
@ -3764,7 +3761,7 @@ impl Clean<Mutability> for hir::Mutability {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)]
|
||||
pub enum ImplPolarity {
|
||||
Positive,
|
||||
Negative,
|
||||
|
|
@ -3779,7 +3776,7 @@ impl Clean<ImplPolarity> for hir::ImplPolarity {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Impl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub generics: Generics,
|
||||
|
|
@ -4003,7 +4000,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Import {
|
||||
// use source as str;
|
||||
Simple(String, ImportSource),
|
||||
|
|
@ -4011,7 +4008,7 @@ pub enum Import {
|
|||
Glob(ImportSource)
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ImportSource {
|
||||
pub path: Path,
|
||||
pub did: Option<DefId>,
|
||||
|
|
@ -4227,7 +4224,7 @@ fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Macro {
|
||||
pub source: String,
|
||||
pub imported_from: Option<String>,
|
||||
|
|
@ -4256,7 +4253,7 @@ impl Clean<Item> for doctree::Macro<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProcMacro {
|
||||
pub kind: MacroKind,
|
||||
pub helpers: Vec<String>,
|
||||
|
|
@ -4280,7 +4277,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Stability {
|
||||
pub level: stability::StabilityLevel,
|
||||
pub feature: Option<String>,
|
||||
|
|
@ -4290,7 +4287,7 @@ pub struct Stability {
|
|||
pub issue: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Deprecation {
|
||||
pub since: Option<String>,
|
||||
pub note: Option<String>,
|
||||
|
|
@ -4340,13 +4337,13 @@ impl Clean<Deprecation> for attr::Deprecation {
|
|||
|
||||
/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
|
||||
/// `A: Send + Sync` in `Foo<A: Send + Sync>`).
|
||||
#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct TypeBinding {
|
||||
pub name: String,
|
||||
pub kind: TypeBindingKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum TypeBindingKind {
|
||||
Equality {
|
||||
ty: Type,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ impl Module<'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, RustcEncodable, RustcDecodable, Copy)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum StructType {
|
||||
/// A braced struct
|
||||
Plain,
|
||||
|
|
|
|||
|
|
@ -737,9 +737,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
clean::Unique(..) => {
|
||||
panic!("should have been cleaned")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ impl From<clean::TypeKind> for ItemType {
|
|||
clean::TypeKind::Module => ItemType::Module,
|
||||
clean::TypeKind::Static => ItemType::Static,
|
||||
clean::TypeKind::Const => ItemType::Constant,
|
||||
clean::TypeKind::Variant => ItemType::Variant,
|
||||
clean::TypeKind::Typedef => ItemType::Typedef,
|
||||
clean::TypeKind::Foreign => ItemType::ForeignType,
|
||||
clean::TypeKind::Macro => ItemType::Macro,
|
||||
|
|
|
|||
|
|
@ -5188,9 +5188,6 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> {
|
|||
clean::Type::Array(ty, _) => {
|
||||
work.push_back(*ty);
|
||||
},
|
||||
clean::Type::Unique(ty) => {
|
||||
work.push_back(*ty);
|
||||
},
|
||||
clean::Type::RawPointer(_, ty) => {
|
||||
work.push_back(*ty);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ extern crate test as testing;
|
|||
#[macro_use] extern crate log;
|
||||
extern crate rustc_errors as errors;
|
||||
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
||||
use std::default::Default;
|
||||
use std::env;
|
||||
use std::panic;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,9 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
|
|||
HOOK_LOCK.write_unlock();
|
||||
|
||||
if let Hook::Custom(ptr) = old_hook {
|
||||
Box::from_raw(ptr);
|
||||
#[allow(unused_must_use)] {
|
||||
Box::from_raw(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5734,9 +5734,12 @@ impl<'a> Parser<'a> {
|
|||
{
|
||||
let is_const_fn = self.eat_keyword(kw::Const);
|
||||
let const_span = self.prev_span;
|
||||
let unsafety = self.parse_unsafety();
|
||||
let asyncness = self.parse_asyncness();
|
||||
if let IsAsync::Async { .. } = asyncness {
|
||||
self.ban_async_in_2015(self.prev_span);
|
||||
}
|
||||
let asyncness = respan(self.prev_span, asyncness);
|
||||
let unsafety = self.parse_unsafety();
|
||||
let (constness, unsafety, abi) = if is_const_fn {
|
||||
(respan(const_span, Constness::Const), unsafety, Abi::Rust)
|
||||
} else {
|
||||
|
|
@ -7254,13 +7257,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
if self.token.span.rust_2015() {
|
||||
self.diagnostic().struct_span_err_with_code(
|
||||
async_span,
|
||||
"`async fn` is not permitted in the 2015 edition",
|
||||
DiagnosticId::Error("E0670".into())
|
||||
).emit();
|
||||
}
|
||||
self.ban_async_in_2015(async_span);
|
||||
return Ok(Some(item));
|
||||
}
|
||||
}
|
||||
|
|
@ -7534,6 +7531,19 @@ impl<'a> Parser<'a> {
|
|||
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
|
||||
}
|
||||
|
||||
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
|
||||
fn ban_async_in_2015(&self, async_span: Span) {
|
||||
if async_span.rust_2015() {
|
||||
self.diagnostic()
|
||||
.struct_span_err_with_code(
|
||||
async_span,
|
||||
"`async fn` is not permitted in the 2015 edition",
|
||||
DiagnosticId::Error("E0670".into())
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a foreign item.
|
||||
crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
|
||||
maybe_whole!(self, NtForeignItem, |ni| ni);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ pub enum Handler {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
take(Handler::Default, Box::new(main));
|
||||
#[allow(unused_must_use)] {
|
||||
take(Handler::Default, Box::new(main));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// run-pass
|
||||
|
||||
#![allow(stable_features)]
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
|
|
|
|||
|
|
@ -134,11 +134,15 @@ trait Bar {
|
|||
}
|
||||
|
||||
impl Foo {
|
||||
async fn async_method(x: u8) -> u8 {
|
||||
async fn async_assoc_item(x: u8) -> u8 {
|
||||
unsafe {
|
||||
unsafe_async_fn(x).await
|
||||
}
|
||||
}
|
||||
|
||||
async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 {
|
||||
unsafe_async_fn(x).await
|
||||
}
|
||||
}
|
||||
|
||||
fn test_future_yields_once_then_returns<F, Fut>(f: F)
|
||||
|
|
@ -180,12 +184,17 @@ fn main() {
|
|||
async_fn,
|
||||
generic_async_fn,
|
||||
async_fn_with_internal_borrow,
|
||||
Foo::async_method,
|
||||
Foo::async_assoc_item,
|
||||
|x| {
|
||||
async move {
|
||||
unsafe { unsafe_async_fn(x).await }
|
||||
}
|
||||
},
|
||||
|x| {
|
||||
async move {
|
||||
unsafe { Foo::async_unsafe_assoc_item(x).await }
|
||||
}
|
||||
},
|
||||
}
|
||||
test_with_borrow! {
|
||||
async_block_with_borrow_named_lifetime,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ fn main() {
|
|||
async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
|
||||
}
|
||||
|
||||
accept_item! {
|
||||
impl Foo {
|
||||
async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
|
||||
}
|
||||
}
|
||||
|
||||
let inside_closure = || {
|
||||
async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,19 @@ LL | async fn async_baz() {
|
|||
| ^^^^^
|
||||
|
||||
error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:32:9
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:16:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^
|
||||
|
||||
error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:20:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^
|
||||
|
||||
error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:38:9
|
||||
|
|
||||
LL | async fn bar() {}
|
||||
| ^^^^^
|
||||
|
|
@ -35,10 +47,10 @@ LL | async fn foo() {}
|
|||
| ^^^^^
|
||||
|
||||
error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:16:5
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:33:13
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^
|
||||
LL | async fn bar() {}
|
||||
| ^^^^^
|
||||
|
||||
error[E0706]: trait fns cannot be declared `async`
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:20:5
|
||||
|
|
@ -46,12 +58,6 @@ error[E0706]: trait fns cannot be declared `async`
|
|||
LL | async fn foo() {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
--> $DIR/edition-deny-async-fns-2015.rs:20:5
|
||||
|
|
||||
LL | async fn foo() {}
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0670`.
|
||||
|
|
|
|||
11
src/test/ui/async-await/no-unsafe-async.rs
Normal file
11
src/test/ui/async-await/no-unsafe-async.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// edition:2018
|
||||
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
#[cfg(FALSE)]
|
||||
unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found `async`
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found `async`
|
||||
14
src/test/ui/async-await/no-unsafe-async.stderr
Normal file
14
src/test/ui/async-await/no-unsafe-async.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error: expected one of `extern` or `fn`, found `async`
|
||||
--> $DIR/no-unsafe-async.rs:7:12
|
||||
|
|
||||
LL | unsafe async fn g() {}
|
||||
| ^^^^^ expected one of `extern` or `fn` here
|
||||
|
||||
error: expected one of `extern`, `fn`, or `{`, found `async`
|
||||
--> $DIR/no-unsafe-async.rs:11:8
|
||||
|
|
||||
LL | unsafe async fn f() {}
|
||||
| ^^^^^ expected one of `extern`, `fn`, or `{` here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
47
src/test/ui/lint/must_use-array.rs
Normal file
47
src/test/ui/lint/must_use-array.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#![deny(unused_must_use)]
|
||||
|
||||
#[must_use]
|
||||
struct S;
|
||||
|
||||
struct A;
|
||||
|
||||
#[must_use]
|
||||
trait T {}
|
||||
|
||||
impl T for A {}
|
||||
|
||||
fn empty() -> [S; 0] {
|
||||
[]
|
||||
}
|
||||
|
||||
fn singleton() -> [S; 1] {
|
||||
[S]
|
||||
}
|
||||
|
||||
fn many() -> [S; 4] {
|
||||
[S, S, S, S]
|
||||
}
|
||||
|
||||
fn array_of_impl_trait() -> [impl T; 2] {
|
||||
[A, A]
|
||||
}
|
||||
|
||||
fn impl_array() -> [(u8, Box<dyn T>); 2] {
|
||||
[(0, Box::new(A)), (0, Box::new(A))]
|
||||
}
|
||||
|
||||
fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
|
||||
[[[S], [S]]]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
empty(); // ok
|
||||
singleton(); //~ ERROR unused array of `S` that must be used
|
||||
many(); //~ ERROR unused array of `S` that must be used
|
||||
([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used
|
||||
array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used
|
||||
impl_array();
|
||||
//~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
|
||||
array_of_arrays_of_arrays();
|
||||
//~^ ERROR unused array of arrays of arrays of `S` that must be used
|
||||
}
|
||||
44
src/test/ui/lint/must_use-array.stderr
Normal file
44
src/test/ui/lint/must_use-array.stderr
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
error: unused array of `S` that must be used
|
||||
--> $DIR/must_use-array.rs:39:5
|
||||
|
|
||||
LL | singleton();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/must_use-array.rs:1:9
|
||||
|
|
||||
LL | #![deny(unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused array of `S` that must be used
|
||||
--> $DIR/must_use-array.rs:40:5
|
||||
|
|
||||
LL | many();
|
||||
| ^^^^^^^
|
||||
|
||||
error: unused array of `S` in tuple element 0 that must be used
|
||||
--> $DIR/must_use-array.rs:41:6
|
||||
|
|
||||
LL | ([S], 0, ());
|
||||
| ^^^
|
||||
|
||||
error: unused array of implementers of `T` that must be used
|
||||
--> $DIR/must_use-array.rs:42:5
|
||||
|
|
||||
LL | array_of_impl_trait();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused array of boxed `T` trait objects in tuple element 1 that must be used
|
||||
--> $DIR/must_use-array.rs:43:5
|
||||
|
|
||||
LL | impl_array();
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: unused array of arrays of arrays of `S` that must be used
|
||||
--> $DIR/must_use-array.rs:45:5
|
||||
|
|
||||
LL | array_of_arrays_of_arrays();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
@ -17,6 +17,23 @@ fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant {
|
|||
Anon {}
|
||||
}
|
||||
|
||||
fn get_boxed_critical() -> Box<dyn Critical> {
|
||||
Box::new(Anon {})
|
||||
}
|
||||
|
||||
fn get_nested_boxed_critical() -> Box<Box<dyn Critical>> {
|
||||
Box::new(Box::new(Anon {}))
|
||||
}
|
||||
|
||||
fn get_critical_tuple() -> (u32, Box<dyn Critical>, impl Critical, ()) {
|
||||
(0, get_boxed_critical(), get_critical(), ())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
get_critical(); //~ ERROR unused implementer of `Critical` that must be used
|
||||
get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used
|
||||
get_nested_boxed_critical();
|
||||
//~^ ERROR unused boxed boxed `Critical` trait object that must be used
|
||||
get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1
|
||||
//~^ ERROR unused implementer of `Critical` in tuple element 2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: unused implementer of `Critical` that must be used
|
||||
--> $DIR/must_use-trait.rs:21:5
|
||||
--> $DIR/must_use-trait.rs:33:5
|
||||
|
|
||||
LL | get_critical();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
@ -10,5 +10,29 @@ note: lint level defined here
|
|||
LL | #![deny(unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: unused boxed `Critical` trait object that must be used
|
||||
--> $DIR/must_use-trait.rs:34:5
|
||||
|
|
||||
LL | get_boxed_critical();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused boxed boxed `Critical` trait object that must be used
|
||||
--> $DIR/must_use-trait.rs:35:5
|
||||
|
|
||||
LL | get_nested_boxed_critical();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused boxed `Critical` trait object in tuple element 1 that must be used
|
||||
--> $DIR/must_use-trait.rs:37:5
|
||||
|
|
||||
LL | get_critical_tuple();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused implementer of `Critical` in tuple element 2 that must be used
|
||||
--> $DIR/must_use-trait.rs:37:5
|
||||
|
|
||||
LL | get_critical_tuple();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 945f007c0d305c3ec069b5e5d911ef783f6d70e7
|
||||
Subproject commit 72b2e1045d642c517347c421b1db92e34c22a70d
|
||||
Loading…
Add table
Add a link
Reference in a new issue