Skip to content

Commit

Permalink
Auto merge of #88596 - m-ou-se:rollup-cidzt4v, r=m-ou-se
Browse files Browse the repository at this point in the history
Rollup of 12 pull requests

Successful merges:

 - #88177 (Stabilize std::os::unix::fs::chroot)
 - #88505 (Use `unwrap_unchecked` where possible)
 - #88512 (Upgrade array_into_iter lint to include Deref-to-array types.)
 - #88532 (Remove single use variables)
 - #88543 (Improve closure dummy capture suggestion in macros.)
 - #88560 (`fmt::Formatter::pad`: don't call chars().count() more than one time)
 - #88565 (Add regression test for issue 83190)
 - #88567 (Remove redundant `Span` in `QueryJobInfo`)
 - #88573 (rustdoc: Don't panic on ambiguous inherent associated types)
 - #88582 (Implement #88581)
 - #88589 (Correct doc comments inside `use_expr_visitor.rs`)
 - #88592 (Fix ICE in const check)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 2, 2021
2 parents 1cf8fdd + c082e15 commit b834c4c
Show file tree
Hide file tree
Showing 28 changed files with 726 additions and 216 deletions.
54 changes: 30 additions & 24 deletions compiler/rustc_lint/src/array_into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,39 +74,45 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
_ => return,
};

// As this is a method call expression, we have at least one
// argument.
// As this is a method call expression, we have at least one argument.
let receiver_arg = &args[0];
let receiver_ty = cx.typeck_results().expr_ty(receiver_arg);
let adjustments = cx.typeck_results().expr_adjustments(receiver_arg);

// Peel all `Box<_>` layers. We have to special case `Box` here as
// `Box` is the only thing that values can be moved out of via
// method call. `Box::new([1]).into_iter()` should trigger this
// lint.
let mut recv_ty = cx.typeck_results().expr_ty(receiver_arg);
let mut num_box_derefs = 0;
while recv_ty.is_box() {
num_box_derefs += 1;
recv_ty = recv_ty.boxed_ty();
}
let target = match adjustments.last() {
Some(Adjustment { kind: Adjust::Borrow(_), target }) => target,
_ => return,
};

// Make sure we found an array after peeling the boxes.
if !matches!(recv_ty.kind(), ty::Array(..)) {
return;
let types =
std::iter::once(receiver_ty).chain(adjustments.iter().map(|adj| adj.target));

let mut found_array = false;

for ty in types {
match ty.kind() {
// If we run into a &[T; N] or &[T] first, there's nothing to warn about.
// It'll resolve to the reference version.
ty::Ref(_, inner_ty, _) if inner_ty.is_array() => return,
ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Slice(..)) => return,
// Found an actual array type without matching a &[T; N] first.
// This is the problematic case.
ty::Array(..) => {
found_array = true;
break;
}
_ => {}
}
}

// Make sure that there is an autoref coercion at the expected
// position. The first `num_box_derefs` adjustments are the derefs
// of the box.
match cx.typeck_results().expr_adjustments(receiver_arg).get(num_box_derefs) {
Some(Adjustment { kind: Adjust::Borrow(_), .. }) => {}
_ => return,
if !found_array {
return;
}

// Emit lint diagnostic.
let target = match *cx.typeck_results().expr_ty_adjusted(receiver_arg).kind() {
let target = match *target.kind() {
ty::Ref(_, inner_ty, _) if inner_ty.is_array() => "[T; N]",
ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Slice(..)) => "[T]",

// We know the original first argument type is an array type,
// we know that the first adjustment was an autoref coercion
// and we know that `IntoIterator` is the trait involved. The
Expand Down Expand Up @@ -135,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
String::new(),
Applicability::MaybeIncorrect,
);
} else {
} else if receiver_ty.is_array() {
diag.multipart_suggestion(
"or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value",
vec![
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,7 @@ impl<'tcx> Body<'tcx> {
/// Returns an iterator over all function arguments.
#[inline]
pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
(1..arg_count + 1).map(Local::new)
(1..self.arg_count + 1).map(Local::new)
}

/// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
Expand All @@ -421,9 +420,7 @@ impl<'tcx> Body<'tcx> {
pub fn vars_and_temps_iter(
&self,
) -> impl DoubleEndedIterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
let local_count = self.local_decls.len();
(arg_count + 1..local_count).map(Local::new)
(self.arg_count + 1..self.local_decls.len()).map(Local::new)
}

#[inline]
Expand Down
36 changes: 19 additions & 17 deletions compiler/rustc_mir/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
use rustc_span::{sym, Span, Symbol};
Expand Down Expand Up @@ -793,7 +793,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {

let fn_ty = func.ty(body, tcx);

let (mut callee, substs) = match *fn_ty.kind() {
let (mut callee, mut substs) = match *fn_ty.kind() {
ty::FnDef(def_id, substs) => (def_id, substs),

ty::FnPtr(_) => {
Expand Down Expand Up @@ -846,29 +846,31 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
.iter()
.find(|did| tcx.item_name(**did) == callee_name)
{
// using internal substs is ok here, since this is only
// used for the `resolve` call below
substs = InternalSubsts::identity_for_item(tcx, did);
callee = did;
}
}
_ => {
if !tcx.is_const_fn_raw(callee) {
// At this point, it is only legal when the caller is marked with
// #[default_method_body_is_const], and the callee is in the same
// trait.
let callee_trait = tcx.trait_of_item(callee);
if callee_trait.is_some() {
if tcx.has_attr(caller, sym::default_method_body_is_const) {
if tcx.trait_of_item(caller) == callee_trait {
nonconst_call_permission = true;
}
_ if !tcx.is_const_fn_raw(callee) => {
// At this point, it is only legal when the caller is marked with
// #[default_method_body_is_const], and the callee is in the same
// trait.
let callee_trait = tcx.trait_of_item(callee);
if callee_trait.is_some() {
if tcx.has_attr(caller, sym::default_method_body_is_const) {
if tcx.trait_of_item(caller) == callee_trait {
nonconst_call_permission = true;
}
}
}

if !nonconst_call_permission {
self.check_op(ops::FnCallNonConst);
return;
}
if !nonconst_call_permission {
self.check_op(ops::FnCallNonConst);
return;
}
}
_ => {}
}

// Resolve a trait method call to its concrete implementation, which may be in a
Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_query_system/src/query/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ where
}

fn query(self, map: &QueryMap<D>) -> QueryStackFrame {
map.get(&self).unwrap().info.query.clone()
map.get(&self).unwrap().query.clone()
}

#[cfg(parallel_compiler)]
Expand All @@ -81,7 +81,7 @@ where
}

pub struct QueryJobInfo<D> {
pub info: QueryInfo,
pub query: QueryStackFrame,
pub job: QueryJob<D>,
}

Expand Down Expand Up @@ -155,7 +155,7 @@ where

while let Some(job) = current_job {
let info = query_map.get(&job).unwrap();
cycle.push(info.info.clone());
cycle.push(QueryInfo { span: info.job.span, query: info.query.clone() });

if job == *self {
cycle.reverse();
Expand All @@ -170,7 +170,7 @@ where
.job
.parent
.as_ref()
.map(|parent| (info.info.span, parent.query(&query_map)));
.map(|parent| (info.job.span, parent.query(&query_map)));
return CycleError { usage, cycle };
}

Expand Down Expand Up @@ -649,13 +649,10 @@ pub fn print_query_stack<CTX: QueryContext>(
};
let mut diag = Diagnostic::new(
Level::FailureNote,
&format!(
"#{} [{}] {}",
i, query_info.info.query.name, query_info.info.query.description
),
&format!("#{} [{}] {}", i, query_info.query.name, query_info.query.description),
);
diag.span =
tcx.dep_context().sess().source_map().guess_head_span(query_info.info.span).into();
tcx.dep_context().sess().source_map().guess_head_span(query_info.job.span).into();
handler.force_print_diagnostic(diag);

current_query = query_info.job.parent;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_query_system/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ where
for (k, v) in shard.active.iter() {
if let QueryResult::Started(ref job) = *v {
let id = QueryJobId::new(job.id, shard_id, kind);
let info = QueryInfo { span: job.span, query: make_query(tcx, k.clone()) };
jobs.insert(id, QueryJobInfo { info, job: job.clone() });
let query = make_query(tcx, k.clone());
jobs.insert(id, QueryJobInfo { query, job: job.clone() });
}
}
}
Expand Down
35 changes: 26 additions & 9 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use rustc_middle::ty::{
};
use rustc_session::lint;
use rustc_span::sym;
use rustc_span::{BytePos, MultiSpan, Pos, Span, Symbol, DUMMY_SP};
use rustc_span::{BytePos, MultiSpan, Pos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;

use rustc_data_structures::stable_map::FxHashMap;
Expand Down Expand Up @@ -680,15 +680,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
migrated_variables_concat
);

// If the body was entirely expanded from a macro
// invocation, i.e. the body is not contained inside the
// closure span, then we walk up the expansion until we
// find the span before the expansion.
let closure_body_span = self.tcx.hir().span(body_id.hir_id)
.find_ancestor_inside(closure_span)
.unwrap_or(DUMMY_SP);
let mut closure_body_span = {
// If the body was entirely expanded from a macro
// invocation, i.e. the body is not contained inside the
// closure span, then we walk up the expansion until we
// find the span before the expansion.
let s = self.tcx.hir().span(body_id.hir_id);
s.find_ancestor_inside(closure_span).unwrap_or(s)
};

if let Ok(mut s) = self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
if s.starts_with('$') {
// Looks like a macro fragment. Try to find the real block.
if let Some(hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::Block(block, ..), ..
})) = self.tcx.hir().find(body_id.hir_id) {
// If the body is a block (with `{..}`), we use the span of that block.
// E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
// Since we know it's a block, we know we can insert the `let _ = ..` without
// breaking the macro syntax.
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(block.span) {
closure_body_span = block.span;
s = snippet;
}
}
}

if let Ok(s) = self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
let mut lines = s.lines();
let line1 = lines.next().unwrap_or_default();

Expand Down
Loading

0 comments on commit b834c4c

Please sign in to comment.