1
Fork 0

Auto merge of #80364 - Dylan-DPC:rollup-0y96okz, r=Dylan-DPC

Rollup of 11 pull requests

Successful merges:

 - #79213 (Stabilize `core::slice::fill`)
 - #79999 (Refactored verbose print into a function)
 - #80160 (Implemented a compiler diagnostic for move async mistake)
 - #80274 (Rename rustc_middle::lint::LintSource)
 - #80280 (Add installation commands to `x` tool README)
 - #80319 (Fix elided lifetimes shown as `'_` on async functions)
 - #80327 (Updated the match with the matches macro)
 - #80330 (Fix typo in simplify_try.rs)
 - #80340 (Don't unnecessarily override attrs for Module)
 - #80342 (Fix typo)
 - #80352 (BTreeMap: make test cases more explicit on failure)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2020-12-25 05:23:24 +00:00
commit 9a40539c38
32 changed files with 203 additions and 105 deletions

View file

@ -12,7 +12,9 @@ use rustc_hir::{intravisit, HirId};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::lint::LevelSource; use rustc_middle::lint::LevelSource;
use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc_middle::lint::{
struct_lint_level, LintLevelMap, LintLevelSets, LintLevelSource, LintSet,
};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::lint::{builtin, Level, Lint, LintId}; use rustc_session::lint::{builtin, Level, Lint, LintId};
@ -91,7 +93,7 @@ impl<'s> LintLevelsBuilder<'s> {
}; };
for id in ids { for id in ids {
self.check_gated_lint(id, DUMMY_SP); self.check_gated_lint(id, DUMMY_SP);
let src = LintSource::CommandLine(lint_flag_val, orig_level); let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
specs.insert(id, (level, src)); specs.insert(id, (level, src));
} }
} }
@ -128,19 +130,19 @@ impl<'s> LintLevelsBuilder<'s> {
); );
diag_builder.span_label(src.span(), "overruled by previous forbid"); diag_builder.span_label(src.span(), "overruled by previous forbid");
match old_src { match old_src {
LintSource::Default => { LintLevelSource::Default => {
diag_builder.note(&format!( diag_builder.note(&format!(
"`forbid` lint level is the default for {}", "`forbid` lint level is the default for {}",
id.to_string() id.to_string()
)); ));
} }
LintSource::Node(_, forbid_source_span, reason) => { LintLevelSource::Node(_, forbid_source_span, reason) => {
diag_builder.span_label(forbid_source_span, "`forbid` level set here"); diag_builder.span_label(forbid_source_span, "`forbid` level set here");
if let Some(rationale) = reason { if let Some(rationale) = reason {
diag_builder.note(&rationale.as_str()); diag_builder.note(&rationale.as_str());
} }
} }
LintSource::CommandLine(_, _) => { LintLevelSource::CommandLine(_, _) => {
diag_builder.note("`forbid` lint level was set on command line"); diag_builder.note("`forbid` lint level was set on command line");
} }
} }
@ -276,7 +278,7 @@ impl<'s> LintLevelsBuilder<'s> {
let name = meta_item.path.segments.last().expect("empty lint name").ident.name; let name = meta_item.path.segments.last().expect("empty lint name").ident.name;
match store.check_lint_name(&name.as_str(), tool_name) { match store.check_lint_name(&name.as_str(), tool_name) {
CheckLintNameResult::Ok(ids) => { CheckLintNameResult::Ok(ids) => {
let src = LintSource::Node(name, li.span(), reason); let src = LintLevelSource::Node(name, li.span(), reason);
for &id in ids { for &id in ids {
self.check_gated_lint(id, attr.span); self.check_gated_lint(id, attr.span);
self.insert_spec(&mut specs, id, (level, src)); self.insert_spec(&mut specs, id, (level, src));
@ -287,7 +289,7 @@ impl<'s> LintLevelsBuilder<'s> {
match result { match result {
Ok(ids) => { Ok(ids) => {
let complete_name = &format!("{}::{}", tool_name.unwrap(), name); let complete_name = &format!("{}::{}", tool_name.unwrap(), name);
let src = LintSource::Node( let src = LintLevelSource::Node(
Symbol::intern(complete_name), Symbol::intern(complete_name),
li.span(), li.span(),
reason, reason,
@ -324,7 +326,7 @@ impl<'s> LintLevelsBuilder<'s> {
}, },
); );
let src = LintSource::Node( let src = LintLevelSource::Node(
Symbol::intern(&new_lint_name), Symbol::intern(&new_lint_name),
li.span(), li.span(),
reason, reason,
@ -403,7 +405,7 @@ impl<'s> LintLevelsBuilder<'s> {
} }
let (lint_attr_name, lint_attr_span) = match *src { let (lint_attr_name, lint_attr_span) = match *src {
LintSource::Node(name, span, _) => (name, span), LintLevelSource::Node(name, span, _) => (name, span),
_ => continue, _ => continue,
}; };
@ -460,7 +462,7 @@ impl<'s> LintLevelsBuilder<'s> {
} }
/// Find the lint level for a lint. /// Find the lint level for a lint.
pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintSource) { pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintLevelSource) {
self.sets.get_lint_level(lint, self.cur, None, self.sess) self.sets.get_lint_level(lint, self.cur, None, self.sess)
} }

View file

@ -13,7 +13,7 @@ use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
/// How a lint level was set. /// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq, HashStable)] #[derive(Clone, Copy, PartialEq, Eq, HashStable)]
pub enum LintSource { pub enum LintLevelSource {
/// Lint is at the default level as declared /// Lint is at the default level as declared
/// in rustc or a plugin. /// in rustc or a plugin.
Default, Default,
@ -27,25 +27,26 @@ pub enum LintSource {
CommandLine(Symbol, Level), CommandLine(Symbol, Level),
} }
impl LintSource { impl LintLevelSource {
pub fn name(&self) -> Symbol { pub fn name(&self) -> Symbol {
match *self { match *self {
LintSource::Default => symbol::kw::Default, LintLevelSource::Default => symbol::kw::Default,
LintSource::Node(name, _, _) => name, LintLevelSource::Node(name, _, _) => name,
LintSource::CommandLine(name, _) => name, LintLevelSource::CommandLine(name, _) => name,
} }
} }
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match *self {
LintSource::Default => DUMMY_SP, LintLevelSource::Default => DUMMY_SP,
LintSource::Node(_, span, _) => span, LintLevelSource::Node(_, span, _) => span,
LintSource::CommandLine(_, _) => DUMMY_SP, LintLevelSource::CommandLine(_, _) => DUMMY_SP,
} }
} }
} }
pub type LevelSource = (Level, LintSource); /// A tuple of a lint level and its source.
pub type LevelSource = (Level, LintLevelSource);
pub struct LintLevelSets { pub struct LintLevelSets {
pub list: Vec<LintSet>, pub list: Vec<LintSet>,
@ -113,7 +114,7 @@ impl LintLevelSets {
id: LintId, id: LintId,
mut idx: u32, mut idx: u32,
aux: Option<&FxHashMap<LintId, LevelSource>>, aux: Option<&FxHashMap<LintId, LevelSource>>,
) -> (Option<Level>, LintSource) { ) -> (Option<Level>, LintLevelSource) {
if let Some(specs) = aux { if let Some(specs) = aux {
if let Some(&(level, src)) = specs.get(&id) { if let Some(&(level, src)) = specs.get(&id) {
return (Some(level), src); return (Some(level), src);
@ -125,7 +126,7 @@ impl LintLevelSets {
if let Some(&(level, src)) = specs.get(&id) { if let Some(&(level, src)) = specs.get(&id) {
return (Some(level), src); return (Some(level), src);
} }
return (None, LintSource::Default); return (None, LintLevelSource::Default);
} }
LintSet::Node { ref specs, parent } => { LintSet::Node { ref specs, parent } => {
if let Some(&(level, src)) = specs.get(&id) { if let Some(&(level, src)) = specs.get(&id) {
@ -213,7 +214,7 @@ pub fn struct_lint_level<'s, 'd>(
sess: &'s Session, sess: &'s Session,
lint: &'static Lint, lint: &'static Lint,
level: Level, level: Level,
src: LintSource, src: LintLevelSource,
span: Option<MultiSpan>, span: Option<MultiSpan>,
decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd, decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd,
) { ) {
@ -223,7 +224,7 @@ pub fn struct_lint_level<'s, 'd>(
sess: &'s Session, sess: &'s Session,
lint: &'static Lint, lint: &'static Lint,
level: Level, level: Level,
src: LintSource, src: LintLevelSource,
span: Option<MultiSpan>, span: Option<MultiSpan>,
decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b>) + 'd>, decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b>) + 'd>,
) { ) {
@ -274,14 +275,14 @@ pub fn struct_lint_level<'s, 'd>(
let name = lint.name_lower(); let name = lint.name_lower();
match src { match src {
LintSource::Default => { LintLevelSource::Default => {
sess.diag_note_once( sess.diag_note_once(
&mut err, &mut err,
DiagnosticMessageId::from(lint), DiagnosticMessageId::from(lint),
&format!("`#[{}({})]` on by default", level.as_str(), name), &format!("`#[{}({})]` on by default", level.as_str(), name),
); );
} }
LintSource::CommandLine(lint_flag_val, orig_level) => { LintLevelSource::CommandLine(lint_flag_val, orig_level) => {
let flag = match orig_level { let flag = match orig_level {
Level::Warn => "-W", Level::Warn => "-W",
Level::Deny => "-D", Level::Deny => "-D",
@ -310,7 +311,7 @@ pub fn struct_lint_level<'s, 'd>(
); );
} }
} }
LintSource::Node(lint_attr_name, src, reason) => { LintLevelSource::Node(lint_attr_name, src, reason) => {
if let Some(rationale) = reason { if let Some(rationale) = reason {
err.note(&rationale.as_str()); err.note(&rationale.as_str());
} }

View file

@ -5,7 +5,7 @@ use crate::dep_graph::{self, DepGraph, DepKind, DepNode, DepNodeExt};
use crate::hir::exports::ExportMap; use crate::hir::exports::ExportMap;
use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::ich::{NodeIdHashingMode, StableHashingContext};
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintSource}; use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
use crate::middle; use crate::middle;
use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata}; use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
@ -2559,7 +2559,7 @@ impl<'tcx> TyCtxt<'tcx> {
self, self,
lint: &'static Lint, lint: &'static Lint,
mut id: hir::HirId, mut id: hir::HirId,
) -> (Level, LintSource) { ) -> (Level, LintLevelSource) {
let sets = self.lint_levels(LOCAL_CRATE); let sets = self.lint_levels(LOCAL_CRATE);
loop { loop {
if let Some(pair) = sets.level_and_source(lint, id, self.sess) { if let Some(pair) = sets.level_and_source(lint, id, self.sess) {

View file

@ -24,7 +24,7 @@ extern "C" {
/// This means we can use pointer for both /// This means we can use pointer for both
/// equality comparisons and hashing. /// equality comparisons and hashing.
/// ///
/// Unlike slices, The types contained in `List` are expected to be `Copy` /// Unlike slices, the types contained in `List` are expected to be `Copy`
/// and iterating over a `List` returns `T` instead of a reference. /// and iterating over a `List` returns `T` instead of a reference.
/// ///
/// Note: `Slice` was already taken by the `Ty`. /// Note: `Slice` was already taken by the `Ty`.

View file

@ -215,10 +215,7 @@ pub enum TyKind<'tcx> {
impl TyKind<'tcx> { impl TyKind<'tcx> {
#[inline] #[inline]
pub fn is_primitive(&self) -> bool { pub fn is_primitive(&self) -> bool {
match self { matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
Bool | Char | Int(_) | Uint(_) | Float(_) => true,
_ => false,
}
} }
/// Get the article ("a" or "an") to use with this type. /// Get the article ("a" or "an") to use with this type.

View file

@ -306,7 +306,7 @@ fn optimization_applies<'tcx>(
return false; return false;
} }
// Verify the assigment chain consists of the form b = a; c = b; d = c; etc... // Verify the assignment chain consists of the form b = a; c = b; d = c; etc...
if opt_info.field_tmp_assignments.is_empty() { if opt_info.field_tmp_assignments.is_empty() {
trace!("NO: no assignments found"); trace!("NO: no assignments found");
return false; return false;

View file

@ -17,7 +17,7 @@ use rustc_middle::mir::interpret::{
}; };
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_middle::ty::{self, TyCtxt, TyS, TypeFoldable, TypeVisitor};
use rustc_target::abi::Size; use rustc_target::abi::Size;
use std::ops::ControlFlow; use std::ops::ControlFlow;
@ -408,6 +408,18 @@ impl ExtraComments<'tcx> {
} }
} }
fn use_verbose(ty: &&TyS<'tcx>) -> bool {
match ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => false,
// Unit type
ty::Tuple(g_args) if g_args.is_empty() => false,
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(&g_arg.expect_ty())),
ty::Array(ty, _) => use_verbose(ty),
ty::FnDef(..) => false,
_ => true,
}
}
impl Visitor<'tcx> for ExtraComments<'tcx> { impl Visitor<'tcx> for ExtraComments<'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location); self.super_constant(constant, location);
@ -430,16 +442,10 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) { fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
self.super_const(constant); self.super_const(constant);
let ty::Const { ty, val, .. } = constant; let ty::Const { ty, val, .. } = constant;
match ty.kind() { if use_verbose(ty) {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => {} self.push("ty::Const");
// Unit type self.push(&format!("+ ty: {:?}", ty));
ty::Tuple(tys) if tys.is_empty() => {} self.push(&format!("+ val: {:?}", val));
ty::FnDef(..) => {}
_ => {
self.push("ty::Const");
self.push(&format!("+ ty: {:?}", ty));
self.push(&format!("+ val: {:?}", val));
}
} }
} }

View file

@ -1912,4 +1912,22 @@ impl<'a> Parser<'a> {
*self = snapshot; *self = snapshot;
Err(err) Err(err)
} }
/// Get the diagnostics for the cases where `move async` is found.
///
/// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
pub(super) fn incorrect_move_async_order_found(
&self,
move_async_span: Span,
) -> DiagnosticBuilder<'a> {
let mut err =
self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect");
err.span_suggestion_verbose(
move_async_span,
"try switching the order",
"async move".to_owned(),
Applicability::MaybeIncorrect,
);
err
}
} }

View file

@ -1603,7 +1603,7 @@ impl<'a> Parser<'a> {
self.sess.gated_spans.gate(sym::async_closure, span); self.sess.gated_spans.gate(sym::async_closure, span);
} }
let capture_clause = self.parse_capture_clause(); let capture_clause = self.parse_capture_clause()?;
let decl = self.parse_fn_block_decl()?; let decl = self.parse_fn_block_decl()?;
let decl_hi = self.prev_token.span; let decl_hi = self.prev_token.span;
let body = match decl.output { let body = match decl.output {
@ -1626,8 +1626,18 @@ impl<'a> Parser<'a> {
} }
/// Parses an optional `move` prefix to a closure-like construct. /// Parses an optional `move` prefix to a closure-like construct.
fn parse_capture_clause(&mut self) -> CaptureBy { fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref } if self.eat_keyword(kw::Move) {
// Check for `move async` and recover
if self.check_keyword(kw::Async) {
let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
Err(self.incorrect_move_async_order_found(move_async_span))
} else {
Ok(CaptureBy::Value)
}
} else {
Ok(CaptureBy::Ref)
}
} }
/// Parses the `|arg, arg|` header of a closure. /// Parses the `|arg, arg|` header of a closure.
@ -2019,7 +2029,7 @@ impl<'a> Parser<'a> {
fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> { fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
let lo = self.token.span; let lo = self.token.span;
self.expect_keyword(kw::Async)?; self.expect_keyword(kw::Async)?;
let capture_clause = self.parse_capture_clause(); let capture_clause = self.parse_capture_clause()?;
let (iattrs, body) = self.parse_inner_attrs_and_block()?; let (iattrs, body) = self.parse_inner_attrs_and_block()?;
attrs.extend(iattrs); attrs.extend(iattrs);
let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body); let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);

View file

@ -115,7 +115,7 @@ impl<K, V> BTreeMap<K, V> {
impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> { impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> {
fn assert_min_len(self, min_len: usize) { fn assert_min_len(self, min_len: usize) {
assert!(self.len() >= min_len, "{} < {}", self.len(), min_len); assert!(self.len() >= min_len, "node len {} < {}", self.len(), min_len);
if let node::ForceResult::Internal(node) = self.force() { if let node::ForceResult::Internal(node) = self.force() {
for idx in 0..=node.len() { for idx in 0..=node.len() {
let edge = unsafe { Handle::new_edge(node, idx) }; let edge = unsafe { Handle::new_edge(node, idx) };

View file

@ -30,11 +30,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
let depth = self.height(); let depth = self.height();
let indent = " ".repeat(depth); let indent = " ".repeat(depth);
result += &format!("\n{}", indent); result += &format!("\n{}", indent);
for idx in 0..leaf.len() { if leaf.len() == 0 {
if idx > 0 { result += "(empty node)";
result += ", "; } else {
for idx in 0..leaf.len() {
if idx > 0 {
result += ", ";
}
result += &format!("{:?}", unsafe { leaf.key_at(idx) });
} }
result += &format!("{:?}", unsafe { leaf.key_at(idx) });
} }
} }
navigate::Position::Internal(_) => {} navigate::Position::Internal(_) => {}

View file

@ -2581,14 +2581,12 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(slice_fill)]
///
/// let mut buf = vec![0; 10]; /// let mut buf = vec![0; 10];
/// buf.fill(1); /// buf.fill(1);
/// assert_eq!(buf, vec![1; 10]); /// assert_eq!(buf, vec![1; 10]);
/// ``` /// ```
#[doc(alias = "memset")] #[doc(alias = "memset")]
#[unstable(feature = "slice_fill", issue = "70758")] #[stable(feature = "slice_fill", since = "1.50.0")]
pub fn fill(&mut self, value: T) pub fn fill(&mut self, value: T)
where where
T: Clone, T: Clone,

View file

@ -304,7 +304,6 @@
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(shrink_to)] #![feature(shrink_to)]
#![feature(slice_concat_ext)] #![feature(slice_concat_ext)]
#![feature(slice_fill)]
#![feature(slice_internals)] #![feature(slice_internals)]
#![feature(slice_ptr_get)] #![feature(slice_ptr_get)]
#![feature(slice_ptr_len)] #![feature(slice_ptr_len)]

View file

@ -218,11 +218,6 @@ impl Clean<ExternalCrate> for CrateNum {
impl Clean<Item> for doctree::Module<'_> { impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item { fn clean(&self, cx: &DocContext<'_>) -> Item {
// maintain a stack of mod ids, for doc comment path resolution
// but we also need to resolve the module's own docs based on whether its docs were written
// inside or outside the module, so check for that
let attrs = self.attrs.clean(cx);
let mut items: Vec<Item> = vec![]; let mut items: Vec<Item> = vec![];
items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
@ -251,7 +246,7 @@ impl Clean<Item> for doctree::Module<'_> {
ModuleItem(Module { is_crate: self.is_crate, items }), ModuleItem(Module { is_crate: self.is_crate, items }),
cx, cx,
); );
Item { attrs, source: span.clean(cx), ..what_rustc_thinks } Item { source: span.clean(cx), ..what_rustc_thinks }
} }
} }
@ -638,6 +633,18 @@ impl Clean<Generics> for hir::Generics<'_> {
_ => false, _ => false,
} }
} }
/// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`.
///
/// See [`lifetime_to_generic_param`] in [`rustc_ast_lowering`] for more information.
///
/// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param
fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
match param.kind {
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } => true,
_ => false,
}
}
let impl_trait_params = self let impl_trait_params = self
.params .params
.iter() .iter()
@ -656,7 +663,7 @@ impl Clean<Generics> for hir::Generics<'_> {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut params = Vec::with_capacity(self.params.len()); let mut params = Vec::with_capacity(self.params.len());
for p in self.params.iter().filter(|p| !is_impl_trait(p)) { for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
let p = p.clean(cx); let p = p.clean(cx);
params.push(p); params.push(p);
} }
@ -1437,7 +1444,16 @@ impl Clean<Type> for hir::Ty<'_> {
TyKind::Never => Never, TyKind::Never => Never,
TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)), TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
TyKind::Rptr(ref l, ref m) => { TyKind::Rptr(ref l, ref m) => {
let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) }; // There are two times a `Fresh` lifetime can be created:
// 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
// 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`.
// See #59286 for more information.
// Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it.
// Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
// there's no case where it could cause the function to fail to compile.
let elided =
l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_)));
let lifetime = if elided { None } else { Some(l.clean(cx)) };
BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) } BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
} }
TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),

View file

@ -9,7 +9,6 @@ use rustc_hir as hir;
crate struct Module<'hir> { crate struct Module<'hir> {
crate name: Option<Symbol>, crate name: Option<Symbol>,
crate attrs: &'hir [ast::Attribute],
crate where_outer: Span, crate where_outer: Span,
crate where_inner: Span, crate where_inner: Span,
crate imports: Vec<Import<'hir>>, crate imports: Vec<Import<'hir>>,
@ -23,13 +22,12 @@ crate struct Module<'hir> {
} }
impl Module<'hir> { impl Module<'hir> {
crate fn new(name: Option<Symbol>, attrs: &'hir [ast::Attribute]) -> Module<'hir> { crate fn new(name: Option<Symbol>) -> Module<'hir> {
Module { Module {
name, name,
id: hir::CRATE_HIR_ID, id: hir::CRATE_HIR_ID,
where_outer: rustc_span::DUMMY_SP, where_outer: rustc_span::DUMMY_SP,
where_inner: rustc_span::DUMMY_SP, where_inner: rustc_span::DUMMY_SP,
attrs,
imports: Vec::new(), imports: Vec::new(),
mods: Vec::new(), mods: Vec::new(),
items: Vec::new(), items: Vec::new(),

View file

@ -5,7 +5,7 @@ use crate::html::markdown::{find_testable_code, ErrorCodes};
use crate::passes::doc_test_lints::{should_have_doc_example, Tests}; use crate::passes::doc_test_lints::{should_have_doc_example, Tests};
use crate::passes::Pass; use crate::passes::Pass;
use rustc_lint::builtin::MISSING_DOCS; use rustc_lint::builtin::MISSING_DOCS;
use rustc_middle::lint::LintSource; use rustc_middle::lint::LintLevelSource;
use rustc_session::lint; use rustc_session::lint;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::FileName; use rustc_span::FileName;
@ -254,7 +254,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
// `missing_docs` is allow-by-default, so don't treat this as ignoring the item // `missing_docs` is allow-by-default, so don't treat this as ignoring the item
// unless the user had an explicit `allow` // unless the user had an explicit `allow`
let should_have_docs = let should_have_docs =
level != lint::Level::Allow || matches!(source, LintSource::Default); level != lint::Level::Allow || matches!(source, LintLevelSource::Default);
debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename); debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename);
self.items.entry(filename).or_default().count_item( self.items.entry(filename).or_default().count_item(
has_docs, has_docs,

View file

@ -9,7 +9,7 @@ use crate::clean::*;
use crate::core::DocContext; use crate::core::DocContext;
use crate::fold::DocFolder; use crate::fold::DocFolder;
use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString}; use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
use rustc_middle::lint::LintSource; use rustc_middle::lint::LintLevelSource;
use rustc_session::lint; use rustc_session::lint;
crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
@ -77,7 +77,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local()); let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local());
let (level, source) = let (level, source) =
cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id); cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id);
level != lint::Level::Allow || matches!(source, LintSource::Default) level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
} }
crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {

View file

@ -1,7 +1,6 @@
//! The Rust AST Visitor. Extracts useful information and massages it into a form //! The Rust AST Visitor. Extracts useful information and massages it into a form
//! usable for `clean`. //! usable for `clean`.
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -64,7 +63,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
let mut module = self.visit_mod_contents( let mut module = self.visit_mod_contents(
krate.item.span, krate.item.span,
krate.item.attrs,
&Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public }, &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public },
hir::CRATE_HIR_ID, hir::CRATE_HIR_ID,
&krate.item.module, &krate.item.module,
@ -82,13 +80,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
fn visit_mod_contents( fn visit_mod_contents(
&mut self, &mut self,
span: Span, span: Span,
attrs: &'tcx [ast::Attribute],
vis: &'tcx hir::Visibility<'_>, vis: &'tcx hir::Visibility<'_>,
id: hir::HirId, id: hir::HirId,
m: &'tcx hir::Mod<'tcx>, m: &'tcx hir::Mod<'tcx>,
name: Option<Symbol>, name: Option<Symbol>,
) -> Module<'tcx> { ) -> Module<'tcx> {
let mut om = Module::new(name, attrs); let mut om = Module::new(name);
om.where_outer = span; om.where_outer = span;
om.where_inner = m.inner; om.where_inner = m.inner;
om.id = id; om.id = id;
@ -292,7 +289,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::Mod(ref m) => { hir::ItemKind::Mod(ref m) => {
om.mods.push(self.visit_mod_contents( om.mods.push(self.visit_mod_contents(
item.span, item.span,
&item.attrs,
&item.vis, &item.vis,
item.hir_id, item.hir_id,
m, m,

View file

@ -14,9 +14,6 @@
- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23 - _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23 - assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:5:18: 5:23 + _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ // ty::Const
+ // + ty: (u32, bool)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/checked_add.rs:5:18: 5:23 + // + span: $DIR/checked_add.rs:5:18: 5:23
+ // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -18,9 +18,6 @@
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29 - assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:25 + _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:25
+ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:5:13: 5:29 + _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ // ty::Const
+ // + ty: (u8, bool)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/indirect.rs:5:13: 5:29 + // + span: $DIR/indirect.rs:5:13: 5:29
+ // + literal: Const { ty: (u8, bool), val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (u8, bool), val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -15,9 +15,6 @@
(_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:11:11: 11:17 (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:11:10: 11:19 - (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
+ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19 + (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
+ // ty::Const
+ // + ty: (u8, u8)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/issue-67019.rs:11:10: 11:19 + // + span: $DIR/issue-67019.rs:11:10: 11:19
+ // + literal: Const { ty: (u8, u8), val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (u8, u8), val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -20,9 +20,6 @@
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:9: 7:10 StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:9: 7:10
- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14 - _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14 + _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ // ty::Const
+ // + ty: (i32, i32)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14 + // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ // + literal: Const { ty: (i32, i32), val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (i32, i32), val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -27,9 +27,6 @@
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 + _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // ty::Const
+ // + ty: (i32, bool)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18 + // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -27,9 +27,6 @@
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 + _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // ty::Const
+ // + ty: (i32, bool)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18 + // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -9,9 +9,6 @@
- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10 - _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10 - assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:6:5: 6:10 + _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ // ty::Const
+ // + ty: (u32, bool)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/return_place.rs:6:5: 6:10 + // + span: $DIR/return_place.rs:6:5: 6:10
+ // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -18,9 +18,6 @@
StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14 StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14 - _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14 + _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ // ty::Const
+ // + ty: (u32, u32)
+ // + val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+ // mir::Constant + // mir::Constant
+ // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14 + // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ // + literal: Const { ty: (u32, u32), val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + // + literal: Const { ty: (u32, u32), val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }

View file

@ -42,9 +42,6 @@
// mir::Constant // mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12 // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12
// + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(Scalar(<ZST>)) } // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(Scalar(<ZST>)) }
// ty::Const
// + ty: ((), ())
// + val: Value(Scalar(<ZST>))
// mir::Constant // mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22 // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
// + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) } // + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) }

View file

@ -1,3 +1,4 @@
// ignore-tidy-linelength
// edition:2018 // edition:2018
#![feature(min_const_generics)] #![feature(min_const_generics)]
@ -48,7 +49,50 @@ impl Foo {
pub async fn mut_self(mut self, mut first: usize) {} pub async fn mut_self(mut self, mut first: usize) {}
} }
pub trait Pattern<'a> {}
pub trait Trait<const N: usize> {} pub trait Trait<const N: usize> {}
// @has async_fn/fn.const_generics.html // @has async_fn/fn.const_generics.html
// @has - '//pre[@class="rust fn"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)' // @has - '//pre[@class="rust fn"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)'
pub async fn const_generics<const N: usize>(_: impl Trait<N>) {} pub async fn const_generics<const N: usize>(_: impl Trait<N>) {}
// test that elided lifetimes are properly elided and not displayed as `'_`
// regression test for #63037
// @has async_fn/fn.elided.html
// @has - '//pre[@class="rust fn"]' 'pub async fn elided(foo: &str) -> &str'
pub async fn elided(foo: &str) -> &str {}
// This should really be shown as written, but for implementation reasons it's difficult.
// See `impl Clean for TyKind::Rptr`.
// @has async_fn/fn.user_elided.html
// @has - '//pre[@class="rust fn"]' 'pub async fn user_elided(foo: &str) -> &str'
pub async fn user_elided(foo: &'_ str) -> &str {}
// @has async_fn/fn.static_trait.html
// @has - '//pre[@class="rust fn"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>'
pub async fn static_trait(foo: &str) -> Box<dyn Bar> {}
// @has async_fn/fn.lifetime_for_trait.html
// @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>"
pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {}
// @has async_fn/fn.elided_in_input_trait.html
// @has - '//pre[@class="rust fn"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)"
pub async fn elided_in_input_trait(t: impl Pattern<'_>) {}
struct AsyncFdReadyGuard<'a, T> { x: &'a T }
impl Foo {
// @has async_fn/struct.Foo.html
// @has - '//h4[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
// taken from `tokio` as an example of a method that was particularly bad before
// @has - '//h4[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
// @has - '//h4[@class="method"]' "pub async fn mut_self(&mut self)"
pub async fn mut_self(&mut self) {}
}
// test named lifetimes, just in case
// @has async_fn/fn.named.html
// @has - '//pre[@class="rust fn"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str"
pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {}
// @has async_fn/fn.named_trait.html
// @has - '//pre[@class="rust fn"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>"
pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {}

View file

@ -0,0 +1,8 @@
// run-rustfix
// edition:2018
// Regression test for issue 79694
fn main() {
let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
}

View file

@ -0,0 +1,8 @@
// run-rustfix
// edition:2018
// Regression test for issue 79694
fn main() {
let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
}

View file

@ -0,0 +1,13 @@
error: the order of `move` and `async` is incorrect
--> $DIR/incorrect-move-async-order-issue-79694.rs:7:13
|
LL | let _ = move async { };
| ^^^^^^^^^^
|
help: try switching the order
|
LL | let _ = async move { };
| ^^^^^^^^^^
error: aborting due to previous error

View file

@ -1,3 +1,10 @@
# x # x
`x` invokes `x.py` from any subdirectory. `x` invokes `x.py` from any subdirectory.
To install, run the following commands:
```
$ cd rust/src/tools/x/
$ cargo install --path .
```