Skip to content

Commit b834c4c

Browse files
committed
Auto merge of rust-lang#88596 - m-ou-se:rollup-cidzt4v, r=m-ou-se
Rollup of 12 pull requests Successful merges: - rust-lang#88177 (Stabilize std::os::unix::fs::chroot) - rust-lang#88505 (Use `unwrap_unchecked` where possible) - rust-lang#88512 (Upgrade array_into_iter lint to include Deref-to-array types.) - rust-lang#88532 (Remove single use variables) - rust-lang#88543 (Improve closure dummy capture suggestion in macros.) - rust-lang#88560 (`fmt::Formatter::pad`: don't call chars().count() more than one time) - rust-lang#88565 (Add regression test for issue 83190) - rust-lang#88567 (Remove redundant `Span` in `QueryJobInfo`) - rust-lang#88573 (rustdoc: Don't panic on ambiguous inherent associated types) - rust-lang#88582 (Implement rust-lang#88581) - rust-lang#88589 (Correct doc comments inside `use_expr_visitor.rs`) - rust-lang#88592 (Fix ICE in const check) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1cf8fdd + c082e15 commit b834c4c

File tree

28 files changed

+726
-216
lines changed

28 files changed

+726
-216
lines changed

compiler/rustc_lint/src/array_into_iter.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -74,39 +74,45 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
7474
_ => return,
7575
};
7676

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

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

92-
// Make sure we found an array after peeling the boxes.
93-
if !matches!(recv_ty.kind(), ty::Array(..)) {
94-
return;
87+
let types =
88+
std::iter::once(receiver_ty).chain(adjustments.iter().map(|adj| adj.target));
89+
90+
let mut found_array = false;
91+
92+
for ty in types {
93+
match ty.kind() {
94+
// If we run into a &[T; N] or &[T] first, there's nothing to warn about.
95+
// It'll resolve to the reference version.
96+
ty::Ref(_, inner_ty, _) if inner_ty.is_array() => return,
97+
ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Slice(..)) => return,
98+
// Found an actual array type without matching a &[T; N] first.
99+
// This is the problematic case.
100+
ty::Array(..) => {
101+
found_array = true;
102+
break;
103+
}
104+
_ => {}
105+
}
95106
}
96107

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

105112
// Emit lint diagnostic.
106-
let target = match *cx.typeck_results().expr_ty_adjusted(receiver_arg).kind() {
113+
let target = match *target.kind() {
107114
ty::Ref(_, inner_ty, _) if inner_ty.is_array() => "[T; N]",
108115
ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Slice(..)) => "[T]",
109-
110116
// We know the original first argument type is an array type,
111117
// we know that the first adjustment was an autoref coercion
112118
// and we know that `IntoIterator` is the trait involved. The
@@ -135,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
135141
String::new(),
136142
Applicability::MaybeIncorrect,
137143
);
138-
} else {
144+
} else if receiver_ty.is_array() {
139145
diag.multipart_suggestion(
140146
"or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value",
141147
vec![

compiler/rustc_middle/src/mir/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,7 @@ impl<'tcx> Body<'tcx> {
411411
/// Returns an iterator over all function arguments.
412412
#[inline]
413413
pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
414-
let arg_count = self.arg_count;
415-
(1..arg_count + 1).map(Local::new)
414+
(1..self.arg_count + 1).map(Local::new)
416415
}
417416

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

429426
#[inline]

compiler/rustc_mir/src/transform/check_consts/check.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
99
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
1010
use rustc_middle::mir::*;
1111
use rustc_middle::ty::cast::CastTy;
12-
use rustc_middle::ty::subst::GenericArgKind;
12+
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
1313
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
1414
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
1515
use rustc_span::{sym, Span, Symbol};
@@ -793,7 +793,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
793793

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

796-
let (mut callee, substs) = match *fn_ty.kind() {
796+
let (mut callee, mut substs) = match *fn_ty.kind() {
797797
ty::FnDef(def_id, substs) => (def_id, substs),
798798

799799
ty::FnPtr(_) => {
@@ -846,29 +846,31 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
846846
.iter()
847847
.find(|did| tcx.item_name(**did) == callee_name)
848848
{
849+
// using internal substs is ok here, since this is only
850+
// used for the `resolve` call below
851+
substs = InternalSubsts::identity_for_item(tcx, did);
849852
callee = did;
850853
}
851854
}
852-
_ => {
853-
if !tcx.is_const_fn_raw(callee) {
854-
// At this point, it is only legal when the caller is marked with
855-
// #[default_method_body_is_const], and the callee is in the same
856-
// trait.
857-
let callee_trait = tcx.trait_of_item(callee);
858-
if callee_trait.is_some() {
859-
if tcx.has_attr(caller, sym::default_method_body_is_const) {
860-
if tcx.trait_of_item(caller) == callee_trait {
861-
nonconst_call_permission = true;
862-
}
855+
_ if !tcx.is_const_fn_raw(callee) => {
856+
// At this point, it is only legal when the caller is marked with
857+
// #[default_method_body_is_const], and the callee is in the same
858+
// trait.
859+
let callee_trait = tcx.trait_of_item(callee);
860+
if callee_trait.is_some() {
861+
if tcx.has_attr(caller, sym::default_method_body_is_const) {
862+
if tcx.trait_of_item(caller) == callee_trait {
863+
nonconst_call_permission = true;
863864
}
864865
}
866+
}
865867

866-
if !nonconst_call_permission {
867-
self.check_op(ops::FnCallNonConst);
868-
return;
869-
}
868+
if !nonconst_call_permission {
869+
self.check_op(ops::FnCallNonConst);
870+
return;
870871
}
871872
}
873+
_ => {}
872874
}
873875

874876
// Resolve a trait method call to its concrete implementation, which may be in a

compiler/rustc_query_system/src/query/job.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ where
6161
}
6262

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

6767
#[cfg(parallel_compiler)]
@@ -81,7 +81,7 @@ where
8181
}
8282

8383
pub struct QueryJobInfo<D> {
84-
pub info: QueryInfo,
84+
pub query: QueryStackFrame,
8585
pub job: QueryJob<D>,
8686
}
8787

@@ -155,7 +155,7 @@ where
155155

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

160160
if job == *self {
161161
cycle.reverse();
@@ -170,7 +170,7 @@ where
170170
.job
171171
.parent
172172
.as_ref()
173-
.map(|parent| (info.info.span, parent.query(&query_map)));
173+
.map(|parent| (info.job.span, parent.query(&query_map)));
174174
return CycleError { usage, cycle };
175175
}
176176

@@ -649,13 +649,10 @@ pub fn print_query_stack<CTX: QueryContext>(
649649
};
650650
let mut diag = Diagnostic::new(
651651
Level::FailureNote,
652-
&format!(
653-
"#{} [{}] {}",
654-
i, query_info.info.query.name, query_info.info.query.description
655-
),
652+
&format!("#{} [{}] {}", i, query_info.query.name, query_info.query.description),
656653
);
657654
diag.span =
658-
tcx.dep_context().sess().source_map().guess_head_span(query_info.info.span).into();
655+
tcx.dep_context().sess().source_map().guess_head_span(query_info.job.span).into();
659656
handler.force_print_diagnostic(diag);
660657

661658
current_query = query_info.job.parent;

compiler/rustc_query_system/src/query/plumbing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ where
130130
for (k, v) in shard.active.iter() {
131131
if let QueryResult::Started(ref job) = *v {
132132
let id = QueryJobId::new(job.id, shard_id, kind);
133-
let info = QueryInfo { span: job.span, query: make_query(tcx, k.clone()) };
134-
jobs.insert(id, QueryJobInfo { info, job: job.clone() });
133+
let query = make_query(tcx, k.clone());
134+
jobs.insert(id, QueryJobInfo { query, job: job.clone() });
135135
}
136136
}
137137
}

compiler/rustc_typeck/src/check/upvar.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use rustc_middle::ty::{
4747
};
4848
use rustc_session::lint;
4949
use rustc_span::sym;
50-
use rustc_span::{BytePos, MultiSpan, Pos, Span, Symbol, DUMMY_SP};
50+
use rustc_span::{BytePos, MultiSpan, Pos, Span, Symbol};
5151
use rustc_trait_selection::infer::InferCtxtExt;
5252

5353
use rustc_data_structures::stable_map::FxHashMap;
@@ -680,15 +680,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680680
migrated_variables_concat
681681
);
682682

683-
// If the body was entirely expanded from a macro
684-
// invocation, i.e. the body is not contained inside the
685-
// closure span, then we walk up the expansion until we
686-
// find the span before the expansion.
687-
let closure_body_span = self.tcx.hir().span(body_id.hir_id)
688-
.find_ancestor_inside(closure_span)
689-
.unwrap_or(DUMMY_SP);
683+
let mut closure_body_span = {
684+
// If the body was entirely expanded from a macro
685+
// invocation, i.e. the body is not contained inside the
686+
// closure span, then we walk up the expansion until we
687+
// find the span before the expansion.
688+
let s = self.tcx.hir().span(body_id.hir_id);
689+
s.find_ancestor_inside(closure_span).unwrap_or(s)
690+
};
691+
692+
if let Ok(mut s) = self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
693+
if s.starts_with('$') {
694+
// Looks like a macro fragment. Try to find the real block.
695+
if let Some(hir::Node::Expr(&hir::Expr {
696+
kind: hir::ExprKind::Block(block, ..), ..
697+
})) = self.tcx.hir().find(body_id.hir_id) {
698+
// If the body is a block (with `{..}`), we use the span of that block.
699+
// E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
700+
// Since we know it's a block, we know we can insert the `let _ = ..` without
701+
// breaking the macro syntax.
702+
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(block.span) {
703+
closure_body_span = block.span;
704+
s = snippet;
705+
}
706+
}
707+
}
690708

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

0 commit comments

Comments
 (0)