1
Fork 0

Auto merge of #100416 - Dylan-DPC:rollup-m344lh1, r=Dylan-DPC

Rollup of 11 pull requests

Successful merges:

 - #92744 (Check if enum from foreign crate has any non exhaustive variants when attempting a cast)
 - #99110 (Determine match_has_guard from candidates instead of looking up thir table again)
 - #100184 (Stabilize ptr_const_cast)
 - #100192 ( Remove duplicated temporaries creating during box derefs elaboration)
 - #100232 (Do not consider method call receiver as an argument in AST.)
 - #100287 (linux: Use `pthread_setname_np` instead of `prctl`)
 - #100351 (Use `&mut Diagnostic` instead of `&mut DiagnosticBuilder` unless needed)
 - #100370 (Remove more Clean trait implementations)
 - #100391 (Improve size assertions)
 - #100398 (Improve `-Zhir-stats`)
 - #100403 (Improve error messages when running rustdoc GUI tests)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-08-11 18:05:55 +00:00
commit 20ffea6938
59 changed files with 954 additions and 474 deletions

View file

@ -19,7 +19,6 @@
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]
#![feature(ptr_const_cast)]
use smallvec::SmallVec;

View file

@ -1338,14 +1338,13 @@ pub enum ExprKind {
///
/// The `PathSegment` represents the method name and its generic arguments
/// (within the angle brackets).
/// The first element of the vector of an `Expr` is the expression that evaluates
/// to the object on which the method is being called on (the receiver),
/// and the remaining elements are the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
/// The standalone `Expr` is the receiver expression.
/// The vector of `Expr` is the arguments.
/// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`.
/// This `Span` is the span of the function, without the dot and receiver
/// (e.g. `foo(a, b)` in `x.foo(a, b)`
MethodCall(PathSegment, Vec<P<Expr>>, Span),
MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(Vec<P<Expr>>),
/// A binary operation (e.g., `a + b`, `a * b`).
@ -3030,22 +3029,25 @@ pub type ForeignItem = Item<ForeignItemKind>;
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(AssocItemKind, 72);
rustc_data_structures::static_assert_size!(Attribute, 152);
rustc_data_structures::static_assert_size!(Block, 48);
rustc_data_structures::static_assert_size!(Expr, 104);
rustc_data_structures::static_assert_size!(Fn, 192);
rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
rustc_data_structures::static_assert_size!(GenericBound, 88);
rustc_data_structures::static_assert_size!(Generics, 72);
rustc_data_structures::static_assert_size!(Impl, 200);
rustc_data_structures::static_assert_size!(Item, 200);
rustc_data_structures::static_assert_size!(ItemKind, 112);
rustc_data_structures::static_assert_size!(Lit, 48);
rustc_data_structures::static_assert_size!(Pat, 120);
rustc_data_structures::static_assert_size!(Path, 40);
rustc_data_structures::static_assert_size!(PathSegment, 24);
rustc_data_structures::static_assert_size!(Stmt, 32);
rustc_data_structures::static_assert_size!(Ty, 96);
static_assert_size!(AssocItem, 160);
static_assert_size!(AssocItemKind, 72);
static_assert_size!(Attribute, 152);
static_assert_size!(Block, 48);
static_assert_size!(Expr, 104);
static_assert_size!(Fn, 192);
static_assert_size!(ForeignItem, 160);
static_assert_size!(ForeignItemKind, 72);
static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200);
static_assert_size!(Item, 200);
static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
static_assert_size!(Pat, 120);
static_assert_size!(Path, 40);
static_assert_size!(PathSegment, 24);
static_assert_size!(Stmt, 32);
static_assert_size!(Ty, 96);
}

View file

@ -1302,10 +1302,11 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(f);
visit_exprs(args, vis);
}
ExprKind::MethodCall(PathSegment { ident, id, args }, exprs, span) => {
ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => {
vis.visit_ident(ident);
vis.visit_id(id);
visit_opt(args, |args| vis.visit_generic_args(args));
vis.visit_expr(receiver);
visit_exprs(exprs, vis);
vis.visit_span(span);
}

View file

@ -396,9 +396,9 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
contains_exterior_struct_lit(&x)
}
ast::ExprKind::MethodCall(.., ref exprs, _) => {
ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
// X { y: 1 }.bar(...)
contains_exterior_struct_lit(&exprs[0])
contains_exterior_struct_lit(&receiver)
}
_ => false,

View file

@ -813,8 +813,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::MethodCall(ref segment, ref arguments, _span) => {
ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => {
visitor.visit_path_segment(expression.span, segment);
visitor.visit_expr(receiver);
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::Binary(_, ref left_expression, ref right_expression) => {

View file

@ -62,7 +62,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ExprKind::Call(f, self.lower_exprs(args))
}
}
ExprKind::MethodCall(ref seg, ref args, span) => {
ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => {
let hir_seg = self.arena.alloc(self.lower_path_segment(
e.span,
seg,
@ -70,7 +70,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
ParenthesizedGenericArgs::Err,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
));
let args = self.lower_exprs(args);
let args = self.arena.alloc_from_iter(
[&*receiver].into_iter().chain(args.iter()).map(|x| self.lower_expr_mut(x)),
);
hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span))
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {

View file

@ -13,9 +13,7 @@ use rustc_ast::walk_list;
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
};
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability, Diagnostic};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@ -477,7 +475,7 @@ impl<'a> AstValidator<'a> {
ctx: &str,
msg: &str,
sugg: &str,
help: impl FnOnce(&mut DiagnosticBuilder<'_, ErrorGuaranteed>),
help: impl FnOnce(&mut Diagnostic),
) {
let source_map = self.session.source_map();
let end = source_map.end_point(sp);
@ -1196,7 +1194,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let msg = "free function without a body";
let ext = sig.header.ext;
let f = |e: &mut DiagnosticBuilder<'_, _>| {
let f = |e: &mut Diagnostic| {
if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext
{
let start_suggestion = if let Extern::Explicit(abi, _) = ext {

View file

@ -193,9 +193,13 @@ impl<'a> State<'a> {
self.print_call_post(args)
}
fn print_expr_method_call(&mut self, segment: &ast::PathSegment, args: &[P<ast::Expr>]) {
let base_args = &args[1..];
self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
fn print_expr_method_call(
&mut self,
segment: &ast::PathSegment,
receiver: &ast::Expr,
base_args: &[P<ast::Expr>],
) {
self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX);
self.word(".");
self.print_ident(segment.ident);
if let Some(ref args) = segment.args {
@ -303,8 +307,8 @@ impl<'a> State<'a> {
ast::ExprKind::Call(ref func, ref args) => {
self.print_expr_call(func, &args);
}
ast::ExprKind::MethodCall(ref segment, ref args, _) => {
self.print_expr_method_call(segment, &args);
ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => {
self.print_expr_method_call(segment, &receiver, &args);
}
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
self.print_expr_binary(op, lhs, rhs);

View file

@ -451,7 +451,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_borrow_fn_like(
&self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
err: &mut Diagnostic,
ty: Ty<'tcx>,
move_sites: &[MoveSite],
value_name: &str,
@ -526,12 +526,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
true
}
fn suggest_adding_copy_bounds(
&self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
ty: Ty<'tcx>,
span: Span,
) {
fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());

View file

@ -783,7 +783,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn maybe_suggest_constrain_dyn_trait_impl(
&self,
diag: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
diag: &mut Diagnostic,
f: Region<'tcx>,
o: Region<'tcx>,
category: &ConstraintCategory<'tcx>,

View file

@ -240,8 +240,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix);
}
ExprKind::MethodCall(_, ref mut local_exprs, _) => {
for local_expr in local_exprs.iter_mut().skip(1) {
ExprKind::MethodCall(_, _,ref mut local_exprs, _) => {
for local_expr in local_exprs.iter_mut() {
self.manage_cond_expr(local_expr);
}
}
@ -377,14 +377,12 @@ impl<'cx, 'a> Context<'cx, 'a> {
id: DUMMY_NODE_ID,
ident: Ident::new(sym::try_capture, self.span),
},
vec![
expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)),
expr_addr_of_mut(
self.cx,
self.span,
self.cx.expr_path(Path::from_ident(capture)),
),
],
expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)),
vec![expr_addr_of_mut(
self.cx,
self.span,
self.cx.expr_path(Path::from_ident(capture)),
)],
self.span,
))
.add_trailing_semicolon();
@ -442,10 +440,11 @@ fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
fn expr_method_call(
cx: &ExtCtxt<'_>,
path: PathSegment,
receiver: P<Expr>,
args: Vec<P<Expr>>,
span: Span,
) -> P<Expr> {
cx.expr(span, ExprKind::MethodCall(path, args, span))
cx.expr(span, ExprKind::MethodCall(path, receiver, args, span))
}
fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {

View file

@ -823,9 +823,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(Immediate, 56);
rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
rustc_data_structures::static_assert_size!(Operand, 64);
rustc_data_structures::static_assert_size!(OpTy<'_>, 88);
static_assert_size!(Immediate, 56);
static_assert_size!(ImmTy<'_>, 72);
static_assert_size!(Operand, 64);
static_assert_size!(OpTy<'_>, 88);
}

View file

@ -891,10 +891,11 @@ where
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(MemPlaceMeta, 24);
rustc_data_structures::static_assert_size!(MemPlace, 40);
rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 64);
rustc_data_structures::static_assert_size!(Place, 48);
rustc_data_structures::static_assert_size!(PlaceTy<'_>, 72);
static_assert_size!(MemPlaceMeta, 24);
static_assert_size!(MemPlace, 40);
static_assert_size!(MPlaceTy<'_>, 64);
static_assert_size!(Place, 48);
static_assert_size!(PlaceTy<'_>, 72);
}

View file

@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, TransparencyError};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_feature::Features;
use rustc_lint_defs::builtin::{
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
@ -608,11 +608,7 @@ enum ExplainDocComment {
},
}
fn annotate_doc_comment(
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
sm: &SourceMap,
span: Span,
) {
fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) {
if let Ok(src) = sm.span_to_snippet(span) {
if src.starts_with("///") || src.starts_with("/**") {
err.subdiagnostic(ExplainDocComment::Outer { span });

View file

@ -3491,16 +3491,16 @@ impl<'hir> Node<'hir> {
mod size_asserts {
use super::*;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(Block<'static>, 48);
rustc_data_structures::static_assert_size!(Expr<'static>, 56);
rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72);
rustc_data_structures::static_assert_size!(GenericBound<'_>, 48);
rustc_data_structures::static_assert_size!(Generics<'static>, 56);
rustc_data_structures::static_assert_size!(ImplItem<'static>, 88);
rustc_data_structures::static_assert_size!(Impl<'static>, 80);
rustc_data_structures::static_assert_size!(Item<'static>, 80);
rustc_data_structures::static_assert_size!(Pat<'static>, 88);
rustc_data_structures::static_assert_size!(QPath<'static>, 24);
rustc_data_structures::static_assert_size!(TraitItem<'static>, 96);
rustc_data_structures::static_assert_size!(Ty<'static>, 72);
static_assert_size!(Block<'static>, 48);
static_assert_size!(Expr<'static>, 56);
static_assert_size!(ForeignItem<'static>, 72);
static_assert_size!(GenericBound<'_>, 48);
static_assert_size!(Generics<'static>, 56);
static_assert_size!(ImplItem<'static>, 88);
static_assert_size!(Impl<'static>, 80);
static_assert_size!(Item<'static>, 80);
static_assert_size!(Pat<'static>, 88);
static_assert_size!(QPath<'static>, 24);
static_assert_size!(TraitItem<'static>, 96);
static_assert_size!(Ty<'static>, 72);
}

View file

@ -608,8 +608,7 @@ trait UnusedDelimLint {
ref call_or_other => {
let (args_to_check, ctx) = match *call_or_other {
Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
// first "argument" is self (which sometimes needs delims)
MethodCall(_, ref args, _) => (&args[1..], UnusedDelimsCtx::MethodArg),
MethodCall(_, _, ref args, _) => (&args[..], UnusedDelimsCtx::MethodArg),
// actual catch-all arm
_ => {
return;

View file

@ -814,8 +814,8 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
mod size_asserts {
use super::*;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(Block, 56);
rustc_data_structures::static_assert_size!(Expr<'_>, 104);
rustc_data_structures::static_assert_size!(Pat<'_>, 24);
rustc_data_structures::static_assert_size!(Stmt<'_>, 120);
static_assert_size!(Block, 56);
static_assert_size!(Expr<'_>, 104);
static_assert_size!(Pat<'_>, 24);
static_assert_size!(Stmt<'_>, 120);
}

View file

@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut arm_candidates = self.create_match_candidates(scrutinee_place.clone(), &arms);
let match_has_guard = arms.iter().copied().any(|arm| self.thir[arm].guard.is_some());
let match_has_guard = arm_candidates.iter().any(|(_, candidate)| candidate.has_guard);
let mut candidates =
arm_candidates.iter_mut().map(|(_, candidate)| candidate).collect::<Vec<_>>();

View file

@ -70,7 +70,6 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
self.local_decls.push(LocalDecl::new(ptr_ty, source_info.span));
self.patch.add_statement(location, StatementKind::StorageLive(ptr_local));
@ -125,13 +124,6 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
index += 1;
}
if let Some(terminator) = terminator
&& !matches!(terminator.kind, TerminatorKind::Yield{..})
{
let location = Location { block, statement_index: index };
visitor.visit_terminator(terminator, location);
}
let location = Location { block, statement_index: index };
match terminator {
// yielding into a box is handled when lowering generators

View file

@ -19,7 +19,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, EmissionGuarantee, ErrorGuaranteed};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, Ident};
@ -228,13 +228,13 @@ struct MultiSugg {
}
impl MultiSugg {
fn emit<G: EmissionGuarantee>(self, err: &mut DiagnosticBuilder<'_, G>) {
fn emit(self, err: &mut Diagnostic) {
err.multipart_suggestion(&self.msg, self.patches, self.applicability);
}
/// Overrides individual messages and applicabilities.
fn emit_many<G: EmissionGuarantee>(
err: &mut DiagnosticBuilder<'_, G>,
fn emit_many(
err: &mut Diagnostic,
msg: &str,
applicability: Applicability,
suggestions: impl Iterator<Item = Self>,

View file

@ -850,7 +850,7 @@ impl<'a> Parser<'a> {
ExprKind::Index(_, _) => "indexing",
ExprKind::Try(_) => "`?`",
ExprKind::Field(_, _) => "a field access",
ExprKind::MethodCall(_, _, _) => "a method call",
ExprKind::MethodCall(_, _, _, _) => "a method call",
ExprKind::Call(_, _) => "a function call",
ExprKind::Await(_) => "`.await`",
ExprKind::Err => return Ok(with_postfix),
@ -859,7 +859,7 @@ impl<'a> Parser<'a> {
);
let mut err = self.struct_span_err(span, &msg);
let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| {
let suggest_parens = |err: &mut Diagnostic| {
let suggestions = vec![
(span.shrink_to_lo(), "(".to_string()),
(span.shrink_to_hi(), ")".to_string()),
@ -1280,12 +1280,14 @@ impl<'a> Parser<'a> {
if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
// Method call `expr.f()`
let mut args = self.parse_paren_expr_seq()?;
args.insert(0, self_arg);
let args = self.parse_paren_expr_seq()?;
let fn_span = fn_span_lo.to(self.prev_token.span);
let span = lo.to(self.prev_token.span);
Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span), AttrVec::new()))
Ok(self.mk_expr(
span,
ExprKind::MethodCall(segment, self_arg, args, fn_span),
AttrVec::new(),
))
} else {
// Field access `expr.f`
if let Some(args) = segment.args {

View file

@ -21,21 +21,55 @@ enum Id {
None,
}
struct NodeData {
struct NodeStats {
count: usize,
size: usize,
}
impl NodeStats {
fn new() -> NodeStats {
NodeStats { count: 0, size: 0 }
}
}
struct Node {
stats: NodeStats,
subnodes: FxHashMap<&'static str, NodeStats>,
}
impl Node {
fn new() -> Node {
Node { stats: NodeStats::new(), subnodes: FxHashMap::default() }
}
}
/// This type measures the size of AST and HIR nodes, by implementing the AST
/// and HIR `Visitor` traits. But we don't measure every visited type because
/// that could cause double counting.
///
/// For example, `ast::Visitor` has `visit_ident`, but `Ident`s are always
/// stored inline within other AST nodes, so we don't implement `visit_ident`
/// here. In constrast, we do implement `visit_expr` because `ast::Expr` is
/// always stored as `P<ast::Expr>`, and every such expression should be
/// measured separately.
///
/// In general, a `visit_foo` method should be implemented here if the
/// corresponding `Foo` type is always stored on its own, e.g.: `P<Foo>`,
/// `Box<Foo>`, `Vec<Foo>`, `Box<[Foo]>`.
///
/// There are some types in the AST and HIR tree that the visitors do not have
/// a `visit_*` method for, and so we cannot measure these, which is
/// unfortunate.
struct StatCollector<'k> {
krate: Option<Map<'k>>,
data: FxHashMap<&'static str, NodeData>,
nodes: FxHashMap<&'static str, Node>,
seen: FxHashSet<Id>,
}
pub fn print_hir_stats(tcx: TyCtxt<'_>) {
let mut collector = StatCollector {
krate: Some(tcx.hir()),
data: FxHashMap::default(),
nodes: FxHashMap::default(),
seen: FxHashSet::default(),
};
tcx.hir().walk_toplevel_module(&mut collector);
@ -44,49 +78,88 @@ pub fn print_hir_stats(tcx: TyCtxt<'_>) {
}
pub fn print_ast_stats(krate: &ast::Crate, title: &str) {
use rustc_ast::visit::Visitor;
let mut collector =
StatCollector { krate: None, data: FxHashMap::default(), seen: FxHashSet::default() };
ast_visit::walk_crate(&mut collector, krate);
StatCollector { krate: None, nodes: FxHashMap::default(), seen: FxHashSet::default() };
collector.visit_crate(krate);
collector.print(title);
}
impl<'k> StatCollector<'k> {
fn record<T>(&mut self, label: &'static str, id: Id, node: &T) {
// Record a top-level node.
fn record<T>(&mut self, label: &'static str, id: Id, val: &T) {
self.record_inner(label, None, id, val);
}
// Record a two-level entry, with a top-level enum type and a variant.
fn record_variant<T>(&mut self, label1: &'static str, label2: &'static str, id: Id, val: &T) {
self.record_inner(label1, Some(label2), id, val);
}
fn record_inner<T>(
&mut self,
label1: &'static str,
label2: Option<&'static str>,
id: Id,
val: &T,
) {
if id != Id::None && !self.seen.insert(id) {
return;
}
let entry = self.data.entry(label).or_insert(NodeData { count: 0, size: 0 });
let node = self.nodes.entry(label1).or_insert(Node::new());
node.stats.count += 1;
node.stats.size = std::mem::size_of_val(val);
entry.count += 1;
entry.size = std::mem::size_of_val(node);
if let Some(label2) = label2 {
let subnode = node.subnodes.entry(label2).or_insert(NodeStats::new());
subnode.count += 1;
subnode.size = std::mem::size_of_val(val);
}
}
fn print(&self, title: &str) {
let mut stats: Vec<_> = self.data.iter().collect();
let mut nodes: Vec<_> = self.nodes.iter().collect();
nodes.sort_by_key(|&(_, ref node)| node.stats.count * node.stats.size);
stats.sort_by_key(|&(_, ref d)| d.count * d.size);
let mut total_size = 0;
let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum();
eprintln!("\n{}\n", title);
eprintln!("{:<18}{:>18}{:>14}{:>14}", "Name", "Accumulated Size", "Count", "Item Size");
eprintln!("----------------------------------------------------------------");
for (label, data) in stats {
eprintln!(
"{:<18}{:>18}{:>14}{:>14}",
label,
to_readable_str(data.count * data.size),
to_readable_str(data.count),
to_readable_str(data.size)
);
let percent = |m, n| (m * 100) as f64 / n as f64;
total_size += data.count * data.size;
for (label, node) in nodes {
let size = node.stats.count * node.stats.size;
eprintln!(
"{:<18}{:>10} ({:4.1}%){:>14}{:>14}",
label,
to_readable_str(size),
percent(size, total_size),
to_readable_str(node.stats.count),
to_readable_str(node.stats.size)
);
if !node.subnodes.is_empty() {
let mut subnodes: Vec<_> = node.subnodes.iter().collect();
subnodes.sort_by_key(|&(_, ref subnode)| subnode.count * subnode.size);
for (label, subnode) in subnodes {
let size = subnode.count * subnode.size;
eprintln!(
"- {:<18}{:>10} ({:4.1}%){:>14}",
label,
to_readable_str(size),
percent(size, total_size),
to_readable_str(subnode.count),
);
}
}
}
eprintln!("----------------------------------------------------------------");
eprintln!("{:<18}{:>18}\n", "Total", to_readable_str(total_size));
eprintln!("{:<18}{:>10}\n", "Total", to_readable_str(total_size));
}
}
@ -228,6 +301,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_path(self, path)
}
// `PathSegment` has one inline use (in `ast::ExprKind::MethodCall`) and
// one non-inline use (in `Path::segments`). The latter case is more common
// than the former case, so we implement this visitor and tolerate the
// double counting in the former case.
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v hir::PathSegment<'v>) {
self.record("PathSegment", Id::None, path_segment);
hir_visit::walk_path_segment(self, path_span, path_segment)
@ -243,14 +320,54 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}
}
// Used to avoid boilerplate for types with many variants.
macro_rules! record_variants {
(
($self:ident, $val:expr, $kind:expr, $ty:ty, $tykind:ident), // mandatory pieces
[$($variant:ident),*]
) => {
match $kind {
$(
ast::$tykind::$variant { .. } => {
$self.record_variant(stringify!($ty), stringify!($variant), Id::None, $val)
}
)*
}
};
}
impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
fn visit_foreign_item(&mut self, i: &'v ast::ForeignItem) {
self.record("ForeignItem", Id::None, i);
record_variants!(
(self, i, i.kind, ForeignItem, ForeignItemKind),
[Static, Fn, TyAlias, MacCall]
);
ast_visit::walk_foreign_item(self, i)
}
fn visit_item(&mut self, i: &'v ast::Item) {
self.record("Item", Id::None, i);
record_variants!(
(self, i, i.kind, Item, ItemKind),
[
ExternCrate,
Use,
Static,
Const,
Fn,
Mod,
ForeignMod,
GlobalAsm,
TyAlias,
Enum,
Struct,
Union,
Trait,
TraitAlias,
Impl,
MacCall,
MacroDef
]
);
ast_visit::walk_item(self, i)
}
@ -265,47 +382,116 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
}
fn visit_stmt(&mut self, s: &'v ast::Stmt) {
self.record("Stmt", Id::None, s);
record_variants!(
(self, s, s.kind, Stmt, StmtKind),
[Local, Item, Expr, Semi, Empty, MacCall]
);
ast_visit::walk_stmt(self, s)
}
fn visit_param(&mut self, p: &'v ast::Param) {
self.record("Param", Id::None, p);
ast_visit::walk_param(self, p)
}
fn visit_arm(&mut self, a: &'v ast::Arm) {
self.record("Arm", Id::None, a);
ast_visit::walk_arm(self, a)
}
fn visit_pat(&mut self, p: &'v ast::Pat) {
self.record("Pat", Id::None, p);
record_variants!(
(self, p, p.kind, Pat, PatKind),
[
Wild,
Ident,
Struct,
TupleStruct,
Or,
Path,
Tuple,
Box,
Ref,
Lit,
Range,
Slice,
Rest,
Paren,
MacCall
]
);
ast_visit::walk_pat(self, p)
}
fn visit_expr(&mut self, ex: &'v ast::Expr) {
self.record("Expr", Id::None, ex);
ast_visit::walk_expr(self, ex)
fn visit_expr(&mut self, e: &'v ast::Expr) {
record_variants!(
(self, e, e.kind, Expr, ExprKind),
[
Box, Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let,
If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign,
AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
InlineAsm, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, Err
]
);
ast_visit::walk_expr(self, e)
}
fn visit_ty(&mut self, t: &'v ast::Ty) {
self.record("Ty", Id::None, t);
record_variants!(
(self, t, t.kind, Ty, TyKind),
[
Slice,
Array,
Ptr,
Rptr,
BareFn,
Never,
Tup,
Path,
TraitObject,
ImplTrait,
Paren,
Typeof,
Infer,
ImplicitSelf,
MacCall,
Err,
CVarArgs
]
);
ast_visit::walk_ty(self, t)
}
fn visit_generic_param(&mut self, g: &'v ast::GenericParam) {
self.record("GenericParam", Id::None, g);
ast_visit::walk_generic_param(self, g)
}
fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
record_variants!(
(self, p, p, WherePredicate, WherePredicate),
[BoundPredicate, RegionPredicate, EqPredicate]
);
ast_visit::walk_where_predicate(self, p)
}
fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, s: Span, _: NodeId) {
self.record("FnDecl", Id::None, fk.decl());
ast_visit::walk_fn(self, fk, s)
}
fn visit_assoc_item(&mut self, item: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
let label = match ctxt {
ast_visit::AssocCtxt::Trait => "TraitItem",
ast_visit::AssocCtxt::Impl => "ImplItem",
};
self.record(label, Id::None, item);
ast_visit::walk_assoc_item(self, item, ctxt);
fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
record_variants!(
(self, i, i.kind, AssocItem, AssocItemKind),
[Const, Fn, TyAlias, MacCall]
);
ast_visit::walk_assoc_item(self, i, ctxt);
}
fn visit_param_bound(&mut self, bounds: &'v ast::GenericBound, _ctxt: BoundKind) {
self.record("GenericBound", Id::None, bounds);
ast_visit::walk_param_bound(self, bounds)
fn visit_param_bound(&mut self, b: &'v ast::GenericBound, _ctxt: BoundKind) {
record_variants!((self, b, b, GenericBound, GenericBound), [Trait, Outlives]);
ast_visit::walk_param_bound(self, b)
}
fn visit_field_def(&mut self, s: &'v ast::FieldDef) {
@ -318,27 +504,42 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
ast_visit::walk_variant(self, v)
}
fn visit_lifetime(&mut self, lifetime: &'v ast::Lifetime, _: ast_visit::LifetimeCtxt) {
self.record("Lifetime", Id::None, lifetime);
ast_visit::walk_lifetime(self, lifetime)
}
fn visit_mac_call(&mut self, mac: &'v ast::MacCall) {
self.record("MacCall", Id::None, mac);
ast_visit::walk_mac(self, mac)
}
// `UseTree` has one inline use (in `ast::ItemKind::Use`) and one
// non-inline use (in `ast::UseTreeKind::Nested). The former case is more
// common, so we don't implement `visit_use_tree` and tolerate the missed
// coverage in the latter case.
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v ast::PathSegment) {
self.record("PathSegment", Id::None, path_segment);
ast_visit::walk_path_segment(self, path_span, path_segment)
}
fn visit_assoc_constraint(&mut self, constraint: &'v ast::AssocConstraint) {
self.record("AssocConstraint", Id::None, constraint);
ast_visit::walk_assoc_constraint(self, constraint)
// `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one
// non-inline use (in `ast::PathSegment::args`). The latter case is more
// common, so we implement `visit_generic_args` and tolerate the double
// counting in the former case.
fn visit_generic_args(&mut self, sp: Span, g: &'v ast::GenericArgs) {
record_variants!((self, g, g, GenericArgs, GenericArgs), [AngleBracketed, Parenthesized]);
ast_visit::walk_generic_args(self, sp, g)
}
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
self.record("Attribute", Id::None, attr);
record_variants!((self, attr, attr.kind, Attribute, AttrKind), [Normal, DocComment]);
ast_visit::walk_attribute(self, attr)
}
fn visit_expr_field(&mut self, f: &'v ast::ExprField) {
self.record("ExprField", Id::None, f);
ast_visit::walk_expr_field(self, f)
}
fn visit_crate(&mut self, krate: &'v ast::Crate) {
self.record("Crate", Id::None, krate);
ast_visit::walk_crate(self, krate)
}
fn visit_inline_asm(&mut self, asm: &'v ast::InlineAsm) {
self.record("InlineAsm", Id::None, asm);
ast_visit::walk_inline_asm(self, asm)
}
}

View file

@ -3796,9 +3796,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
ExprKind::Field(ref subexpression, _) => {
self.resolve_expr(subexpression, Some(expr));
}
ExprKind::MethodCall(ref segment, ref arguments, _) => {
let mut arguments = arguments.iter();
self.resolve_expr(arguments.next().unwrap(), Some(expr));
ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _) => {
self.resolve_expr(receiver, Some(expr));
for argument in arguments {
self.resolve_expr(argument, None);
}

View file

@ -2021,9 +2021,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
fn suggest_introducing_lifetime(
&self,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
err: &mut Diagnostic,
name: Option<&str>,
suggest: impl Fn(&mut DiagnosticBuilder<'_, ErrorGuaranteed>, bool, Span, &str, String) -> bool,
suggest: impl Fn(&mut Diagnostic, bool, Span, &str, String) -> bool,
) {
let mut suggest_note = true;
for rib in self.lifetime_ribs.iter().rev() {
@ -2149,7 +2149,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
pub(crate) fn add_missing_lifetime_specifiers_label(
&mut self,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
err: &mut Diagnostic,
lifetime_refs: Vec<MissingLifetime>,
function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>,
) {

View file

@ -16,7 +16,8 @@ use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan,
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@ -2106,7 +2107,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
pub fn prohibit_generics<'a>(
&self,
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
extend: impl Fn(&mut Diagnostic),
) -> bool {
let args = segments.clone().flat_map(|segment| segment.args().args);
@ -2984,11 +2985,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
/// Make sure that we are in the condition to suggest the blanket implementation.
fn maybe_lint_blanket_trait_impl<T: rustc_errors::EmissionGuarantee>(
&self,
self_ty: &hir::Ty<'_>,
diag: &mut DiagnosticBuilder<'_, T>,
) {
fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) {
let tcx = self.tcx();
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id);
if let hir::Node::Item(hir::Item {
@ -3081,7 +3078,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
sugg,
Applicability::MachineApplicable,
);
self.maybe_lint_blanket_trait_impl::<()>(&self_ty, &mut diag);
self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
diag.emit();
},
);

View file

@ -32,6 +32,7 @@ use super::FnCtxt;
use crate::hir::def_id::DefId;
use crate::type_error_struct;
use hir::def_id::LOCAL_CRATE;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
@ -40,7 +41,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable};
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef};
use rustc_session::lint;
use rustc_session::Session;
use rustc_span::symbol::sym;
@ -173,6 +174,7 @@ pub enum CastError {
/// or "a length". If this argument is None, then the metadata is unknown, for example,
/// when we're typechecking a type parameter with a ?Sized bound.
IntToFatCast(Option<&'static str>),
ForeignNonExhaustiveAdt,
}
impl From<ErrorGuaranteed> for CastError {
@ -591,6 +593,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
}
err.emit();
}
CastError::ForeignNonExhaustiveAdt => {
make_invalid_casting_error(
fcx.tcx.sess,
self.span,
self.expr_ty,
self.cast_ty,
fcx,
)
.note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate")
.emit();
}
}
}
@ -789,6 +802,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
_ => return Err(CastError::NonScalar),
};
if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
if adt_def.did().krate != LOCAL_CRATE {
if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
return Err(CastError::ForeignNonExhaustiveAdt);
}
}
}
match (t_from, t_cast) {
// These types have invariants! can't cast into them.
(_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),

View file

@ -1525,9 +1525,7 @@ fn detect_discriminant_duplicate<'tcx>(
) {
// Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate.
// Here `idx` refers to the order of which the discriminant appears, and its index in `vs`
let report = |dis: Discr<'tcx>,
idx: usize,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>| {
let report = |dis: Discr<'tcx>, idx: usize, err: &mut Diagnostic| {
let var = &vs[idx]; // HIR for the duplicate discriminant
let (span, display_discr) = match var.disr_expr {
Some(ref expr) => {

View file

@ -1585,9 +1585,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
}
}
fn note_unreachable_loop_return<'a>(
fn note_unreachable_loop_return(
&self,
err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
ret_exprs: &Vec<&'tcx hir::Expr<'tcx>>,
) {

View file

@ -28,7 +28,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
EmissionGuarantee, ErrorGuaranteed,
ErrorGuaranteed,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
@ -879,7 +879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs: &'tcx hir::Expr<'tcx>,
err_code: &'static str,
op_span: Span,
adjust_err: impl FnOnce(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>),
adjust_err: impl FnOnce(&mut Diagnostic),
) {
if lhs.is_syntactic_place_expr() {
return;
@ -1089,8 +1089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
let suggest_deref_binop = |err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
rhs_ty: Ty<'tcx>| {
let suggest_deref_binop = |err: &mut Diagnostic, rhs_ty: Ty<'tcx>| {
if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
// Can only assign if the type is sized, so if `DerefMut` yields a type that is
// unsized, do not suggest dereferencing it.
@ -2205,9 +2204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx().ty_error()
}
fn check_call_constructor<G: EmissionGuarantee>(
fn check_call_constructor(
&self,
err: &mut DiagnosticBuilder<'_, G>,
err: &mut Diagnostic,
base: &'tcx hir::Expr<'tcx>,
def_id: DefId,
) {

View file

@ -1778,7 +1778,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn label_fn_like(
&self,
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
err: &mut Diagnostic,
callable_def_id: Option<DefId>,
callee_ty: Option<Ty<'tcx>>,
) {

View file

@ -904,7 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
let label_span_not_found = |err: &mut DiagnosticBuilder<'_, _>| {
let label_span_not_found = |err: &mut Diagnostic| {
if unsatisfied_predicates.is_empty() {
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
let is_string_or_ref_str = match actual.kind() {
@ -1154,7 +1154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
expr: &hir::Expr<'_>,
item_name: Ident,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
err: &mut Diagnostic,
) -> bool {
let tcx = self.tcx;
let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
@ -1331,7 +1331,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_for_field_method(
&self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
err: &mut Diagnostic,
source: SelfSource<'tcx>,
span: Span,
actual: Ty<'tcx>,
@ -1380,7 +1380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_for_unwrap_self(
&self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
err: &mut Diagnostic,
source: SelfSource<'tcx>,
span: Span,
actual: Ty<'tcx>,

View file

@ -104,7 +104,7 @@ use crate::astconv::AstConv;
use crate::check::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
pluralize, struct_span_err, Applicability, DiagnosticBuilder, EmissionGuarantee, MultiSpan,
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::Res;
@ -973,12 +973,7 @@ fn has_expected_num_generic_args<'tcx>(
/// * `span` - The span of the snippet
/// * `params` - The number of parameters the constructor accepts
/// * `err` - A mutable diagnostic builder to add the suggestion to
fn suggest_call_constructor<G: EmissionGuarantee>(
span: Span,
kind: CtorOf,
params: usize,
err: &mut DiagnosticBuilder<'_, G>,
) {
fn suggest_call_constructor(span: Span, kind: CtorOf, params: usize, err: &mut Diagnostic) {
// Note: tuple-structs don't have named fields, so just use placeholders
let args = vec!["_"; params].join(", ");
let applicable = if params > 0 {

View file

@ -59,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
// Suppress this error, since we already emitted
// a deref suggestion in check_overloaded_binop
err.delay_as_bug();
err.downgrade_to_delayed_bug();
}
}
});

View file

@ -95,8 +95,8 @@ impl<T: ?Sized> *const T {
///
/// This is a bit safer than `as` because it wouldn't silently change the type if the code is
/// refactored.
#[unstable(feature = "ptr_const_cast", issue = "92675")]
#[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")]
#[stable(feature = "ptr_const_cast", since = "1.65.0")]
#[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
pub const fn cast_mut(self) -> *mut T {
self as _
}

View file

@ -100,8 +100,8 @@ impl<T: ?Sized> *mut T {
/// coercion.
///
/// [`cast_mut`]: #method.cast_mut
#[unstable(feature = "ptr_const_cast", issue = "92675")]
#[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")]
#[stable(feature = "ptr_const_cast", since = "1.65.0")]
#[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
pub const fn cast_const(self) -> *const T {
self as _
}

View file

@ -116,11 +116,9 @@ impl Thread {
debug_assert_eq!(ret, 0);
}
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(target_os = "android")]
pub fn set_name(name: &CStr) {
const PR_SET_NAME: libc::c_int = 15;
// pthread wrapper only appeared in glibc 2.12, so we use syscall
// directly.
unsafe {
libc::prctl(
PR_SET_NAME,
@ -132,6 +130,14 @@ impl Thread {
}
}
#[cfg(target_os = "linux")]
pub fn set_name(name: &CStr) {
unsafe {
// Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20.
libc::pthread_setname_np(libc::pthread_self(), name.as_ptr());
}
}
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
pub fn set_name(name: &CStr) {
unsafe {

View file

@ -924,6 +924,11 @@ fn compare_browser_ui_test_version(installed_version: &str, src: &Path) {
one used in the CI (`{}`)",
installed_version, v
);
eprintln!(
"You can install this version using `npm update browser-ui-test` or by using \
`npm install browser-ui-test@{}`",
v,
);
}
}
Err(e) => eprintln!("Couldn't find the CI browser-ui-test version: {:?}", e),

View file

@ -120,7 +120,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
items: cx.tcx
.associated_items(impl_def_id)
.in_definition_order()
.map(|x| x.clean(cx))
.map(|x| clean_middle_assoc_item(x, cx))
.collect::<Vec<_>>(),
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))),

View file

@ -16,9 +16,10 @@ use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use crate::clean::{
self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_field,
clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def,
clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility,
self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item,
clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty,
clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
ImplKind, ItemId, Type, Visibility,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
@ -217,7 +218,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
// which causes methods to have a `pub` prefix, which is invalid since items in traits
// can not have a visibility prefix. Thus we override the visibility here manually.
// See https://github.com/rust-lang/rust/issues/81274
clean::Item { visibility: Visibility::Inherited, ..item.clean(cx) }
clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) }
})
.collect();
@ -452,7 +453,7 @@ pub(crate) fn build_impl(
item.visibility(tcx).is_public()
}
})
.map(|item| item.clean(cx))
.map(|item| clean_middle_assoc_item(item, cx))
.collect::<Vec<_>>(),
clean::enter_impl_trait(cx, |cx| {
clean_ty_generics(cx, tcx.generics_of(did), predicates)

View file

@ -123,7 +123,7 @@ fn clean_generic_bound<'tcx>(
let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();
let generic_args = generic_args.clean(cx);
let generic_args = clean_generic_args(generic_args, cx);
let GenericArgs::AngleBracketed { bindings, .. } = generic_args
else {
bug!("clean: parenthesized `GenericBound::LangItemTrait`");
@ -1092,199 +1092,201 @@ pub(crate) fn clean_impl_item<'tcx>(
})
}
impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
let tcx = cx.tcx;
let kind = match self.kind {
ty::AssocKind::Const => {
let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id));
pub(crate) fn clean_middle_assoc_item<'tcx>(
assoc_item: &ty::AssocItem,
cx: &mut DocContext<'tcx>,
) -> Item {
let tcx = cx.tcx;
let kind = match assoc_item.kind {
ty::AssocKind::Const => {
let ty = clean_middle_ty(tcx.type_of(assoc_item.def_id), cx, Some(assoc_item.def_id));
let provided = match self.container {
ty::ImplContainer => true,
ty::TraitContainer => tcx.impl_defaultness(self.def_id).has_value(),
};
if provided {
AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id })
} else {
TyAssocConstItem(ty)
}
let provided = match assoc_item.container {
ty::ImplContainer => true,
ty::TraitContainer => tcx.impl_defaultness(assoc_item.def_id).has_value(),
};
if provided {
AssocConstItem(ty, ConstantKind::Extern { def_id: assoc_item.def_id })
} else {
TyAssocConstItem(ty)
}
ty::AssocKind::Fn => {
let generics = clean_ty_generics(
cx,
tcx.generics_of(self.def_id),
tcx.explicit_predicates_of(self.def_id),
);
let sig = tcx.fn_sig(self.def_id);
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(self.def_id), sig);
}
ty::AssocKind::Fn => {
let generics = clean_ty_generics(
cx,
tcx.generics_of(assoc_item.def_id),
tcx.explicit_predicates_of(assoc_item.def_id),
);
let sig = tcx.fn_sig(assoc_item.def_id);
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
if self.fn_has_self_parameter {
let self_ty = match self.container {
ty::ImplContainer => tcx.type_of(self.container_id(tcx)),
ty::TraitContainer => tcx.types.self_param,
};
let self_arg_ty = sig.input(0).skip_binder();
if self_arg_ty == self_ty {
decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
if ty == self_ty {
match decl.inputs.values[0].type_ {
BorrowedRef { ref mut type_, .. } => {
**type_ = Generic(kw::SelfUpper)
}
_ => unreachable!(),
}
if assoc_item.fn_has_self_parameter {
let self_ty = match assoc_item.container {
ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)),
ty::TraitContainer => tcx.types.self_param,
};
let self_arg_ty = sig.input(0).skip_binder();
if self_arg_ty == self_ty {
decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
if ty == self_ty {
match decl.inputs.values[0].type_ {
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
_ => unreachable!(),
}
}
}
}
let provided = match self.container {
ty::ImplContainer => true,
ty::TraitContainer => self.defaultness(tcx).has_value(),
let provided = match assoc_item.container {
ty::ImplContainer => true,
ty::TraitContainer => assoc_item.defaultness(tcx).has_value(),
};
if provided {
let defaultness = match assoc_item.container {
ty::ImplContainer => Some(assoc_item.defaultness(tcx)),
ty::TraitContainer => None,
};
if provided {
let defaultness = match self.container {
ty::ImplContainer => Some(self.defaultness(tcx)),
ty::TraitContainer => None,
};
MethodItem(Box::new(Function { generics, decl }), defaultness)
} else {
TyMethodItem(Box::new(Function { generics, decl }))
MethodItem(Box::new(Function { generics, decl }), defaultness)
} else {
TyMethodItem(Box::new(Function { generics, decl }))
}
}
ty::AssocKind::Type => {
let my_name = assoc_item.name;
fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
match (&param.kind, arg) {
(GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty)))
if *ty == param.name =>
{
true
}
(GenericParamDefKind::Lifetime { .. }, GenericArg::Lifetime(Lifetime(lt)))
if *lt == param.name =>
{
true
}
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind {
ConstantKind::TyConst { expr } => expr == param.name.as_str(),
_ => false,
},
_ => false,
}
}
ty::AssocKind::Type => {
let my_name = self.name;
fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
match (&param.kind, arg) {
(GenericParamDefKind::Type { .. }, GenericArg::Type(Type::Generic(ty)))
if *ty == param.name =>
{
if let ty::TraitContainer = assoc_item.container {
let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
let mut generics =
clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates);
// Filter out the bounds that are (likely?) directly attached to the associated type,
// as opposed to being located in the where clause.
let mut bounds = generics
.where_predicates
.drain_filter(|pred| match *pred {
WherePredicate::BoundPredicate {
ty: QPath { ref assoc, ref self_type, ref trait_, .. },
..
} => {
if assoc.name != my_name {
return false;
}
if trait_.def_id() != assoc_item.container_id(tcx) {
return false;
}
match **self_type {
Generic(ref s) if *s == kw::SelfUpper => {}
_ => return false,
}
match &assoc.args {
GenericArgs::AngleBracketed { args, bindings } => {
if !bindings.is_empty()
|| generics
.params
.iter()
.zip(args.iter())
.any(|(param, arg)| !param_eq_arg(param, arg))
{
return false;
}
}
GenericArgs::Parenthesized { .. } => {
// The only time this happens is if we're inside the rustdoc for Fn(),
// which only has one associated type, which is not a GAT, so whatever.
}
}
true
}
(
GenericParamDefKind::Lifetime { .. },
GenericArg::Lifetime(Lifetime(lt)),
) if *lt == param.name => true,
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => {
match &c.kind {
ConstantKind::TyConst { expr } => expr == param.name.as_str(),
_ => false,
}
}
_ => false,
})
.flat_map(|pred| {
if let WherePredicate::BoundPredicate { bounds, .. } = pred {
bounds
} else {
unreachable!()
}
})
.collect::<Vec<_>>();
// Our Sized/?Sized bound didn't get handled when creating the generics
// because we didn't actually get our whole set of bounds until just now
// (some of them may have come from the trait). If we do have a sized
// bound, we remove it, and if we don't then we add the `?Sized` bound
// at the end.
match bounds.iter().position(|b| b.is_sized_bound(cx)) {
Some(i) => {
bounds.remove(i);
}
None => bounds.push(GenericBound::maybe_sized(cx)),
}
if let ty::TraitContainer = self.container {
let bounds = tcx.explicit_item_bounds(self.def_id);
let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
let mut generics =
clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates);
// Filter out the bounds that are (likely?) directly attached to the associated type,
// as opposed to being located in the where clause.
let mut bounds = generics
.where_predicates
.drain_filter(|pred| match *pred {
WherePredicate::BoundPredicate {
ty: QPath { ref assoc, ref self_type, ref trait_, .. },
..
} => {
if assoc.name != my_name {
return false;
}
if trait_.def_id() != self.container_id(tcx) {
return false;
}
match **self_type {
Generic(ref s) if *s == kw::SelfUpper => {}
_ => return false,
}
match &assoc.args {
GenericArgs::AngleBracketed { args, bindings } => {
if !bindings.is_empty()
|| generics
.params
.iter()
.zip(args.iter())
.any(|(param, arg)| !param_eq_arg(param, arg))
{
return false;
}
}
GenericArgs::Parenthesized { .. } => {
// The only time this happens is if we're inside the rustdoc for Fn(),
// which only has one associated type, which is not a GAT, so whatever.
}
}
true
}
_ => false,
})
.flat_map(|pred| {
if let WherePredicate::BoundPredicate { bounds, .. } = pred {
bounds
} else {
unreachable!()
}
})
.collect::<Vec<_>>();
// Our Sized/?Sized bound didn't get handled when creating the generics
// because we didn't actually get our whole set of bounds until just now
// (some of them may have come from the trait). If we do have a sized
// bound, we remove it, and if we don't then we add the `?Sized` bound
// at the end.
match bounds.iter().position(|b| b.is_sized_bound(cx)) {
Some(i) => {
bounds.remove(i);
}
None => bounds.push(GenericBound::maybe_sized(cx)),
}
if tcx.impl_defaultness(self.def_id).has_value() {
AssocTypeItem(
Box::new(Typedef {
type_: clean_middle_ty(
tcx.type_of(self.def_id),
cx,
Some(self.def_id),
),
generics,
// FIXME: should we obtain the Type from HIR and pass it on here?
item_type: None,
}),
bounds,
)
} else {
TyAssocTypeItem(Box::new(generics), bounds)
}
} else {
// FIXME: when could this happen? Associated items in inherent impls?
if tcx.impl_defaultness(assoc_item.def_id).has_value() {
AssocTypeItem(
Box::new(Typedef {
type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)),
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
type_: clean_middle_ty(
tcx.type_of(assoc_item.def_id),
cx,
Some(assoc_item.def_id),
),
generics,
// FIXME: should we obtain the Type from HIR and pass it on here?
item_type: None,
}),
Vec::new(),
bounds,
)
} else {
TyAssocTypeItem(Box::new(generics), bounds)
}
} else {
// FIXME: when could this happen? Associated items in inherent impls?
AssocTypeItem(
Box::new(Typedef {
type_: clean_middle_ty(
tcx.type_of(assoc_item.def_id),
cx,
Some(assoc_item.def_id),
),
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
item_type: None,
}),
Vec::new(),
)
}
};
let mut what_rustc_thinks =
Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx);
let impl_ref = tcx.impl_trait_ref(tcx.parent(self.def_id));
// Trait impl items always inherit the impl's visibility --
// we don't want to show `pub`.
if impl_ref.is_some() {
what_rustc_thinks.visibility = Visibility::Inherited;
}
};
what_rustc_thinks
let mut what_rustc_thinks =
Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx);
let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id));
// Trait impl items always inherit the impl's visibility --
// we don't want to show `pub`.
if impl_ref.is_some() {
what_rustc_thinks.visibility = Visibility::Inherited;
}
what_rustc_thinks
}
fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type {
@ -1824,39 +1826,44 @@ fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
Path { res: path.res, segments: path.segments.iter().map(|x| x.clean(cx)).collect() }
}
impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs {
if self.parenthesized {
let output = clean_ty(self.bindings[0].ty(), cx);
let output =
if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
let inputs = self.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
GenericArgs::Parenthesized { inputs, output }
} else {
let args = self
.args
.iter()
.map(|arg| match arg {
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
GenericArg::Lifetime(clean_lifetime(*lt, cx))
}
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))),
hir::GenericArg::Infer(_inf) => GenericArg::Infer,
})
.collect::<Vec<_>>()
.into();
let bindings =
self.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::<Vec<_>>().into();
GenericArgs::AngleBracketed { args, bindings }
}
fn clean_generic_args<'tcx>(
generic_args: &hir::GenericArgs<'tcx>,
cx: &mut DocContext<'tcx>,
) -> GenericArgs {
if generic_args.parenthesized {
let output = clean_ty(generic_args.bindings[0].ty(), cx);
let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
let inputs =
generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
GenericArgs::Parenthesized { inputs, output }
} else {
let args = generic_args
.args
.iter()
.map(|arg| match arg {
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
GenericArg::Lifetime(clean_lifetime(*lt, cx))
}
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))),
hir::GenericArg::Infer(_inf) => GenericArg::Infer,
})
.collect::<Vec<_>>()
.into();
let bindings = generic_args
.bindings
.iter()
.map(|x| clean_type_binding(x, cx))
.collect::<Vec<_>>()
.into();
GenericArgs::AngleBracketed { args, bindings }
}
}
impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment {
PathSegment { name: self.ident.name, args: self.args().clean(cx) }
PathSegment { name: self.ident.name, args: clean_generic_args(self.args(), cx) }
}
}
@ -2226,7 +2233,10 @@ fn clean_type_binding<'tcx>(
cx: &mut DocContext<'tcx>,
) -> TypeBinding {
TypeBinding {
assoc: PathSegment { name: type_binding.ident.name, args: type_binding.gen_args.clean(cx) },
assoc: PathSegment {
name: type_binding.ident.name,
args: clean_generic_args(type_binding.gen_args, cx),
},
kind: match type_binding.kind {
hir::TypeBindingKind::Equality { ref term } => {
TypeBindingKind::Equality { term: clean_hir_term(term, cx) }

View file

@ -2495,14 +2495,15 @@ impl SubstParam {
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// These are in alphabetical order, which is easy to maintain.
rustc_data_structures::static_assert_size!(Crate, 72); // frequently moved by-value
rustc_data_structures::static_assert_size!(DocFragment, 32);
rustc_data_structures::static_assert_size!(GenericArg, 80);
rustc_data_structures::static_assert_size!(GenericArgs, 32);
rustc_data_structures::static_assert_size!(GenericParamDef, 56);
rustc_data_structures::static_assert_size!(Item, 56);
rustc_data_structures::static_assert_size!(ItemKind, 112);
rustc_data_structures::static_assert_size!(PathSegment, 40);
rustc_data_structures::static_assert_size!(Type, 72);
static_assert_size!(Crate, 72); // frequently moved by-value
static_assert_size!(DocFragment, 32);
static_assert_size!(GenericArg, 80);
static_assert_size!(GenericArgs, 32);
static_assert_size!(GenericParamDef, 56);
static_assert_size!(Item, 56);
static_assert_size!(ItemKind, 112);
static_assert_size!(PathSegment, 40);
static_assert_size!(Type, 72);
}

View file

@ -12,8 +12,6 @@
let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
scope 1 {
debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10
}

View file

@ -10,15 +10,14 @@
let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
scope 1 {
debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
}
scope 2 {
}
+ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
+ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ let mut _9: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ }
bb0: {
@ -37,10 +36,10 @@
StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
// mir::Constant
- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
- // + user_ty: UserType(1)
@ -51,11 +50,11 @@
+ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ Deinit((*_8)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43

View file

@ -10,15 +10,14 @@
let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
scope 1 {
debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
}
scope 2 {
}
+ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
+ let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ let mut _9: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ }
bb0: {
@ -37,10 +36,10 @@
StorageLive(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _9 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ _9 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
// mir::Constant
- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
- // + user_ty: UserType(1)
@ -51,11 +50,11 @@
+ // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ // + user_ty: UserType(0)
+ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
+ Deinit((*_9)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_10); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_9); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ Deinit((*_8)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
StorageDead(_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
_1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43

View file

@ -74,10 +74,10 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
2 => {
let seg = PathSegment::from_ident(Ident::from_str("x"));
iter_exprs(depth - 1, &mut |e| {
g(ExprKind::MethodCall(seg.clone(), vec![e, make_x()], DUMMY_SP))
g(ExprKind::MethodCall(seg.clone(), e, vec![make_x()], DUMMY_SP))
});
iter_exprs(depth - 1, &mut |e| {
g(ExprKind::MethodCall(seg.clone(), vec![make_x(), e], DUMMY_SP))
g(ExprKind::MethodCall(seg.clone(), make_x(), vec![e], DUMMY_SP))
});
}
3..=8 => {

View file

@ -0,0 +1,12 @@
macro_rules! cbor_map {
($key:expr) => {
$key.signum();
//~^ ERROR can't call method `signum` on ambiguous numeric type `{integer}` [E0689]
};
}
fn main() {
cbor_map! { #[cfg(test)] 4};
//~^ ERROR attributes on expressions are experimental
//~| ERROR removing an expression is not supported in this position
}

View file

@ -0,0 +1,34 @@
error[E0658]: attributes on expressions are experimental
--> $DIR/cfg-method-receiver.rs:9:17
|
LL | cbor_map! { #[cfg(test)] 4};
| ^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error: removing an expression is not supported in this position
--> $DIR/cfg-method-receiver.rs:9:17
|
LL | cbor_map! { #[cfg(test)] 4};
| ^^^^^^^^^^^^
error[E0689]: can't call method `signum` on ambiguous numeric type `{integer}`
--> $DIR/cfg-method-receiver.rs:3:14
|
LL | $key.signum();
| ^^^^^^
...
LL | cbor_map! { #[cfg(test)] 4};
| --------------------------- in this macro invocation
|
= note: this error originates in the macro `cbor_map` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you must specify a concrete type for this numeric value, like `i32`
|
LL | cbor_map! { #[cfg(test)] 4_i32};
| ~~~~~
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0658, E0689.
For more information about an error, try `rustc --explain E0658`.

View file

@ -1,5 +1,4 @@
// aux-build:enums.rs
// run-pass
extern crate enums;
@ -7,11 +6,6 @@ use enums::FieldLessWithNonExhaustiveVariant;
fn main() {
let e = FieldLessWithNonExhaustiveVariant::default();
// FIXME: https://github.com/rust-lang/rust/issues/91161
// This `as` cast *should* be an error, since it would fail
// if the non-exhaustive variant got fields. But today it
// doesn't. The fix for that will update this test to
// show an error (and not be run-pass any more).
let d = e as u8;
let d = e as u8; //~ ERROR casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid [E0606]
assert_eq!(d, 0);
}

View file

@ -0,0 +1,11 @@
error[E0606]: casting `FieldLessWithNonExhaustiveVariant` as `u8` is invalid
--> $DIR/enum-as-cast.rs:9:13
|
LL | let d = e as u8;
| ^^^^^^^
|
= note: cannot cast an enum with a non-exhaustive variant when it's defined in another crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0606`.

View file

@ -0,0 +1,41 @@
// check-pass
// compile-flags: -Zhir-stats
// only-x86_64
// The aim here is to include at least one of every different type of top-level
// AST/HIR node reported by `-Zhir-stats`.
#![allow(dead_code)]
use std::arch::asm;
use std::fmt::Debug;
use std::ffi::c_void;
extern "C" { fn f(p: *mut c_void); }
/// An enum.
enum E<'a, T: Copy> { A { t: T }, B(&'a u32) }
trait Go {
type G: Debug;
fn go(self) -> u32;
}
impl<'a, T: Copy> Go for E<'a, T> {
type G = bool;
fn go(self) -> u32 {
99
}
}
fn f2<T>(t: T) where T: Debug {}
fn main() {
let x = E::A { t: 3 };
match x {
E::A { .. } => {}
_ => {}
}
unsafe { asm!("mov rdi, 1"); }
}

View file

@ -0,0 +1,151 @@
PRE EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
ExprField 48 ( 0.5%) 1 48
GenericArgs 64 ( 0.7%) 1 64
- AngleBracketed 64 ( 0.7%) 1
Local 72 ( 0.8%) 1 72
WherePredicate 72 ( 0.8%) 1 72
- BoundPredicate 72 ( 0.8%) 1
Crate 72 ( 0.8%) 1 72
Arm 96 ( 1.0%) 2 48
FieldDef 160 ( 1.7%) 2 80
ForeignItem 160 ( 1.7%) 1 160
- Fn 160 ( 1.7%) 1
Stmt 160 ( 1.7%) 5 32
- Local 32 ( 0.3%) 1
- MacCall 32 ( 0.3%) 1
- Expr 96 ( 1.0%) 3
Param 160 ( 1.7%) 4 40
FnDecl 200 ( 2.2%) 5 40
Variant 240 ( 2.6%) 2 120
Block 288 ( 3.1%) 6 48
Attribute 304 ( 3.3%) 2 152
- Normal 152 ( 1.7%) 1
- DocComment 152 ( 1.7%) 1
GenericBound 352 ( 3.8%) 4 88
- Trait 352 ( 3.8%) 4
GenericParam 520 ( 5.7%) 5 104
AssocItem 640 ( 7.0%) 4 160
- TyAlias 320 ( 3.5%) 2
- Fn 320 ( 3.5%) 2
PathSegment 720 ( 7.9%) 30 24
Expr 832 ( 9.1%) 8 104
- Path 104 ( 1.1%) 1
- Match 104 ( 1.1%) 1
- Struct 104 ( 1.1%) 1
- Lit 208 ( 2.3%) 2
- Block 312 ( 3.4%) 3
Pat 840 ( 9.2%) 7 120
- Struct 120 ( 1.3%) 1
- Wild 120 ( 1.3%) 1
- Ident 600 ( 6.6%) 5
Ty 1_344 (14.7%) 14 96
- Rptr 96 ( 1.0%) 1
- Ptr 96 ( 1.0%) 1
- ImplicitSelf 192 ( 2.1%) 2
- Path 960 (10.5%) 10
Item 1_800 (19.7%) 9 200
- Trait 200 ( 2.2%) 1
- Enum 200 ( 2.2%) 1
- ForeignMod 200 ( 2.2%) 1
- Impl 200 ( 2.2%) 1
- Fn 400 ( 4.4%) 2
- Use 600 ( 6.6%) 3
----------------------------------------------------------------
Total 9_144
POST EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
ExprField 48 ( 0.5%) 1 48
GenericArgs 64 ( 0.6%) 1 64
- AngleBracketed 64 ( 0.6%) 1
Local 72 ( 0.7%) 1 72
WherePredicate 72 ( 0.7%) 1 72
- BoundPredicate 72 ( 0.7%) 1
Crate 72 ( 0.7%) 1 72
Arm 96 ( 0.9%) 2 48
InlineAsm 120 ( 1.2%) 1 120
FieldDef 160 ( 1.6%) 2 80
ForeignItem 160 ( 1.6%) 1 160
- Fn 160 ( 1.6%) 1
Stmt 160 ( 1.6%) 5 32
- Local 32 ( 0.3%) 1
- Semi 32 ( 0.3%) 1
- Expr 96 ( 0.9%) 3
Param 160 ( 1.6%) 4 40
FnDecl 200 ( 2.0%) 5 40
Variant 240 ( 2.4%) 2 120
Block 288 ( 2.8%) 6 48
GenericBound 352 ( 3.5%) 4 88
- Trait 352 ( 3.5%) 4
GenericParam 520 ( 5.1%) 5 104
Attribute 608 ( 6.0%) 4 152
- DocComment 152 ( 1.5%) 1
- Normal 456 ( 4.5%) 3
AssocItem 640 ( 6.3%) 4 160
- TyAlias 320 ( 3.2%) 2
- Fn 320 ( 3.2%) 2
PathSegment 792 ( 7.8%) 33 24
Pat 840 ( 8.3%) 7 120
- Struct 120 ( 1.2%) 1
- Wild 120 ( 1.2%) 1
- Ident 600 ( 5.9%) 5
Expr 936 ( 9.2%) 9 104
- Path 104 ( 1.0%) 1
- Match 104 ( 1.0%) 1
- Struct 104 ( 1.0%) 1
- InlineAsm 104 ( 1.0%) 1
- Lit 208 ( 2.1%) 2
- Block 312 ( 3.1%) 3
Ty 1_344 (13.2%) 14 96
- Rptr 96 ( 0.9%) 1
- Ptr 96 ( 0.9%) 1
- ImplicitSelf 192 ( 1.9%) 2
- Path 960 ( 9.5%) 10
Item 2_200 (21.7%) 11 200
- Trait 200 ( 2.0%) 1
- Enum 200 ( 2.0%) 1
- ExternCrate 200 ( 2.0%) 1
- ForeignMod 200 ( 2.0%) 1
- Impl 200 ( 2.0%) 1
- Fn 400 ( 3.9%) 2
- Use 800 ( 7.9%) 4
----------------------------------------------------------------
Total 10_144
HIR STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
Param 64 ( 0.7%) 2 32
Local 64 ( 0.7%) 1 64
ForeignItem 72 ( 0.7%) 1 72
FieldDef 96 ( 1.0%) 2 48
Arm 96 ( 1.0%) 2 48
Stmt 96 ( 1.0%) 3 32
FnDecl 120 ( 1.2%) 3 40
Lifetime 128 ( 1.3%) 4 32
Variant 160 ( 1.6%) 2 80
ImplItem 176 ( 1.8%) 2 88
GenericBound 192 ( 2.0%) 4 48
TraitItem 192 ( 2.0%) 2 96
WherePredicate 216 ( 2.2%) 3 72
Block 288 ( 3.0%) 6 48
QPath 408 ( 4.2%) 17 24
Pat 440 ( 4.5%) 5 88
Attribute 608 ( 6.2%) 4 152
Expr 672 ( 6.9%) 12 56
Item 960 ( 9.9%) 12 80
Ty 1_152 (11.8%) 16 72
Path 1_296 (13.3%) 27 48
PathSegment 2_240 (23.0%) 40 56
----------------------------------------------------------------
Total 9_736

View file

@ -61,9 +61,8 @@ impl EarlyLintPass for DoubleParens {
}
}
},
ExprKind::MethodCall(_, ref params, _) => {
if params.len() == 2 {
let param = &params[1];
ExprKind::MethodCall(_, _, ref params, _) => {
if let [ref param] = params[..] {
if let ExprKind::Paren(_) = param.kind {
span_lint(cx, DOUBLE_PARENS, param.span, msg);
}

View file

@ -37,9 +37,9 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]);
impl EarlyLintPass for OptionEnvUnwrap {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if_chain! {
if let ExprKind::MethodCall(path_segment, args, _) = &expr.kind;
if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind;
if matches!(path_segment.ident.name, sym::expect | sym::unwrap);
if let ExprKind::Call(caller, _) = &args[0].kind;
if let ExprKind::Call(caller, _) = &receiver.kind;
if is_direct_expn_of(caller.span, "option_env").is_some();
then {
span_lint_and_help(

View file

@ -109,12 +109,12 @@ impl EarlyLintPass for Precedence {
let mut arg = operand;
let mut all_odd = true;
while let ExprKind::MethodCall(path_segment, args, _) = &arg.kind {
while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind {
let path_segment_str = path_segment.ident.name.as_str();
all_odd &= ALLOWED_ODD_FUNCTIONS
.iter()
.any(|odd_function| **odd_function == *path_segment_str);
arg = args.first().expect("A method always has a receiver.");
arg = receiver;
}
if_chain! {

View file

@ -595,7 +595,7 @@ fn ident_difference_expr_with_base_location(
| (Unary(_, _), Unary(_, _))
| (Binary(_, _, _), Binary(_, _, _))
| (Tup(_), Tup(_))
| (MethodCall(_, _, _), MethodCall(_, _, _))
| (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
| (Call(_, _), Call(_, _))
| (ConstBlock(_), ConstBlock(_))
| (Array(_), Array(_))

View file

@ -30,11 +30,10 @@ declare_clippy_lint! {
declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind
if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind
&& let method_name = name_ident.ident.name.as_str()
&& (method_name == "ceil" || method_name == "round" || method_name == "floor")
&& !args.is_empty()
&& let ExprKind::Lit(spanned) = &args[0].kind
&& let ExprKind::Lit(spanned) = &receiver.kind
&& let LitKind::Float(symbol, ty) = spanned.kind {
let f = symbol.as_str().parse::<f64>().unwrap();
let f_str = symbol.to_string() + if let LitFloatType::Suffixed(ty) = ty {

View file

@ -147,7 +147,9 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
(Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
(Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
(MethodCall(lc, la, _), MethodCall(rc, ra, _)) => eq_path_seg(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
(MethodCall(lc, ls, la, _), MethodCall(rc, rs, ra, _)) => {
eq_path_seg(lc, rc) && eq_expr(ls, rs) && over(la, ra, |l, r| eq_expr(l, r))
},
(Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),
(Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
(Lit(l), Lit(r)) => l.kind == r.kind,

View file

@ -201,6 +201,19 @@ async function main(argv) {
process.setMaxListeners(opts["jobs"] + 1);
}
// We catch this "event" to display a nicer message in case of unexpected exit (because of a
// missing `--no-sandbox`).
const exitHandling = (code) => {
if (!opts["no_sandbox"]) {
console.log("");
console.log(
"`browser-ui-test` crashed unexpectedly. Please try again with adding `--test-args \
--no-sandbox` at the end. For example: `x.py test src/test/rustdoc-gui --test-args --no-sandbox`");
console.log("");
}
};
process.on('exit', exitHandling);
const tests_queue = [];
let results = {
successful: [],
@ -247,6 +260,9 @@ async function main(argv) {
}
status_bar.finish();
// We don't need this listener anymore.
process.removeListener("exit", exitHandling);
if (debug) {
results.successful.sort(by_filename);
results.successful.forEach(r => {

View file

@ -145,7 +145,7 @@ impl ChainItemKind {
fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) {
let (kind, span) = match expr.kind {
ast::ExprKind::MethodCall(ref segment, ref expressions, _) => {
ast::ExprKind::MethodCall(ref segment, ref receiver, ref expressions, _) => {
let types = if let Some(ref generic_args) = segment.args {
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
data.args
@ -163,7 +163,7 @@ impl ChainItemKind {
} else {
vec![]
};
let span = mk_sp(expressions[0].span.hi(), expr.span.hi());
let span = mk_sp(receiver.span.hi(), expr.span.hi());
let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone());
(kind, span)
}
@ -253,7 +253,7 @@ impl ChainItem {
format!("::<{}>", type_list.join(", "))
};
let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str);
rewrite_call(context, &callee_str, &args[1..], span, shape)
rewrite_call(context, &callee_str, &args, span, shape)
}
}
@ -400,8 +400,8 @@ impl Chain {
// is a try! macro, we'll convert it to shorthand when the option is set.
fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option<ast::Expr> {
match expr.kind {
ast::ExprKind::MethodCall(_, ref expressions, _) => {
Some(Self::convert_try(&expressions[0], context))
ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
Some(Self::convert_try(&receiver, context))
}
ast::ExprKind::Field(ref subexpr, _)
| ast::ExprKind::Try(ref subexpr)