1
Fork 0

Auto merge of #106090 - WaffleLapkin:dereffffffffff, r=Nilstrieb

Remove some `ref` patterns from the compiler

Previous PR: https://github.com/rust-lang/rust/pull/105368

r? `@Nilstrieb`
This commit is contained in:
bors 2023-01-20 04:52:28 +00:00
commit 56ee85274e
53 changed files with 524 additions and 587 deletions

View file

@ -36,16 +36,16 @@ impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
impl fmt::Display for ConstEvalErrKind { impl fmt::Display for ConstEvalErrKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::ConstEvalErrKind::*; use self::ConstEvalErrKind::*;
match *self { match self {
ConstAccessesStatic => write!(f, "constant accesses static"), ConstAccessesStatic => write!(f, "constant accesses static"),
ModifiedGlobal => { ModifiedGlobal => {
write!(f, "modifying a static's initial value from another static's initializer") write!(f, "modifying a static's initial value from another static's initializer")
} }
AssertFailure(ref msg) => write!(f, "{:?}", msg), AssertFailure(msg) => write!(f, "{:?}", msg),
Panic { msg, line, col, file } => { Panic { msg, line, col, file } => {
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col) write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)
} }
Abort(ref msg) => write!(f, "{}", msg), Abort(msg) => write!(f, "{}", msg),
} }
} }
} }

View file

@ -533,7 +533,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
let eval_to_int = let eval_to_int =
|op| ecx.read_immediate(&ecx.eval_operand(op, None)?).map(|x| x.to_const_int()); |op| ecx.read_immediate(&ecx.eval_operand(op, None)?).map(|x| x.to_const_int());
let err = match msg { let err = match msg {
BoundsCheck { ref len, ref index } => { BoundsCheck { len, index } => {
let len = eval_to_int(len)?; let len = eval_to_int(len)?;
let index = eval_to_int(index)?; let index = eval_to_int(index)?;
BoundsCheck { len, index } BoundsCheck { len, index }

View file

@ -347,7 +347,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?; let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?;
self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest) self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
} }
(_, &ty::Dynamic(ref data, _, ty::Dyn)) => { (_, &ty::Dynamic(data, _, ty::Dyn)) => {
// Initial cast from sized to dyn trait // Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?; let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
let ptr = self.read_scalar(src)?; let ptr = self.read_scalar(src)?;

View file

@ -79,9 +79,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
} }
sym::variant_count => match tp_ty.kind() { sym::variant_count => match tp_ty.kind() {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
ty::Adt(ref adt, _) => { ty::Adt(adt, _) => ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx),
ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
}
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
throw_inval!(TooGeneric) throw_inval!(TooGeneric)
} }

View file

@ -863,7 +863,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
write!(fmt, "{id:?}")?; write!(fmt, "{id:?}")?;
match self.ecx.memory.alloc_map.get(id) { match self.ecx.memory.alloc_map.get(id) {
Some(&(kind, ref alloc)) => { Some((kind, alloc)) => {
// normal alloc // normal alloc
write!(fmt, " ({}, ", kind)?; write!(fmt, " ({}, ", kind)?;
write_allocation_track_relocs( write_allocation_track_relocs(

View file

@ -533,11 +533,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
use rustc_middle::mir::Operand::*; use rustc_middle::mir::Operand::*;
let op = match *mir_op { let op = match mir_op {
// FIXME: do some more logic on `move` to invalidate the old location // FIXME: do some more logic on `move` to invalidate the old location
Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?, &Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?,
Constant(ref constant) => { Constant(constant) => {
let c = let c =
self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?; self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?;

View file

@ -111,7 +111,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
M::retag_place_contents(self, *kind, &dest)?; M::retag_place_contents(self, *kind, &dest)?;
} }
Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
// Statements we do not track. // Statements we do not track.
AscribeUserType(..) => {} AscribeUserType(..) => {}
@ -163,8 +163,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.copy_op(&op, &dest, /*allow_transmute*/ false)?; self.copy_op(&op, &dest, /*allow_transmute*/ false)?;
} }
CopyForDeref(ref place) => { CopyForDeref(place) => {
let op = self.eval_place_to_op(*place, Some(dest.layout))?; let op = self.eval_place_to_op(place, Some(dest.layout))?;
self.copy_op(&op, &dest, /* allow_transmute*/ false)?; self.copy_op(&op, &dest, /* allow_transmute*/ false)?;
} }

View file

@ -419,7 +419,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
) )
} }
// Recursive checking // Recursive checking
if let Some(ref mut ref_tracking) = self.ref_tracking { if let Some(ref_tracking) = self.ref_tracking.as_deref_mut() {
// Proceed recursively even for ZST, no reason to skip them! // Proceed recursively even for ZST, no reason to skip them!
// `!` is a ZST and we want to validate it. // `!` is a ZST and we want to validate it.
if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr) { if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {

View file

@ -481,12 +481,12 @@ macro_rules! make_value_visitor {
}; };
// Visit the fields of this value. // Visit the fields of this value.
match v.layout().fields { match &v.layout().fields {
FieldsShape::Primitive => {} FieldsShape::Primitive => {}
FieldsShape::Union(fields) => { &FieldsShape::Union(fields) => {
self.visit_union(v, fields)?; self.visit_union(v, fields)?;
} }
FieldsShape::Arbitrary { ref offsets, .. } => { FieldsShape::Arbitrary { offsets, .. } => {
// FIXME: We collect in a vec because otherwise there are lifetime // FIXME: We collect in a vec because otherwise there are lifetime
// errors: Projecting to a field needs access to `ecx`. // errors: Projecting to a field needs access to `ecx`.
let fields: Vec<InterpResult<'tcx, Self::V>> = let fields: Vec<InterpResult<'tcx, Self::V>> =

View file

@ -442,7 +442,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.super_rvalue(rvalue, location); self.super_rvalue(rvalue, location);
match *rvalue { match rvalue {
Rvalue::ThreadLocalRef(_) => self.check_op(ops::ThreadLocalAccess), Rvalue::ThreadLocalRef(_) => self.check_op(ops::ThreadLocalAccess),
Rvalue::Use(_) Rvalue::Use(_)
@ -451,18 +451,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
| Rvalue::Discriminant(..) | Rvalue::Discriminant(..)
| Rvalue::Len(_) => {} | Rvalue::Len(_) => {}
Rvalue::Aggregate(ref kind, ..) => { Rvalue::Aggregate(kind, ..) => {
if let AggregateKind::Generator(def_id, ..) = kind.as_ref() { if let AggregateKind::Generator(def_id, ..) = kind.as_ref()
if let Some(generator_kind) = self.tcx.generator_kind(def_id.to_def_id()) { && let Some(generator_kind @ hir::GeneratorKind::Async(..)) = self.tcx.generator_kind(def_id.to_def_id())
if matches!(generator_kind, hir::GeneratorKind::Async(..)) { {
self.check_op(ops::Generator(generator_kind)); self.check_op(ops::Generator(generator_kind));
} }
} }
}
}
Rvalue::Ref(_, kind @ BorrowKind::Mut { .. }, ref place) Rvalue::Ref(_, kind @ (BorrowKind::Mut { .. } | BorrowKind::Unique), place) => {
| Rvalue::Ref(_, kind @ BorrowKind::Unique, ref place) => {
let ty = place.ty(self.body, self.tcx).ty; let ty = place.ty(self.body, self.tcx).ty;
let is_allowed = match ty.kind() { let is_allowed = match ty.kind() {
// Inside a `static mut`, `&mut [...]` is allowed. // Inside a `static mut`, `&mut [...]` is allowed.
@ -491,12 +488,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
} }
} }
Rvalue::AddressOf(Mutability::Mut, ref place) => { Rvalue::AddressOf(Mutability::Mut, place) => {
self.check_mut_borrow(place.local, hir::BorrowKind::Raw) self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
} }
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place) Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, place)
| Rvalue::AddressOf(Mutability::Not, ref place) => { | Rvalue::AddressOf(Mutability::Not, place) => {
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>( let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
&self.ccx, &self.ccx,
&mut |local| self.qualifs.has_mut_interior(self.ccx, local, location), &mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),
@ -564,7 +561,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
Rvalue::ShallowInitBox(_, _) => {} Rvalue::ShallowInitBox(_, _) => {}
Rvalue::UnaryOp(_, ref operand) => { Rvalue::UnaryOp(_, operand) => {
let ty = operand.ty(self.body, self.tcx); let ty = operand.ty(self.body, self.tcx);
if is_int_bool_or_char(ty) { if is_int_bool_or_char(ty) {
// Int, bool, and char operations are fine. // Int, bool, and char operations are fine.
@ -575,8 +572,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
} }
} }
Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) Rvalue::BinaryOp(op, box (lhs, rhs))
| Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => { | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => {
let lhs_ty = lhs.ty(self.body, self.tcx); let lhs_ty = lhs.ty(self.body, self.tcx);
let rhs_ty = rhs.ty(self.body, self.tcx); let rhs_ty = rhs.ty(self.body, self.tcx);
@ -585,13 +582,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() { } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
assert_eq!(lhs_ty, rhs_ty); assert_eq!(lhs_ty, rhs_ty);
assert!( assert!(
op == BinOp::Eq matches!(
|| op == BinOp::Ne op,
|| op == BinOp::Le BinOp::Eq
|| op == BinOp::Lt | BinOp::Ne
|| op == BinOp::Ge | BinOp::Le
|| op == BinOp::Gt | BinOp::Lt
|| op == BinOp::Offset | BinOp::Ge
| BinOp::Gt
| BinOp::Offset
)
); );
self.check_op(ops::RawPtrComparison); self.check_op(ops::RawPtrComparison);

View file

@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
} }
_ => { /* mark as unpromotable below */ } _ => { /* mark as unpromotable below */ }
} }
} else if let TempState::Defined { ref mut uses, .. } = *temp { } else if let TempState::Defined { uses, .. } = temp {
// We always allow borrows, even mutable ones, as we need // We always allow borrows, even mutable ones, as we need
// to promote mutable borrows of some ZSTs e.g., `&mut []`. // to promote mutable borrows of some ZSTs e.g., `&mut []`.
let allowed_use = match context { let allowed_use = match context {
@ -748,7 +748,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
if loc.statement_index < num_stmts { if loc.statement_index < num_stmts {
let (mut rvalue, source_info) = { let (mut rvalue, source_info) = {
let statement = &mut self.source[loc.block].statements[loc.statement_index]; let statement = &mut self.source[loc.block].statements[loc.statement_index];
let StatementKind::Assign(box (_, ref mut rhs)) = statement.kind else { let StatementKind::Assign(box (_, rhs)) = &mut statement.kind else {
span_bug!( span_bug!(
statement.source_info.span, statement.source_info.span,
"{:?} is not an assignment", "{:?} is not an assignment",
@ -778,9 +778,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
self.source[loc.block].terminator().clone() self.source[loc.block].terminator().clone()
} else { } else {
let terminator = self.source[loc.block].terminator_mut(); let terminator = self.source[loc.block].terminator_mut();
let target = match terminator.kind { let target = match &terminator.kind {
TerminatorKind::Call { target: Some(target), .. } => target, TerminatorKind::Call { target: Some(target), .. } => *target,
ref kind => { kind => {
span_bug!(terminator.source_info.span, "{:?} not promotable", kind); span_bug!(terminator.source_info.span, "{:?} not promotable", kind);
} }
}; };
@ -814,7 +814,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
..terminator ..terminator
}; };
} }
ref kind => { kind => {
span_bug!(terminator.source_info.span, "{:?} not promotable", kind); span_bug!(terminator.source_info.span, "{:?} not promotable", kind);
} }
}; };
@ -847,11 +847,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let local_decls = &mut self.source.local_decls; let local_decls = &mut self.source.local_decls;
let loc = candidate.location; let loc = candidate.location;
let statement = &mut blocks[loc.block].statements[loc.statement_index]; let statement = &mut blocks[loc.block].statements[loc.statement_index];
match statement.kind { let StatementKind::Assign(box (_, Rvalue::Ref(region, borrow_kind, place))) = &mut statement.kind else {
StatementKind::Assign(box ( bug!()
_, };
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
)) => {
// Use the underlying local for this (necessarily interior) borrow. // Use the underlying local for this (necessarily interior) borrow.
let ty = local_decls[place.local].ty; let ty = local_decls[place.local].ty;
let span = statement.source_info.span; let span = statement.source_info.span;
@ -886,15 +885,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
Rvalue::Ref( Rvalue::Ref(
tcx.lifetimes.re_erased, tcx.lifetimes.re_erased,
borrow_kind, *borrow_kind,
Place { Place {
local: mem::replace(&mut place.local, promoted_ref), local: mem::replace(&mut place.local, promoted_ref),
projection: List::empty(), projection: List::empty(),
}, },
) )
}
_ => bug!(),
}
}; };
assert_eq!(self.new_block(), START_BLOCK); assert_eq!(self.new_block(), START_BLOCK);

View file

@ -70,8 +70,8 @@ fn test_adjacent_edges<N: PartialEq + Debug, E: PartialEq + Debug>(
"counter={:?} expected={:?} edge_index={:?} edge={:?}", "counter={:?} expected={:?} edge_index={:?} edge={:?}",
counter, expected_incoming[counter], edge_index, edge counter, expected_incoming[counter], edge_index, edge
); );
match expected_incoming[counter] { match &expected_incoming[counter] {
(ref e, ref n) => { (e, n) => {
assert!(e == &edge.data); assert!(e == &edge.data);
assert!(n == graph.node_data(edge.source())); assert!(n == graph.node_data(edge.source()));
assert!(start_index == edge.target); assert!(start_index == edge.target);
@ -88,8 +88,8 @@ fn test_adjacent_edges<N: PartialEq + Debug, E: PartialEq + Debug>(
"counter={:?} expected={:?} edge_index={:?} edge={:?}", "counter={:?} expected={:?} edge_index={:?} edge={:?}",
counter, expected_outgoing[counter], edge_index, edge counter, expected_outgoing[counter], edge_index, edge
); );
match expected_outgoing[counter] { match &expected_outgoing[counter] {
(ref e, ref n) => { (e, n) => {
assert!(e == &edge.data); assert!(e == &edge.data);
assert!(start_index == edge.source); assert!(start_index == edge.source);
assert!(n == graph.node_data(edge.target)); assert!(n == graph.node_data(edge.target));

View file

@ -1,6 +1,5 @@
use crate::stable_hasher::{HashStable, StableHasher, StableOrd}; use crate::stable_hasher::{HashStable, StableHasher, StableOrd};
use std::borrow::Borrow; use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt::Debug; use std::fmt::Debug;
use std::mem; use std::mem;
use std::ops::{Bound, Index, IndexMut, RangeBounds}; use std::ops::{Bound, Index, IndexMut, RangeBounds};
@ -171,7 +170,7 @@ impl<K: Ord, V> SortedMap<K, V> {
where where
F: Fn(&mut K), F: Fn(&mut K),
{ {
self.data.iter_mut().map(|&mut (ref mut k, _)| k).for_each(f); self.data.iter_mut().map(|(k, _)| k).for_each(f);
} }
/// Inserts a presorted range of elements into the map. If the range can be /// Inserts a presorted range of elements into the map. If the range can be
@ -232,10 +231,10 @@ impl<K: Ord, V> SortedMap<K, V> {
R: RangeBounds<K>, R: RangeBounds<K>,
{ {
let start = match range.start_bound() { let start = match range.start_bound() {
Bound::Included(ref k) => match self.lookup_index_for(k) { Bound::Included(k) => match self.lookup_index_for(k) {
Ok(index) | Err(index) => index, Ok(index) | Err(index) => index,
}, },
Bound::Excluded(ref k) => match self.lookup_index_for(k) { Bound::Excluded(k) => match self.lookup_index_for(k) {
Ok(index) => index + 1, Ok(index) => index + 1,
Err(index) => index, Err(index) => index,
}, },
@ -243,11 +242,11 @@ impl<K: Ord, V> SortedMap<K, V> {
}; };
let end = match range.end_bound() { let end = match range.end_bound() {
Bound::Included(ref k) => match self.lookup_index_for(k) { Bound::Included(k) => match self.lookup_index_for(k) {
Ok(index) => index + 1, Ok(index) => index + 1,
Err(index) => index, Err(index) => index,
}, },
Bound::Excluded(ref k) => match self.lookup_index_for(k) { Bound::Excluded(k) => match self.lookup_index_for(k) {
Ok(index) | Err(index) => index, Ok(index) | Err(index) => index,
}, },
Bound::Unbounded => self.data.len(), Bound::Unbounded => self.data.len(),
@ -302,7 +301,7 @@ impl<K: Ord, V> FromIterator<(K, V)> for SortedMap<K, V> {
let mut data: Vec<(K, V)> = iter.into_iter().collect(); let mut data: Vec<(K, V)> = iter.into_iter().collect();
data.sort_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2)); data.sort_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2));
data.dedup_by(|&mut (ref k1, _), &mut (ref k2, _)| k1.cmp(k2) == Ordering::Equal); data.dedup_by(|(k1, _), (k2, _)| k1 == k2);
SortedMap { data } SortedMap { data }
} }

View file

@ -63,13 +63,13 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
/// Returns an iterator over the items in the map in insertion order. /// Returns an iterator over the items in the map in insertion order.
#[inline] #[inline]
pub fn iter(&self) -> impl '_ + DoubleEndedIterator<Item = (&K, &V)> { pub fn iter(&self) -> impl '_ + DoubleEndedIterator<Item = (&K, &V)> {
self.items.iter().map(|(ref k, ref v)| (k, v)) self.items.iter().map(|(k, v)| (k, v))
} }
/// Returns an iterator over the items in the map in insertion order along with their indices. /// Returns an iterator over the items in the map in insertion order along with their indices.
#[inline] #[inline]
pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator<Item = (I, (&K, &V))> { pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator<Item = (I, (&K, &V))> {
self.items.iter_enumerated().map(|(i, (ref k, ref v))| (i, (k, v))) self.items.iter_enumerated().map(|(i, (k, v))| (i, (k, v)))
} }
/// Returns the item in the map with the given index. /// Returns the item in the map with the given index.

View file

@ -6,7 +6,7 @@ fn test_sorted_index_multi_map() {
let set: SortedIndexMultiMap<usize, _, _> = entries.iter().copied().collect(); let set: SortedIndexMultiMap<usize, _, _> = entries.iter().copied().collect();
// Insertion order is preserved. // Insertion order is preserved.
assert!(entries.iter().map(|(ref k, ref v)| (k, v)).eq(set.iter())); assert!(entries.iter().map(|(k, v)| (k, v)).eq(set.iter()));
// Indexing // Indexing
for (i, expect) in entries.iter().enumerate() { for (i, expect) in entries.iter().enumerate() {

View file

@ -37,9 +37,9 @@ impl<T: PartialEq> TinyList<T> {
#[inline] #[inline]
pub fn remove(&mut self, data: &T) -> bool { pub fn remove(&mut self, data: &T) -> bool {
self.head = match self.head { self.head = match &mut self.head {
Some(ref mut head) if head.data == *data => head.next.take().map(|x| *x), Some(head) if head.data == *data => head.next.take().map(|x| *x),
Some(ref mut head) => return head.remove_next(data), Some(head) => return head.remove_next(data),
None => return false, None => return false,
}; };
true true
@ -48,7 +48,7 @@ impl<T: PartialEq> TinyList<T> {
#[inline] #[inline]
pub fn contains(&self, data: &T) -> bool { pub fn contains(&self, data: &T) -> bool {
let mut elem = self.head.as_ref(); let mut elem = self.head.as_ref();
while let Some(ref e) = elem { while let Some(e) = elem {
if &e.data == data { if &e.data == data {
return true; return true;
} }
@ -65,15 +65,14 @@ struct Element<T> {
} }
impl<T: PartialEq> Element<T> { impl<T: PartialEq> Element<T> {
fn remove_next(&mut self, data: &T) -> bool { fn remove_next(mut self: &mut Self, data: &T) -> bool {
let mut n = self;
loop { loop {
match n.next { match self.next {
Some(ref mut next) if next.data == *data => { Some(ref mut next) if next.data == *data => {
n.next = next.next.take(); self.next = next.next.take();
return true; return true;
} }
Some(ref mut next) => n = next, Some(ref mut next) => self = next,
None => return false, None => return false,
} }
} }

View file

@ -6,7 +6,7 @@ use test::{black_box, Bencher};
impl<T> TinyList<T> { impl<T> TinyList<T> {
fn len(&self) -> usize { fn len(&self) -> usize {
let (mut elem, mut count) = (self.head.as_ref(), 0); let (mut elem, mut count) = (self.head.as_ref(), 0);
while let Some(ref e) = elem { while let Some(e) = elem {
count += 1; count += 1;
elem = e.next.as_deref(); elem = e.next.as_deref();
} }

View file

@ -63,21 +63,21 @@ pub enum Annotatable {
impl Annotatable { impl Annotatable {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match self {
Annotatable::Item(ref item) => item.span, Annotatable::Item(item) => item.span,
Annotatable::TraitItem(ref trait_item) => trait_item.span, Annotatable::TraitItem(trait_item) => trait_item.span,
Annotatable::ImplItem(ref impl_item) => impl_item.span, Annotatable::ImplItem(impl_item) => impl_item.span,
Annotatable::ForeignItem(ref foreign_item) => foreign_item.span, Annotatable::ForeignItem(foreign_item) => foreign_item.span,
Annotatable::Stmt(ref stmt) => stmt.span, Annotatable::Stmt(stmt) => stmt.span,
Annotatable::Expr(ref expr) => expr.span, Annotatable::Expr(expr) => expr.span,
Annotatable::Arm(ref arm) => arm.span, Annotatable::Arm(arm) => arm.span,
Annotatable::ExprField(ref field) => field.span, Annotatable::ExprField(field) => field.span,
Annotatable::PatField(ref fp) => fp.pat.span, Annotatable::PatField(fp) => fp.pat.span,
Annotatable::GenericParam(ref gp) => gp.ident.span, Annotatable::GenericParam(gp) => gp.ident.span,
Annotatable::Param(ref p) => p.span, Annotatable::Param(p) => p.span,
Annotatable::FieldDef(ref sf) => sf.span, Annotatable::FieldDef(sf) => sf.span,
Annotatable::Variant(ref v) => v.span, Annotatable::Variant(v) => v.span,
Annotatable::Crate(ref c) => c.spans.inner_span, Annotatable::Crate(c) => c.spans.inner_span,
} }
} }

View file

@ -298,7 +298,7 @@ impl<'a> StripUnconfigured<'a> {
Some(AttrTokenTree::Delimited(sp, delim, inner)) Some(AttrTokenTree::Delimited(sp, delim, inner))
.into_iter() .into_iter()
} }
AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(ref nt) = token.kind => { AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(nt) = &token.kind => {
panic!( panic!(
"Nonterminal should have been flattened at {:?}: {:?}", "Nonterminal should have been flattened at {:?}: {:?}",
token.span, nt token.span, nt

View file

@ -144,12 +144,12 @@ macro_rules! ast_fragments {
} }
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
match *self { match self {
AstFragment::OptExpr(Some(ref expr)) => visitor.visit_expr(expr), AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr),
AstFragment::OptExpr(None) => {} AstFragment::OptExpr(None) => {}
AstFragment::MethodReceiverExpr(ref expr) => visitor.visit_method_receiver_expr(expr), AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)* $($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] { $($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] {
visitor.$visit_ast_elt(ast_elt, $($args)*); visitor.$visit_ast_elt(ast_elt, $($args)*);
})?)* })?)*
} }
@ -592,7 +592,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let expn_id = invoc.expansion_data.id; let expn_id = invoc.expansion_data.id;
let parent_def = self.cx.resolver.invocation_parent(expn_id); let parent_def = self.cx.resolver.invocation_parent(expn_id);
let span = match &mut invoc.kind { let span = match &mut invoc.kind {
InvocationKind::Bang { ref mut span, .. } => span, InvocationKind::Bang { span, .. } => span,
InvocationKind::Attr { attr, .. } => &mut attr.span, InvocationKind::Attr { attr, .. } => &mut attr.span,
InvocationKind::Derive { path, .. } => &mut path.span, InvocationKind::Derive { path, .. } => &mut path.span,
}; };
@ -945,8 +945,8 @@ pub fn ensure_complete_parse<'a>(
let def_site_span = parser.token.span.with_ctxt(SyntaxContext::root()); let def_site_span = parser.token.span.with_ctxt(SyntaxContext::root());
let semi_span = parser.sess.source_map().next_point(span); let semi_span = parser.sess.source_map().next_point(span);
let add_semicolon = match parser.sess.source_map().span_to_snippet(semi_span) { let add_semicolon = match &parser.sess.source_map().span_to_snippet(semi_span) {
Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => { Ok(snippet) if &snippet[..] != ";" && kind_name == "expression" => {
Some(span.shrink_to_hi()) Some(span.shrink_to_hi())
} }
_ => None, _ => None,

View file

@ -151,9 +151,9 @@ impl<'a, T> Iterator for &'a Stack<'a, T> {
// Iterates from top to bottom of the stack. // Iterates from top to bottom of the stack.
fn next(&mut self) -> Option<&'a T> { fn next(&mut self) -> Option<&'a T> {
match *self { match self {
Stack::Empty => None, Stack::Empty => None,
Stack::Push { ref top, ref prev } => { Stack::Push { top, prev } => {
*self = prev; *self = prev;
Some(top) Some(top)
} }
@ -437,8 +437,8 @@ fn check_nested_occurrences(
// We check that the meta-variable is correctly used. // We check that the meta-variable is correctly used.
check_occurrences(sess, node_id, tt, macros, binders, ops, valid); check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
} }
(NestedMacroState::MacroRulesNotName, &TokenTree::Delimited(_, ref del)) (NestedMacroState::MacroRulesNotName, TokenTree::Delimited(_, del))
| (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) | (NestedMacroState::MacroName, TokenTree::Delimited(_, del))
if del.delim == Delimiter::Brace => if del.delim == Delimiter::Brace =>
{ {
let macro_rules = state == NestedMacroState::MacroRulesNotName; let macro_rules = state == NestedMacroState::MacroRulesNotName;
@ -497,7 +497,7 @@ fn check_nested_occurrences(
valid, valid,
); );
} }
(_, ref tt) => { (_, tt) => {
state = NestedMacroState::Empty; state = NestedMacroState::Empty;
check_occurrences(sess, node_id, tt, macros, binders, ops, valid); check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
} }

View file

@ -486,11 +486,11 @@ pub fn compile_declarative_macro(
let mut valid = true; let mut valid = true;
// Extract the arguments: // Extract the arguments:
let lhses = match argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] { let lhses = match &argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] {
MatchedSeq(ref s) => s MatchedSeq(s) => s
.iter() .iter()
.map(|m| { .map(|m| {
if let MatchedTokenTree(ref tt) = *m { if let MatchedTokenTree(tt) = m {
let tt = mbe::quoted::parse( let tt = mbe::quoted::parse(
TokenStream::new(vec![tt.clone()]), TokenStream::new(vec![tt.clone()]),
true, true,
@ -510,11 +510,11 @@ pub fn compile_declarative_macro(
_ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
}; };
let rhses = match argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] { let rhses = match &argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] {
MatchedSeq(ref s) => s MatchedSeq(s) => s
.iter() .iter()
.map(|m| { .map(|m| {
if let MatchedTokenTree(ref tt) = *m { if let MatchedTokenTree(tt) = m {
return mbe::quoted::parse( return mbe::quoted::parse(
TokenStream::new(vec![tt.clone()]), TokenStream::new(vec![tt.clone()]),
false, false,
@ -624,21 +624,21 @@ fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree)
fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
use mbe::TokenTree; use mbe::TokenTree;
for tt in tts { for tt in tts {
match *tt { match tt {
TokenTree::Token(..) TokenTree::Token(..)
| TokenTree::MetaVar(..) | TokenTree::MetaVar(..)
| TokenTree::MetaVarDecl(..) | TokenTree::MetaVarDecl(..)
| TokenTree::MetaVarExpr(..) => (), | TokenTree::MetaVarExpr(..) => (),
TokenTree::Delimited(_, ref del) => { TokenTree::Delimited(_, del) => {
if !check_lhs_no_empty_seq(sess, &del.tts) { if !check_lhs_no_empty_seq(sess, &del.tts) {
return false; return false;
} }
} }
TokenTree::Sequence(span, ref seq) => { TokenTree::Sequence(span, seq) => {
if seq.separator.is_none() if seq.separator.is_none()
&& seq.tts.iter().all(|seq_tt| match *seq_tt { && seq.tts.iter().all(|seq_tt| match seq_tt {
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
TokenTree::Sequence(_, ref sub_seq) => { TokenTree::Sequence(_, sub_seq) => {
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
} }
@ -736,21 +736,21 @@ impl<'tt> FirstSets<'tt> {
fn build_recur<'tt>(sets: &mut FirstSets<'tt>, tts: &'tt [TokenTree]) -> TokenSet<'tt> { fn build_recur<'tt>(sets: &mut FirstSets<'tt>, tts: &'tt [TokenTree]) -> TokenSet<'tt> {
let mut first = TokenSet::empty(); let mut first = TokenSet::empty();
for tt in tts.iter().rev() { for tt in tts.iter().rev() {
match *tt { match tt {
TokenTree::Token(..) TokenTree::Token(..)
| TokenTree::MetaVar(..) | TokenTree::MetaVar(..)
| TokenTree::MetaVarDecl(..) | TokenTree::MetaVarDecl(..)
| TokenTree::MetaVarExpr(..) => { | TokenTree::MetaVarExpr(..) => {
first.replace_with(TtHandle::TtRef(tt)); first.replace_with(TtHandle::TtRef(tt));
} }
TokenTree::Delimited(span, ref delimited) => { TokenTree::Delimited(span, delimited) => {
build_recur(sets, &delimited.tts); build_recur(sets, &delimited.tts);
first.replace_with(TtHandle::from_token_kind( first.replace_with(TtHandle::from_token_kind(
token::OpenDelim(delimited.delim), token::OpenDelim(delimited.delim),
span.open, span.open,
)); ));
} }
TokenTree::Sequence(sp, ref seq_rep) => { TokenTree::Sequence(sp, seq_rep) => {
let subfirst = build_recur(sets, &seq_rep.tts); let subfirst = build_recur(sets, &seq_rep.tts);
match sets.first.entry(sp.entire()) { match sets.first.entry(sp.entire()) {
@ -804,7 +804,7 @@ impl<'tt> FirstSets<'tt> {
let mut first = TokenSet::empty(); let mut first = TokenSet::empty();
for tt in tts.iter() { for tt in tts.iter() {
assert!(first.maybe_empty); assert!(first.maybe_empty);
match *tt { match tt {
TokenTree::Token(..) TokenTree::Token(..)
| TokenTree::MetaVar(..) | TokenTree::MetaVar(..)
| TokenTree::MetaVarDecl(..) | TokenTree::MetaVarDecl(..)
@ -812,14 +812,14 @@ impl<'tt> FirstSets<'tt> {
first.add_one(TtHandle::TtRef(tt)); first.add_one(TtHandle::TtRef(tt));
return first; return first;
} }
TokenTree::Delimited(span, ref delimited) => { TokenTree::Delimited(span, delimited) => {
first.add_one(TtHandle::from_token_kind( first.add_one(TtHandle::from_token_kind(
token::OpenDelim(delimited.delim), token::OpenDelim(delimited.delim),
span.open, span.open,
)); ));
return first; return first;
} }
TokenTree::Sequence(sp, ref seq_rep) => { TokenTree::Sequence(sp, seq_rep) => {
let subfirst_owned; let subfirst_owned;
let subfirst = match self.first.get(&sp.entire()) { let subfirst = match self.first.get(&sp.entire()) {
Some(Some(subfirst)) => subfirst, Some(Some(subfirst)) => subfirst,
@ -1041,7 +1041,7 @@ fn check_matcher_core<'tt>(
// First, update `last` so that it corresponds to the set // First, update `last` so that it corresponds to the set
// of NT tokens that might end the sequence `... token`. // of NT tokens that might end the sequence `... token`.
match *token { match token {
TokenTree::Token(..) TokenTree::Token(..)
| TokenTree::MetaVar(..) | TokenTree::MetaVar(..)
| TokenTree::MetaVarDecl(..) | TokenTree::MetaVarDecl(..)
@ -1057,7 +1057,7 @@ fn check_matcher_core<'tt>(
suffix_first = build_suffix_first(); suffix_first = build_suffix_first();
} }
} }
TokenTree::Delimited(span, ref d) => { TokenTree::Delimited(span, d) => {
let my_suffix = TokenSet::singleton(TtHandle::from_token_kind( let my_suffix = TokenSet::singleton(TtHandle::from_token_kind(
token::CloseDelim(d.delim), token::CloseDelim(d.delim),
span.close, span.close,
@ -1070,7 +1070,7 @@ fn check_matcher_core<'tt>(
// against SUFFIX // against SUFFIX
continue 'each_token; continue 'each_token;
} }
TokenTree::Sequence(_, ref seq_rep) => { TokenTree::Sequence(_, seq_rep) => {
suffix_first = build_suffix_first(); suffix_first = build_suffix_first();
// The trick here: when we check the interior, we want // The trick here: when we check the interior, we want
// to include the separator (if any) as a potential // to include the separator (if any) as a potential
@ -1372,8 +1372,8 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
} }
fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
match *tt { match tt {
mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token).into(), mbe::TokenTree::Token(token) => pprust::token_to_string(&token).into(),
mbe::TokenTree::MetaVar(_, name) => format!("${}", name), mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),

View file

@ -47,8 +47,7 @@ impl<'a> Iterator for Frame<'a> {
fn next(&mut self) -> Option<&'a mbe::TokenTree> { fn next(&mut self) -> Option<&'a mbe::TokenTree> {
match self { match self {
Frame::Delimited { tts, ref mut idx, .. } Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => {
| Frame::Sequence { tts, ref mut idx, .. } => {
let res = tts.get(*idx); let res = tts.get(*idx);
*idx += 1; *idx += 1;
res res
@ -220,13 +219,13 @@ pub(super) fn transcribe<'a>(
let ident = MacroRulesNormalizedIdent::new(original_ident); let ident = MacroRulesNormalizedIdent::new(original_ident);
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
match cur_matched { match cur_matched {
MatchedTokenTree(ref tt) => { MatchedTokenTree(tt) => {
// `tt`s are emitted into the output stream directly as "raw tokens", // `tt`s are emitted into the output stream directly as "raw tokens",
// without wrapping them into groups. // without wrapping them into groups.
let token = tt.clone(); let token = tt.clone();
result.push(token); result.push(token);
} }
MatchedNonterminal(ref nt) => { MatchedNonterminal(nt) => {
// Other variables are emitted into the output stream as groups with // Other variables are emitted into the output stream as groups with
// `Delimiter::Invisible` to maintain parsing priorities. // `Delimiter::Invisible` to maintain parsing priorities.
// `Interpolated` is currently used for such groups in rustc parser. // `Interpolated` is currently used for such groups in rustc parser.
@ -299,12 +298,11 @@ fn lookup_cur_matched<'a>(
interpolations: &'a FxHashMap<MacroRulesNormalizedIdent, NamedMatch>, interpolations: &'a FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
repeats: &[(usize, usize)], repeats: &[(usize, usize)],
) -> Option<&'a NamedMatch> { ) -> Option<&'a NamedMatch> {
interpolations.get(&ident).map(|matched| { interpolations.get(&ident).map(|mut matched| {
let mut matched = matched;
for &(idx, _) in repeats { for &(idx, _) in repeats {
match matched { match matched {
MatchedTokenTree(_) | MatchedNonterminal(_) => break, MatchedTokenTree(_) | MatchedNonterminal(_) => break,
MatchedSeq(ref ads) => matched = ads.get(idx).unwrap(), MatchedSeq(ads) => matched = ads.get(idx).unwrap(),
} }
} }
@ -339,7 +337,7 @@ impl LockstepIterSize {
match self { match self {
LockstepIterSize::Unconstrained => other, LockstepIterSize::Unconstrained => other,
LockstepIterSize::Contradiction(_) => self, LockstepIterSize::Contradiction(_) => self,
LockstepIterSize::Constraint(l_len, ref l_id) => match other { LockstepIterSize::Constraint(l_len, l_id) => match other {
LockstepIterSize::Unconstrained => self, LockstepIterSize::Unconstrained => self,
LockstepIterSize::Contradiction(_) => other, LockstepIterSize::Contradiction(_) => other,
LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self, LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self,
@ -378,33 +376,33 @@ fn lockstep_iter_size(
repeats: &[(usize, usize)], repeats: &[(usize, usize)],
) -> LockstepIterSize { ) -> LockstepIterSize {
use mbe::TokenTree; use mbe::TokenTree;
match *tree { match tree {
TokenTree::Delimited(_, ref delimited) => { TokenTree::Delimited(_, delimited) => {
delimited.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| { delimited.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| {
size.with(lockstep_iter_size(tt, interpolations, repeats)) size.with(lockstep_iter_size(tt, interpolations, repeats))
}) })
} }
TokenTree::Sequence(_, ref seq) => { TokenTree::Sequence(_, seq) => {
seq.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| { seq.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| {
size.with(lockstep_iter_size(tt, interpolations, repeats)) size.with(lockstep_iter_size(tt, interpolations, repeats))
}) })
} }
TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => { TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => {
let name = MacroRulesNormalizedIdent::new(name); let name = MacroRulesNormalizedIdent::new(*name);
match lookup_cur_matched(name, interpolations, repeats) { match lookup_cur_matched(name, interpolations, repeats) {
Some(matched) => match matched { Some(matched) => match matched {
MatchedTokenTree(_) | MatchedNonterminal(_) => LockstepIterSize::Unconstrained, MatchedTokenTree(_) | MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
MatchedSeq(ref ads) => LockstepIterSize::Constraint(ads.len(), name), MatchedSeq(ads) => LockstepIterSize::Constraint(ads.len(), name),
}, },
_ => LockstepIterSize::Unconstrained, _ => LockstepIterSize::Unconstrained,
} }
} }
TokenTree::MetaVarExpr(_, ref expr) => { TokenTree::MetaVarExpr(_, expr) => {
let default_rslt = LockstepIterSize::Unconstrained; let default_rslt = LockstepIterSize::Unconstrained;
let Some(ident) = expr.ident() else { return default_rslt; }; let Some(ident) = expr.ident() else { return default_rslt; };
let name = MacroRulesNormalizedIdent::new(ident); let name = MacroRulesNormalizedIdent::new(ident);
match lookup_cur_matched(name, interpolations, repeats) { match lookup_cur_matched(name, interpolations, repeats) {
Some(MatchedSeq(ref ads)) => { Some(MatchedSeq(ads)) => {
default_rslt.with(LockstepIterSize::Constraint(ads.len(), name)) default_rslt.with(LockstepIterSize::Constraint(ads.len(), name))
} }
_ => default_rslt, _ => default_rslt,
@ -449,7 +447,7 @@ fn count_repetitions<'a>(
Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")), Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
} }
} }
MatchedSeq(ref named_matches) => { MatchedSeq(named_matches) => {
let new_declared_lhs_depth = declared_lhs_depth + 1; let new_declared_lhs_depth = declared_lhs_depth + 1;
match depth_opt { match depth_opt {
None => named_matches None => named_matches
@ -472,7 +470,7 @@ fn count_repetitions<'a>(
// before we start counting. `matched` contains the various levels of the // before we start counting. `matched` contains the various levels of the
// tree as we descend, and its final value is the subtree we are currently at. // tree as we descend, and its final value is the subtree we are currently at.
for &(idx, _) in repeats { for &(idx, _) in repeats {
if let MatchedSeq(ref ads) = matched { if let MatchedSeq(ads) = matched {
matched = &ads[idx]; matched = &ads[idx];
} }
} }

View file

@ -176,9 +176,9 @@ fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
} }
impl<'a> visit::Visitor<'a> for PatIdentVisitor { impl<'a> visit::Visitor<'a> for PatIdentVisitor {
fn visit_pat(&mut self, p: &'a ast::Pat) { fn visit_pat(&mut self, p: &'a ast::Pat) {
match p.kind { match &p.kind {
PatKind::Ident(_, ref ident, _) => { PatKind::Ident(_, ident, _) => {
self.spans.push(ident.span.clone()); self.spans.push(ident.span);
} }
_ => { _ => {
visit::walk_pat(self, p); visit::walk_pat(self, p);
@ -290,10 +290,8 @@ fn ttdelim_span() {
) )
.unwrap(); .unwrap();
let tts: Vec<_> = match expr.kind { let ast::ExprKind::MacCall(mac) = &expr.kind else { panic!("not a macro") };
ast::ExprKind::MacCall(ref mac) => mac.args.tokens.clone().into_trees().collect(), let tts: Vec<_> = mac.args.tokens.clone().into_trees().collect();
_ => panic!("not a macro"),
};
let span = tts.iter().rev().next().unwrap().span(); let span = tts.iter().rev().next().unwrap().span();
@ -318,11 +316,8 @@ fn out_of_line_mod() {
.unwrap() .unwrap()
.unwrap(); .unwrap();
if let ast::ItemKind::Mod(_, ref mod_kind) = item.kind { let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() };
assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2)); assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2));
} else {
panic!();
}
}); });
} }

View file

@ -597,8 +597,8 @@ impl server::SourceFile for Rustc<'_, '_> {
} }
fn path(&mut self, file: &Self::SourceFile) -> String { fn path(&mut self, file: &Self::SourceFile) -> String {
match file.name { match &file.name {
FileName::Real(ref name) => name FileName::Real(name) => name
.local_path() .local_path()
.expect("attempting to get a file path in an imported file in `proc_macro::SourceFile::path`") .expect("attempting to get a file path in an imported file in `proc_macro::SourceFile::path`")
.to_str() .to_str()

View file

@ -569,17 +569,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.bindings .bindings
.iter() .iter()
.map(|binding| { .map(|binding| {
let kind = match binding.kind { let kind = match &binding.kind {
hir::TypeBindingKind::Equality { ref term } => match term { hir::TypeBindingKind::Equality { term } => match term {
hir::Term::Ty(ref ty) => { hir::Term::Ty(ty) => {
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty).into()) ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty).into())
} }
hir::Term::Const(ref c) => { hir::Term::Const(c) => {
let c = Const::from_anon_const(self.tcx(), c.def_id); let c = Const::from_anon_const(self.tcx(), c.def_id);
ConvertedBindingKind::Equality(c.into()) ConvertedBindingKind::Equality(c.into())
} }
}, },
hir::TypeBindingKind::Constraint { ref bounds } => { hir::TypeBindingKind::Constraint { bounds } => {
ConvertedBindingKind::Constraint(bounds) ConvertedBindingKind::Constraint(bounds)
} }
}; };
@ -1928,7 +1928,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> { ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
let tcx = self.tcx(); let tcx = self.tcx();
let assoc_ident = assoc_segment.ident; let assoc_ident = assoc_segment.ident;
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind { let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
path.res path.res
} else { } else {
Res::Err Res::Err
@ -1971,8 +1971,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return; return;
}; };
let (qself_sugg_span, is_self) = if let hir::TyKind::Path( let (qself_sugg_span, is_self) = if let hir::TyKind::Path(
hir::QPath::Resolved(_, ref path) hir::QPath::Resolved(_, path)
) = qself.kind { ) = &qself.kind {
// If the path segment already has type params, we want to overwrite // If the path segment already has type params, we want to overwrite
// them. // them.
match &path.segments[..] { match &path.segments[..] {
@ -2760,7 +2760,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
"generic `Self` types are currently not permitted in anonymous constants", "generic `Self` types are currently not permitted in anonymous constants",
); );
if let Some(hir::Node::Item(&hir::Item { if let Some(hir::Node::Item(&hir::Item {
kind: hir::ItemKind::Impl(ref impl_), kind: hir::ItemKind::Impl(impl_),
.. ..
})) = tcx.hir().get_if_local(def_id) })) = tcx.hir().get_if_local(def_id)
{ {
@ -2843,12 +2843,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> { fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
let result_ty = match ast_ty.kind { let result_ty = match &ast_ty.kind {
hir::TyKind::Slice(ref ty) => tcx.mk_slice(self.ast_ty_to_ty(ty)), hir::TyKind::Slice(ty) => tcx.mk_slice(self.ast_ty_to_ty(ty)),
hir::TyKind::Ptr(ref mt) => { hir::TyKind::Ptr(mt) => {
tcx.mk_ptr(ty::TypeAndMut { ty: self.ast_ty_to_ty(mt.ty), mutbl: mt.mutbl }) tcx.mk_ptr(ty::TypeAndMut { ty: self.ast_ty_to_ty(mt.ty), mutbl: mt.mutbl })
} }
hir::TyKind::Ref(ref region, ref mt) => { hir::TyKind::Ref(region, mt) => {
let r = self.ast_region_to_region(region, None); let r = self.ast_region_to_region(region, None);
debug!(?r); debug!(?r);
let t = self.ast_ty_to_ty_inner(mt.ty, true, false); let t = self.ast_ty_to_ty_inner(mt.ty, true, false);
@ -2868,7 +2868,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Some(ast_ty), Some(ast_ty),
)) ))
} }
hir::TyKind::TraitObject(bounds, ref lifetime, repr) => { hir::TyKind::TraitObject(bounds, lifetime, repr) => {
self.maybe_lint_bare_trait(ast_ty, in_path); self.maybe_lint_bare_trait(ast_ty, in_path);
let repr = match repr { let repr = match repr {
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn, TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
@ -2876,12 +2876,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}; };
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr) self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
} }
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => { hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
debug!(?maybe_qself, ?path); debug!(?maybe_qself, ?path);
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself)); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
self.res_to_ty(opt_self_ty, path, false) self.res_to_ty(opt_self_ty, path, false)
} }
hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => { &hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
let opaque_ty = tcx.hir().item(item_id); let opaque_ty = tcx.hir().item(item_id);
let def_id = item_id.owner_id.to_def_id(); let def_id = item_id.owner_id.to_def_id();
@ -2892,14 +2892,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
} }
} }
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
debug!(?qself, ?segment); debug!(?qself, ?segment);
let ty = self.ast_ty_to_ty_inner(qself, false, true); let ty = self.ast_ty_to_ty_inner(qself, false, true);
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false) self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false)
.map(|(ty, _, _)| ty) .map(|(ty, _, _)| ty)
.unwrap_or_else(|_| tcx.ty_error()) .unwrap_or_else(|_| tcx.ty_error())
} }
hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => { &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
let def_id = tcx.require_lang_item(lang_item, Some(span)); let def_id = tcx.require_lang_item(lang_item, Some(span));
let (substs, _) = self.create_substs_for_ast_path( let (substs, _) = self.create_substs_for_ast_path(
span, span,
@ -2913,7 +2913,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
); );
EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs) EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs)
} }
hir::TyKind::Array(ref ty, ref length) => { hir::TyKind::Array(ty, length) => {
let length = match length { let length = match length {
&hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span), &hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
hir::ArrayLen::Body(constant) => { hir::ArrayLen::Body(constant) => {
@ -2923,7 +2923,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length)) tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length))
} }
hir::TyKind::Typeof(ref e) => { hir::TyKind::Typeof(e) => {
let ty_erased = tcx.type_of(e.def_id); let ty_erased = tcx.type_of(e.def_id);
let ty = tcx.fold_regions(ty_erased, |r, _| { let ty = tcx.fold_regions(ty_erased, |r, _| {
if r.is_erased() { tcx.lifetimes.re_static } else { r } if r.is_erased() { tcx.lifetimes.re_static } else { r }

View file

@ -531,9 +531,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
DefKind::Fn => {} // entirely within check_item_body DefKind::Fn => {} // entirely within check_item_body
DefKind::Impl => { DefKind::Impl => {
let it = tcx.hir().item(id); let it = tcx.hir().item(id);
let hir::ItemKind::Impl(ref impl_) = it.kind else { let hir::ItemKind::Impl(impl_) = it.kind else { return };
return;
};
debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id);
if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) {
check_impl_items_against_trait( check_impl_items_against_trait(
@ -548,15 +546,15 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
} }
DefKind::Trait => { DefKind::Trait => {
let it = tcx.hir().item(id); let it = tcx.hir().item(id);
let hir::ItemKind::Trait(_, _, _, _, ref items) = it.kind else { let hir::ItemKind::Trait(_, _, _, _, items) = it.kind else {
return; return;
}; };
check_on_unimplemented(tcx, it); check_on_unimplemented(tcx, it);
for item in items.iter() { for item in items.iter() {
let item = tcx.hir().trait_item(item.id); let item = tcx.hir().trait_item(item.id);
match item.kind { match &item.kind {
hir::TraitItemKind::Fn(ref sig, _) => { hir::TraitItemKind::Fn(sig, _) => {
let abi = sig.header.abi; let abi = sig.header.abi;
fn_maybe_err(tcx, item.ident.span, abi); fn_maybe_err(tcx, item.ident.span, abi);
} }
@ -652,8 +650,8 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
} }
let item = tcx.hir().foreign_item(item.id); let item = tcx.hir().foreign_item(item.id);
match item.kind { match &item.kind {
hir::ForeignItemKind::Fn(ref fn_decl, _, _) => { hir::ForeignItemKind::Fn(fn_decl, _, _) => {
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span); require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
} }
hir::ForeignItemKind::Static(..) => { hir::ForeignItemKind::Static(..) => {

View file

@ -47,42 +47,22 @@ pub(super) fn compare_impl_method<'tcx>(
let impl_m_span = tcx.def_span(impl_m.def_id); let impl_m_span = tcx.def_span(impl_m.def_id);
if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) { let _: Result<_, ErrorGuaranteed> = try {
return; compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)?;
} compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false)?;
compare_generic_param_kinds(tcx, impl_m, trait_m, false)?;
if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false) { compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?;
return; compare_synthetic_generics(tcx, impl_m, trait_m)?;
} compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?;
compare_method_predicate_entailment(
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m, false) {
return;
}
if let Err(_) =
compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)
{
return;
}
if let Err(_) = compare_synthetic_generics(tcx, impl_m, trait_m) {
return;
}
if let Err(_) = compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
return;
}
if let Err(_) = compare_method_predicate_entailment(
tcx, tcx,
impl_m, impl_m,
impl_m_span, impl_m_span,
trait_m, trait_m,
impl_trait_ref, impl_trait_ref,
CheckImpliedWfMode::Check, CheckImpliedWfMode::Check,
) { )?;
return; };
}
} }
/// This function is best explained by example. Consider a trait: /// This function is best explained by example. Consider a trait:
@ -936,16 +916,14 @@ fn report_trait_method_mismatch<'tcx>(
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
// span points only at the type `Box<Self`>, but we want to cover the whole // span points only at the type `Box<Self`>, but we want to cover the whole
// argument pattern and type. // argument pattern and type.
let span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind { let ImplItemKind::Fn(ref sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{impl_m:?} is not a method") };
ImplItemKind::Fn(ref sig, body) => tcx let span = tcx
.hir() .hir()
.body_param_names(body) .body_param_names(body)
.zip(sig.decl.inputs.iter()) .zip(sig.decl.inputs.iter())
.map(|(param, ty)| param.span.to(ty.span)) .map(|(param, ty)| param.span.to(ty.span))
.next() .next()
.unwrap_or(impl_err_span), .unwrap_or(impl_err_span);
_ => bug!("{:?} is not a method", impl_m),
};
diag.span_suggestion( diag.span_suggestion(
span, span,
@ -958,8 +936,9 @@ fn report_trait_method_mismatch<'tcx>(
if trait_sig.inputs().len() == *i { if trait_sig.inputs().len() == *i {
// Suggestion to change output type. We do not suggest in `async` functions // Suggestion to change output type. We do not suggest in `async` functions
// to avoid complex logic or incorrect output. // to avoid complex logic or incorrect output.
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind { if let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => { && !sig.header.asyncness.is_async()
{
let msg = "change the output type to match the trait"; let msg = "change the output type to match the trait";
let ap = Applicability::MachineApplicable; let ap = Applicability::MachineApplicable;
match sig.decl.output { match sig.decl.output {
@ -972,8 +951,6 @@ fn report_trait_method_mismatch<'tcx>(
diag.span_suggestion(hir_ty.span, msg, sugg, ap); diag.span_suggestion(hir_ty.span, msg, sugg, ap);
} }
}; };
}
_ => {}
}; };
} else if let Some(trait_ty) = trait_sig.inputs().get(*i) { } else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
diag.span_suggestion( diag.span_suggestion(
@ -1100,25 +1077,18 @@ fn extract_spans_for_error_reporting<'tcx>(
trait_m: &ty::AssocItem, trait_m: &ty::AssocItem,
) -> (Span, Option<Span>) { ) -> (Span, Option<Span>) {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let mut impl_args = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind { let mut impl_args = {
ImplItemKind::Fn(ref sig, _) => { let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{:?} is not a method", impl_m) };
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
}
_ => bug!("{:?} is not a method", impl_m),
}; };
let trait_args =
trait_m.def_id.as_local().map(|def_id| match tcx.hir().expect_trait_item(def_id).kind { let trait_args = trait_m.def_id.as_local().map(|def_id| {
TraitItemKind::Fn(ref sig, _) => { let TraitItemKind::Fn(sig, _) = &tcx.hir().expect_trait_item(def_id).kind else { bug!("{:?} is not a TraitItemKind::Fn", trait_m) };
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
}
_ => bug!("{:?} is not a TraitItemKind::Fn", trait_m),
}); });
match terr { match terr {
TypeError::ArgumentMutability(i) => { TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
}
TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i))) (impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
} }
_ => (cause.span(), tcx.hir().span_if_local(trait_m.def_id)), _ => (cause.span(), tcx.hir().span_if_local(trait_m.def_id)),
@ -1178,8 +1148,7 @@ fn compare_self_type<'tcx>(
} else { } else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
} }
let reported = err.emit(); return Err(err.emit());
return Err(reported);
} }
(true, false) => { (true, false) => {
@ -1198,8 +1167,8 @@ fn compare_self_type<'tcx>(
} else { } else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
} }
let reported = err.emit();
return Err(reported); return Err(err.emit());
} }
} }
@ -1381,41 +1350,39 @@ fn compare_number_of_method_arguments<'tcx>(
let trait_m_fty = tcx.fn_sig(trait_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id);
let trait_number_args = trait_m_fty.inputs().skip_binder().len(); let trait_number_args = trait_m_fty.inputs().skip_binder().len();
let impl_number_args = impl_m_fty.inputs().skip_binder().len(); let impl_number_args = impl_m_fty.inputs().skip_binder().len();
if trait_number_args != impl_number_args { if trait_number_args != impl_number_args {
let trait_span = if let Some(def_id) = trait_m.def_id.as_local() { let trait_span = trait_m
match tcx.hir().expect_trait_item(def_id).kind { .def_id
TraitItemKind::Fn(ref trait_m_sig, _) => { .as_local()
let pos = if trait_number_args > 0 { trait_number_args - 1 } else { 0 }; .and_then(|def_id| {
if let Some(arg) = trait_m_sig.decl.inputs.get(pos) { let TraitItemKind::Fn(trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).kind else { bug!("{:?} is not a method", impl_m) };
Some(if pos == 0 { let pos = trait_number_args.saturating_sub(1);
trait_m_sig.decl.inputs.get(pos).map(|arg| {
if pos == 0 {
arg.span arg.span
} else { } else {
arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo()) arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo())
}
}) })
} else { })
trait_item_span .or(trait_item_span);
}
} let ImplItemKind::Fn(impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{:?} is not a method", impl_m) };
_ => bug!("{:?} is not a method", impl_m), let pos = impl_number_args.saturating_sub(1);
} let impl_span = impl_m_sig
} else { .decl
trait_item_span .inputs
}; .get(pos)
let impl_span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind { .map(|arg| {
ImplItemKind::Fn(ref impl_m_sig, _) => {
let pos = if impl_number_args > 0 { impl_number_args - 1 } else { 0 };
if let Some(arg) = impl_m_sig.decl.inputs.get(pos) {
if pos == 0 { if pos == 0 {
arg.span arg.span
} else { } else {
arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo()) arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo())
} }
} else { })
impl_m_span .unwrap_or(impl_m_span);
}
}
_ => bug!("{:?} is not a method", impl_m),
};
let mut err = struct_span_err!( let mut err = struct_span_err!(
tcx.sess, tcx.sess,
impl_span, impl_span,
@ -1426,6 +1393,7 @@ fn compare_number_of_method_arguments<'tcx>(
tcx.def_path_str(trait_m.def_id), tcx.def_path_str(trait_m.def_id),
trait_number_args trait_number_args
); );
if let Some(trait_span) = trait_span { if let Some(trait_span) = trait_span {
err.span_label( err.span_label(
trait_span, trait_span,
@ -1437,6 +1405,7 @@ fn compare_number_of_method_arguments<'tcx>(
} else { } else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
} }
err.span_label( err.span_label(
impl_span, impl_span,
format!( format!(
@ -1445,8 +1414,8 @@ fn compare_number_of_method_arguments<'tcx>(
impl_number_args impl_number_args
), ),
); );
let reported = err.emit();
return Err(reported); return Err(err.emit());
} }
Ok(()) Ok(())
@ -1493,7 +1462,7 @@ fn compare_synthetic_generics<'tcx>(
// explicit generics // explicit generics
(true, false) => { (true, false) => {
err.span_label(impl_span, "expected generic parameter, found `impl Trait`"); err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
(|| { let _: Option<_> = try {
// try taking the name from the trait impl // try taking the name from the trait impl
// FIXME: this is obviously suboptimal since the name can already be used // FIXME: this is obviously suboptimal since the name can already be used
// as another generic argument // as another generic argument
@ -1526,26 +1495,23 @@ fn compare_synthetic_generics<'tcx>(
], ],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
Some(()) };
})();
} }
// The case where the trait method uses `impl Trait`, but the impl method uses // The case where the trait method uses `impl Trait`, but the impl method uses
// explicit generics. // explicit generics.
(false, true) => { (false, true) => {
err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
(|| { let _: Option<_> = try {
let impl_m = impl_m.def_id.as_local()?; let impl_m = impl_m.def_id.as_local()?;
let impl_m = tcx.hir().expect_impl_item(impl_m); let impl_m = tcx.hir().expect_impl_item(impl_m);
let input_tys = match impl_m.kind { let hir::ImplItemKind::Fn(sig, _) = &impl_m.kind else { unreachable!() };
hir::ImplItemKind::Fn(ref sig, _) => sig.decl.inputs, let input_tys = sig.decl.inputs;
_ => unreachable!(),
};
struct Visitor(Option<Span>, hir::def_id::LocalDefId); struct Visitor(Option<Span>, hir::def_id::LocalDefId);
impl<'v> intravisit::Visitor<'v> for Visitor { impl<'v> intravisit::Visitor<'v> for Visitor {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
intravisit::walk_ty(self, ty); intravisit::walk_ty(self, ty);
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
ty.kind
&& let Res::Def(DefKind::TyParam, def_id) = path.res && let Res::Def(DefKind::TyParam, def_id) = path.res
&& def_id == self.1.to_def_id() && def_id == self.1.to_def_id()
{ {
@ -1553,6 +1519,7 @@ fn compare_synthetic_generics<'tcx>(
} }
} }
} }
let mut visitor = Visitor(None, impl_def_id); let mut visitor = Visitor(None, impl_def_id);
for ty in input_tys { for ty in input_tys {
intravisit::Visitor::visit_ty(&mut visitor, ty); intravisit::Visitor::visit_ty(&mut visitor, ty);
@ -1573,13 +1540,11 @@ fn compare_synthetic_generics<'tcx>(
], ],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
Some(()) };
})();
} }
_ => unreachable!(), _ => unreachable!(),
} }
let reported = err.emit(); error_found = Some(err.emit());
error_found = Some(reported);
} }
} }
if let Some(reported) = error_found { Err(reported) } else { Ok(()) } if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
@ -1739,10 +1704,8 @@ pub(super) fn compare_impl_const_raw(
); );
// Locate the Span containing just the type of the offending impl // Locate the Span containing just the type of the offending impl
match tcx.hir().expect_impl_item(impl_const_item_def).kind { let ImplItemKind::Const(ty, _) = tcx.hir().expect_impl_item(impl_const_item_def).kind else { bug!("{impl_const_item:?} is not a impl const") };
ImplItemKind::Const(ref ty, _) => cause.span = ty.span, cause.span = ty.span;
_ => bug!("{:?} is not a impl const", impl_const_item),
}
let mut diag = struct_span_err!( let mut diag = struct_span_err!(
tcx.sess, tcx.sess,
@ -1754,10 +1717,8 @@ pub(super) fn compare_impl_const_raw(
let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| { let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| {
// Add a label to the Span containing just the type of the const // Add a label to the Span containing just the type of the const
match tcx.hir().expect_trait_item(trait_c_def_id).kind { let TraitItemKind::Const(ty, _) = tcx.hir().expect_trait_item(trait_c_def_id).kind else { bug!("{trait_const_item:?} is not a trait const") };
TraitItemKind::Const(ref ty, _) => ty.span, ty.span
_ => bug!("{:?} is not a trait const", trait_const_item),
}
}); });
infcx.err_ctxt().note_type_err( infcx.err_ctxt().note_type_err(
@ -1799,7 +1760,7 @@ pub(super) fn compare_impl_ty<'tcx>(
) { ) {
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
let _: Result<(), ErrorGuaranteed> = (|| { let _: Result<(), ErrorGuaranteed> = try {
compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?; compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?;
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
@ -1807,8 +1768,8 @@ pub(super) fn compare_impl_ty<'tcx>(
let sp = tcx.def_span(impl_ty.def_id); let sp = tcx.def_span(impl_ty.def_id);
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?; compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;
check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref) check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref)?;
})(); };
} }
/// The equivalent of [compare_method_predicate_entailment], but for associated types /// The equivalent of [compare_method_predicate_entailment], but for associated types

View file

@ -351,7 +351,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
} }
match *op { match *op {
hir::InlineAsmOperand::In { reg, ref expr } => { hir::InlineAsmOperand::In { reg, expr } => {
self.check_asm_operand_type( self.check_asm_operand_type(
idx, idx,
reg, reg,
@ -362,7 +362,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
&target_features, &target_features,
); );
} }
hir::InlineAsmOperand::Out { reg, late: _, ref expr } => { hir::InlineAsmOperand::Out { reg, late: _, expr } => {
if let Some(expr) = expr { if let Some(expr) = expr {
self.check_asm_operand_type( self.check_asm_operand_type(
idx, idx,
@ -375,7 +375,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
); );
} }
} }
hir::InlineAsmOperand::InOut { reg, late: _, ref expr } => { hir::InlineAsmOperand::InOut { reg, late: _, expr } => {
self.check_asm_operand_type( self.check_asm_operand_type(
idx, idx,
reg, reg,
@ -386,7 +386,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
&target_features, &target_features,
); );
} }
hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => { hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => {
let in_ty = self.check_asm_operand_type( let in_ty = self.check_asm_operand_type(
idx, idx,
reg, reg,

View file

@ -180,7 +180,7 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir
visitor.terminating_scopes.insert(arm.body.hir_id.local_id); visitor.terminating_scopes.insert(arm.body.hir_id.local_id);
if let Some(hir::Guard::If(ref expr)) = arm.guard { if let Some(hir::Guard::If(expr)) = arm.guard {
visitor.terminating_scopes.insert(expr.hir_id.local_id); visitor.terminating_scopes.insert(expr.hir_id.local_id);
} }
@ -242,8 +242,8 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
// This ensures fixed size stacks. // This ensures fixed size stacks.
hir::ExprKind::Binary( hir::ExprKind::Binary(
source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. }, source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
ref l, l,
ref r, r,
) => { ) => {
// expr is a short circuiting operator (|| or &&). As its // expr is a short circuiting operator (|| or &&). As its
// functionality can't be overridden by traits, it always // functionality can't be overridden by traits, it always
@ -288,20 +288,20 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
terminating(r.hir_id.local_id); terminating(r.hir_id.local_id);
} }
} }
hir::ExprKind::If(_, ref then, Some(ref otherwise)) => { hir::ExprKind::If(_, then, Some(otherwise)) => {
terminating(then.hir_id.local_id); terminating(then.hir_id.local_id);
terminating(otherwise.hir_id.local_id); terminating(otherwise.hir_id.local_id);
} }
hir::ExprKind::If(_, ref then, None) => { hir::ExprKind::If(_, then, None) => {
terminating(then.hir_id.local_id); terminating(then.hir_id.local_id);
} }
hir::ExprKind::Loop(ref body, _, _, _) => { hir::ExprKind::Loop(body, _, _, _) => {
terminating(body.hir_id.local_id); terminating(body.hir_id.local_id);
} }
hir::ExprKind::DropTemps(ref expr) => { hir::ExprKind::DropTemps(expr) => {
// `DropTemps(expr)` does not denote a conditional scope. // `DropTemps(expr)` does not denote a conditional scope.
// Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`. // Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`.
terminating(expr.hir_id.local_id); terminating(expr.hir_id.local_id);
@ -396,7 +396,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
let body = visitor.tcx.hir().body(body); let body = visitor.tcx.hir().body(body);
visitor.visit_body(body); visitor.visit_body(body);
} }
hir::ExprKind::AssignOp(_, ref left_expr, ref right_expr) => { hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
debug!( debug!(
"resolve_expr - enabling pessimistic_yield, was previously {}", "resolve_expr - enabling pessimistic_yield, was previously {}",
prev_pessimistic prev_pessimistic
@ -447,7 +447,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
} }
} }
hir::ExprKind::If(ref cond, ref then, Some(ref otherwise)) => { hir::ExprKind::If(cond, then, Some(otherwise)) => {
let expr_cx = visitor.cx; let expr_cx = visitor.cx;
visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen }); visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen });
visitor.cx.var_parent = visitor.cx.parent; visitor.cx.var_parent = visitor.cx.parent;
@ -457,7 +457,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
visitor.visit_expr(otherwise); visitor.visit_expr(otherwise);
} }
hir::ExprKind::If(ref cond, ref then, None) => { hir::ExprKind::If(cond, then, None) => {
let expr_cx = visitor.cx; let expr_cx = visitor.cx;
visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen }); visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen });
visitor.cx.var_parent = visitor.cx.parent; visitor.cx.var_parent = visitor.cx.parent;
@ -641,21 +641,21 @@ fn resolve_local<'tcx>(
match pat.kind { match pat.kind {
PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes, _), ..) => true, PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes, _), ..) => true,
PatKind::Struct(_, ref field_pats, _) => { PatKind::Struct(_, field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(&fp.pat)) field_pats.iter().any(|fp| is_binding_pat(&fp.pat))
} }
PatKind::Slice(ref pats1, ref pats2, ref pats3) => { PatKind::Slice(pats1, pats2, pats3) => {
pats1.iter().any(|p| is_binding_pat(&p)) pats1.iter().any(|p| is_binding_pat(&p))
|| pats2.iter().any(|p| is_binding_pat(&p)) || pats2.iter().any(|p| is_binding_pat(&p))
|| pats3.iter().any(|p| is_binding_pat(&p)) || pats3.iter().any(|p| is_binding_pat(&p))
} }
PatKind::Or(ref subpats) PatKind::Or(subpats)
| PatKind::TupleStruct(_, ref subpats, _) | PatKind::TupleStruct(_, subpats, _)
| PatKind::Tuple(ref subpats, _) => subpats.iter().any(|p| is_binding_pat(&p)), | PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(&p)),
PatKind::Box(ref subpat) => is_binding_pat(&subpat), PatKind::Box(subpat) => is_binding_pat(&subpat),
PatKind::Ref(_, _) PatKind::Ref(_, _)
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..) | PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
@ -704,11 +704,11 @@ fn resolve_local<'tcx>(
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
} }
} }
hir::ExprKind::Cast(ref subexpr, _) => { hir::ExprKind::Cast(subexpr, _) => {
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id) record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id)
} }
hir::ExprKind::Block(ref block, _) => { hir::ExprKind::Block(block, _) => {
if let Some(ref subexpr) = block.expr { if let Some(subexpr) = block.expr {
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
} }
} }

View file

@ -178,7 +178,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
// //
// won't be allowed unless there's an *explicit* implementation of `Send` // won't be allowed unless there's an *explicit* implementation of `Send`
// for `T` // for `T`
hir::ItemKind::Impl(ref impl_) => { hir::ItemKind::Impl(impl_) => {
let is_auto = tcx let is_auto = tcx
.impl_trait_ref(def_id) .impl_trait_ref(def_id)
.map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id)); .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id));
@ -224,15 +224,15 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
hir::ItemKind::Const(ty, ..) => { hir::ItemKind::Const(ty, ..) => {
check_item_type(tcx, def_id, ty.span, false); check_item_type(tcx, def_id, ty.span, false);
} }
hir::ItemKind::Struct(_, ref ast_generics) => { hir::ItemKind::Struct(_, ast_generics) => {
check_type_defn(tcx, item, false); check_type_defn(tcx, item, false);
check_variances_for_type_defn(tcx, item, ast_generics); check_variances_for_type_defn(tcx, item, ast_generics);
} }
hir::ItemKind::Union(_, ref ast_generics) => { hir::ItemKind::Union(_, ast_generics) => {
check_type_defn(tcx, item, true); check_type_defn(tcx, item, true);
check_variances_for_type_defn(tcx, item, ast_generics); check_variances_for_type_defn(tcx, item, ast_generics);
} }
hir::ItemKind::Enum(_, ref ast_generics) => { hir::ItemKind::Enum(_, ast_generics) => {
check_type_defn(tcx, item, true); check_type_defn(tcx, item, true);
check_variances_for_type_defn(tcx, item, ast_generics); check_variances_for_type_defn(tcx, item, ast_generics);
} }
@ -1247,8 +1247,8 @@ fn check_impl<'tcx>(
constness: hir::Constness, constness: hir::Constness,
) { ) {
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
match *ast_trait_ref { match ast_trait_ref {
Some(ref ast_trait_ref) => { Some(ast_trait_ref) => {
// `#[rustc_reservation_impl]` impls are not real impls and // `#[rustc_reservation_impl]` impls are not real impls and
// therefore don't need to be WF (the trait's `Self: Trait` predicate // therefore don't need to be WF (the trait's `Self: Trait` predicate
// won't hold). // won't hold).

View file

@ -54,12 +54,9 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
_ => {} _ => {}
} }
let sp = match tcx.hir().expect_item(impl_did).kind { let ItemKind::Impl(impl_) = tcx.hir().expect_item(impl_did).kind else { bug!("expected Drop impl item") };
ItemKind::Impl(ref impl_) => impl_.self_ty.span,
_ => bug!("expected Drop impl item"),
};
tcx.sess.emit_err(DropImplOnWrongItem { span: sp }); tcx.sess.emit_err(DropImplOnWrongItem { span: impl_.self_ty.span });
} }
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
@ -505,8 +502,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
return err_info; return err_info;
} else if diff_fields.len() > 1 { } else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_did); let item = tcx.hir().expect_item(impl_did);
let span = let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind {
if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) = item.kind {
t.path.span t.path.span
} else { } else {
tcx.def_span(impl_did) tcx.def_span(impl_did)

View file

@ -182,7 +182,7 @@ impl<'tcx> InherentCollect<'tcx> {
} }
let item = self.tcx.hir().item(id); let item = self.tcx.hir().item(id);
let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, ref items, .. }) = item.kind else { let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items, .. }) = item.kind else {
return; return;
}; };

View file

@ -40,7 +40,7 @@ fn do_orphan_check_impl<'tcx>(
let trait_def_id = trait_ref.def_id; let trait_def_id = trait_ref.def_id;
let item = tcx.hir().expect_item(def_id); let item = tcx.hir().expect_item(def_id);
let hir::ItemKind::Impl(ref impl_) = item.kind else { let hir::ItemKind::Impl(impl_) = item.kind else {
bug!("{:?} is not an impl: {:?}", def_id, item); bug!("{:?} is not an impl: {:?}", def_id, item);
}; };
let sp = tcx.def_span(def_id); let sp = tcx.def_span(def_id);

View file

@ -11,7 +11,7 @@ use rustc_span::def_id::LocalDefId;
pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Impl)); debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Impl));
let item = tcx.hir().expect_item(def_id); let item = tcx.hir().expect_item(def_id);
let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() }; let hir::ItemKind::Impl(impl_) = item.kind else { bug!() };
if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) { if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
let trait_ref = trait_ref.subst_identity(); let trait_ref = trait_ref.subst_identity();

View file

@ -561,7 +561,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
debug!("convert: item {} with id {}", it.ident, it.hir_id()); debug!("convert: item {} with id {}", it.ident, it.hir_id());
let def_id = item_id.owner_id.def_id; let def_id = item_id.owner_id.def_id;
match it.kind { match &it.kind {
// These don't define types. // These don't define types.
hir::ItemKind::ExternCrate(_) hir::ItemKind::ExternCrate(_)
| hir::ItemKind::Use(..) | hir::ItemKind::Use(..)
@ -569,7 +569,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
| hir::ItemKind::Mod(_) | hir::ItemKind::Mod(_)
| hir::ItemKind::GlobalAsm(_) => {} | hir::ItemKind::GlobalAsm(_) => {}
hir::ItemKind::ForeignMod { items, .. } => { hir::ItemKind::ForeignMod { items, .. } => {
for item in items { for item in *items {
let item = tcx.hir().foreign_item(item.id); let item = tcx.hir().foreign_item(item.id);
tcx.ensure().generics_of(item.owner_id); tcx.ensure().generics_of(item.owner_id);
tcx.ensure().type_of(item.owner_id); tcx.ensure().type_of(item.owner_id);
@ -619,7 +619,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.at(it.span).super_predicates_of(def_id); tcx.at(it.span).super_predicates_of(def_id);
tcx.ensure().predicates_of(def_id); tcx.ensure().predicates_of(def_id);
} }
hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
tcx.ensure().generics_of(def_id); tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id); tcx.ensure().type_of(def_id);
tcx.ensure().predicates_of(def_id); tcx.ensure().predicates_of(def_id);
@ -854,14 +854,14 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtDef<'_> {
}; };
let repr = tcx.repr_options_of_def(def_id.to_def_id()); let repr = tcx.repr_options_of_def(def_id.to_def_id());
let (kind, variants) = match item.kind { let (kind, variants) = match &item.kind {
ItemKind::Enum(ref def, _) => { ItemKind::Enum(def, _) => {
let mut distance_from_explicit = 0; let mut distance_from_explicit = 0;
let variants = def let variants = def
.variants .variants
.iter() .iter()
.map(|v| { .map(|v| {
let discr = if let Some(ref e) = v.disr_expr { let discr = if let Some(e) = &v.disr_expr {
distance_from_explicit = 0; distance_from_explicit = 0;
ty::VariantDiscr::Explicit(e.def_id.to_def_id()) ty::VariantDiscr::Explicit(e.def_id.to_def_id())
} else { } else {
@ -883,7 +883,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtDef<'_> {
(AdtKind::Enum, variants) (AdtKind::Enum, variants)
} }
ItemKind::Struct(ref def, _) | ItemKind::Union(ref def, _) => { ItemKind::Struct(def, _) | ItemKind::Union(def, _) => {
let adt_kind = match item.kind { let adt_kind = match item.kind {
ItemKind::Struct(..) => AdtKind::Struct, ItemKind::Struct(..) => AdtKind::Struct,
_ => AdtKind::Union, _ => AdtKind::Union,
@ -1343,8 +1343,8 @@ fn suggest_impl_trait<'tcx>(
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> { fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
let icx = ItemCtxt::new(tcx, def_id); let icx = ItemCtxt::new(tcx, def_id);
let item = tcx.hir().expect_item(def_id.expect_local()); let item = tcx.hir().expect_item(def_id.expect_local());
match item.kind { let hir::ItemKind::Impl(impl_) = item.kind else { bug!() };
hir::ItemKind::Impl(ref impl_) => impl_ impl_
.of_trait .of_trait
.as_ref() .as_ref()
.map(|ast_trait_ref| { .map(|ast_trait_ref| {
@ -1355,9 +1355,7 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::EarlyBinder<ty::
check_impl_constness(tcx, impl_.constness, ast_trait_ref), check_impl_constness(tcx, impl_.constness, ast_trait_ref),
) )
}) })
.map(ty::EarlyBinder), .map(ty::EarlyBinder)
_ => bug!(),
}
} }
fn check_impl_constness( fn check_impl_constness(
@ -1512,7 +1510,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) { for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
check(input, *ty) check(input, *ty)
} }
if let hir::FnRetTy::Return(ref ty) = decl.output { if let hir::FnRetTy::Return(ty) = decl.output {
check(ty, fty.output().skip_binder()) check(ty, fty.output().skip_binder())
} }
} }

View file

@ -110,12 +110,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
// expressions' count (i.e. `N` in `[x; N]`), and explicit // expressions' count (i.e. `N` in `[x; N]`), and explicit
// `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
// as they shouldn't be able to cause query cycle errors. // as they shouldn't be able to cause query cycle errors.
Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
if constant.hir_id() == hir_id => if constant.hir_id() == hir_id =>
{ {
Some(parent_def_id.to_def_id()) Some(parent_def_id.to_def_id())
} }
Node::Variant(Variant { disr_expr: Some(ref constant), .. }) Node::Variant(Variant { disr_expr: Some(constant), .. })
if constant.hir_id == hir_id => if constant.hir_id == hir_id =>
{ {
Some(parent_def_id.to_def_id()) Some(parent_def_id.to_def_id())
@ -259,7 +259,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind { params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => None, GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref default, synthetic, .. } => { GenericParamKind::Type { default, synthetic, .. } => {
if default.is_some() { if default.is_some() {
match allow_defaults { match allow_defaults {
Defaults::Allowed => {} Defaults::Allowed => {}
@ -426,26 +426,22 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
} }
match node { match node {
Node::TraitItem(item) => match item.kind { Node::TraitItem(item) => match &item.kind {
hir::TraitItemKind::Fn(ref sig, _) => { hir::TraitItemKind::Fn(sig, _) => has_late_bound_regions(tcx, &item.generics, sig.decl),
has_late_bound_regions(tcx, &item.generics, sig.decl)
}
_ => None, _ => None,
}, },
Node::ImplItem(item) => match item.kind { Node::ImplItem(item) => match &item.kind {
hir::ImplItemKind::Fn(ref sig, _) => { hir::ImplItemKind::Fn(sig, _) => has_late_bound_regions(tcx, &item.generics, sig.decl),
has_late_bound_regions(tcx, &item.generics, sig.decl)
}
_ => None, _ => None,
}, },
Node::ForeignItem(item) => match item.kind { Node::ForeignItem(item) => match item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => { hir::ForeignItemKind::Fn(fn_decl, _, generics) => {
has_late_bound_regions(tcx, generics, fn_decl) has_late_bound_regions(tcx, generics, fn_decl)
} }
_ => None, _ => None,
}, },
Node::Item(item) => match item.kind { Node::Item(item) => match &item.kind {
hir::ItemKind::Fn(ref sig, .., ref generics, _) => { hir::ItemKind::Fn(sig, .., generics, _) => {
has_late_bound_regions(tcx, generics, sig.decl) has_late_bound_regions(tcx, generics, sig.decl)
} }
_ => None, _ => None,

View file

@ -428,7 +428,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
_ => {} _ => {}
} }
match item.kind { match item.kind {
hir::ItemKind::Fn(_, ref generics, _) => { hir::ItemKind::Fn(_, generics, _) => {
self.visit_early_late(item.hir_id(), generics, |this| { self.visit_early_late(item.hir_id(), generics, |this| {
intravisit::walk_item(this, item); intravisit::walk_item(this, item);
}); });
@ -508,13 +508,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
this.with(scope, |this| intravisit::walk_item(this, item)) this.with(scope, |this| intravisit::walk_item(this, item))
}); });
} }
hir::ItemKind::TyAlias(_, ref generics) hir::ItemKind::TyAlias(_, generics)
| hir::ItemKind::Enum(_, ref generics) | hir::ItemKind::Enum(_, generics)
| hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Struct(_, generics)
| hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Union(_, generics)
| hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::Trait(_, _, generics, ..)
| hir::ItemKind::TraitAlias(ref generics, ..) | hir::ItemKind::TraitAlias(generics, ..)
| hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => { | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
// These kinds of items have only early-bound lifetime parameters. // These kinds of items have only early-bound lifetime parameters.
let lifetimes = generics let lifetimes = generics
.params .params
@ -544,7 +544,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
match item.kind { match item.kind {
hir::ForeignItemKind::Fn(_, _, ref generics) => { hir::ForeignItemKind::Fn(_, _, generics) => {
self.visit_early_late(item.hir_id(), generics, |this| { self.visit_early_late(item.hir_id(), generics, |this| {
intravisit::walk_foreign_item(this, item); intravisit::walk_foreign_item(this, item);
}) })
@ -561,7 +561,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
match ty.kind { match ty.kind {
hir::TyKind::BareFn(ref c) => { hir::TyKind::BareFn(c) => {
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c
.generic_params .generic_params
.iter() .iter()
@ -587,7 +587,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
intravisit::walk_ty(this, ty); intravisit::walk_ty(this, ty);
}); });
} }
hir::TyKind::TraitObject(bounds, ref lifetime, _) => { hir::TyKind::TraitObject(bounds, lifetime, _) => {
debug!(?bounds, ?lifetime, "TraitObject"); debug!(?bounds, ?lifetime, "TraitObject");
let scope = Scope::TraitRefBoundary { s: self.scope }; let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |this| { self.with(scope, |this| {
@ -617,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
LifetimeName::Error => {} LifetimeName::Error => {}
} }
} }
hir::TyKind::Ref(ref lifetime_ref, ref mt) => { hir::TyKind::Ref(lifetime_ref, ref mt) => {
self.visit_lifetime(lifetime_ref); self.visit_lifetime(lifetime_ref);
let scope = Scope::ObjectLifetimeDefault { let scope = Scope::ObjectLifetimeDefault {
lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(), lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
@ -632,7 +632,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// ^ ^ this gets resolved in the scope of // ^ ^ this gets resolved in the scope of
// the opaque_ty generics // the opaque_ty generics
let opaque_ty = self.tcx.hir().item(item_id); let opaque_ty = self.tcx.hir().item(item_id);
match opaque_ty.kind { match &opaque_ty.kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { hir::ItemKind::OpaqueTy(hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias, origin: hir::OpaqueTyOrigin::TyAlias,
.. ..
@ -655,7 +655,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..), origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
.. ..
}) => {} }) => {}
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
}; };
// Resolve the lifetimes that are applied to the opaque type. // Resolve the lifetimes that are applied to the opaque type.
@ -720,7 +720,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
intravisit::walk_trait_item(this, trait_item) intravisit::walk_trait_item(this, trait_item)
}); });
} }
Type(bounds, ref ty) => { Type(bounds, ty) => {
let generics = &trait_item.generics; let generics = &trait_item.generics;
let lifetimes = generics let lifetimes = generics
.params .params
@ -766,7 +766,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
Fn(..) => self.visit_early_late(impl_item.hir_id(), &impl_item.generics, |this| { Fn(..) => self.visit_early_late(impl_item.hir_id(), &impl_item.generics, |this| {
intravisit::walk_impl_item(this, impl_item) intravisit::walk_impl_item(this, impl_item)
}), }),
Type(ref ty) => { Type(ty) => {
let generics = &impl_item.generics; let generics = &impl_item.generics;
let lifetimes: FxIndexMap<LocalDefId, Region> = generics let lifetimes: FxIndexMap<LocalDefId, Region> = generics
.params .params
@ -817,7 +817,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) { fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
for (i, segment) in path.segments.iter().enumerate() { for (i, segment) in path.segments.iter().enumerate() {
let depth = path.segments.len() - i - 1; let depth = path.segments.len() - i - 1;
if let Some(ref args) = segment.args { if let Some(args) = segment.args {
self.visit_segment_args(path.res, depth, args); self.visit_segment_args(path.res, depth, args);
} }
} }
@ -833,7 +833,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
) { ) {
let output = match fd.output { let output = match fd.output {
hir::FnRetTy::DefaultReturn(_) => None, hir::FnRetTy::DefaultReturn(_) => None,
hir::FnRetTy::Return(ref ty) => Some(&**ty), hir::FnRetTy::Return(ty) => Some(ty),
}; };
self.visit_fn_like_elision(&fd.inputs, output, matches!(fk, intravisit::FnKind::Closure)); self.visit_fn_like_elision(&fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
intravisit::walk_fn_kind(self, fk); intravisit::walk_fn_kind(self, fk);
@ -846,13 +846,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
for param in generics.params { for param in generics.params {
match param.kind { match param.kind {
GenericParamKind::Lifetime { .. } => {} GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { ref default, .. } => { GenericParamKind::Type { default, .. } => {
if let Some(ref ty) = default { if let Some(ty) = default {
this.visit_ty(&ty); this.visit_ty(ty);
} }
} }
GenericParamKind::Const { ref ty, default } => { GenericParamKind::Const { ty, default } => {
this.visit_ty(&ty); this.visit_ty(ty);
if let Some(default) = default { if let Some(default) = default {
this.visit_body(this.tcx.hir().body(default.body)); this.visit_body(this.tcx.hir().body(default.body));
} }
@ -863,9 +863,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
match predicate { match predicate {
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
hir_id, hir_id,
ref bounded_ty, bounded_ty,
bounds, bounds,
ref bound_generic_params, bound_generic_params,
origin, origin,
.. ..
}) => { }) => {
@ -905,7 +905,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}) })
} }
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
ref lifetime, lifetime,
bounds, bounds,
.. ..
}) => { }) => {
@ -914,7 +914,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
if lifetime.res != hir::LifetimeName::Static { if lifetime.res != hir::LifetimeName::Static {
for bound in bounds { for bound in bounds {
let hir::GenericBound::Outlives(ref lt) = bound else { let hir::GenericBound::Outlives(lt) = bound else {
continue; continue;
}; };
if lt.res != hir::LifetimeName::Static { if lt.res != hir::LifetimeName::Static {
@ -939,8 +939,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
} }
} }
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
ref lhs_ty, lhs_ty,
ref rhs_ty, rhs_ty,
.. ..
}) => { }) => {
this.visit_ty(lhs_ty); this.visit_ty(lhs_ty);
@ -1042,7 +1042,7 @@ fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: DefId) -> ObjectLifeti
} }
for bound in bound.bounds { for bound in bound.bounds {
if let hir::GenericBound::Outlives(ref lifetime) = *bound { if let hir::GenericBound::Outlives(lifetime) = bound {
set.insert(lifetime.res); set.insert(lifetime.res);
} }
} }
@ -1828,7 +1828,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
} }
} }
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => { hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
// consider only the lifetimes on the final // consider only the lifetimes on the final
// segment; I am not sure it's even currently // segment; I am not sure it's even currently
// valid to have them elsewhere, but even if it // valid to have them elsewhere, but even if it

View file

@ -85,30 +85,30 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
Node::ImplItem(item) => item.generics, Node::ImplItem(item) => item.generics,
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
ItemKind::Impl(ref impl_) => { ItemKind::Impl(impl_) => {
if impl_.defaultness.is_default() { if impl_.defaultness.is_default() {
is_default_impl_trait = is_default_impl_trait =
tcx.impl_trait_ref(def_id).map(|t| ty::Binder::dummy(t.subst_identity())); tcx.impl_trait_ref(def_id).map(|t| ty::Binder::dummy(t.subst_identity()));
} }
&impl_.generics impl_.generics
} }
ItemKind::Fn(.., ref generics, _) ItemKind::Fn(.., generics, _)
| ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, generics)
| ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, generics)
| ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, generics)
| ItemKind::Union(_, ref generics) => *generics, | ItemKind::Union(_, generics) => generics,
ItemKind::Trait(_, _, ref generics, ..) | ItemKind::TraitAlias(ref generics, _) => { ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => {
is_trait = Some(ty::TraitRef::identity(tcx, def_id)); is_trait = Some(ty::TraitRef::identity(tcx, def_id));
*generics generics
} }
ItemKind::OpaqueTy(OpaqueTy { ref generics, .. }) => generics, ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics,
_ => NO_GENERICS, _ => NO_GENERICS,
}, },
Node::ForeignItem(item) => match item.kind { Node::ForeignItem(item) => match item.kind {
ForeignItemKind::Static(..) => NO_GENERICS, ForeignItemKind::Static(..) => NO_GENERICS,
ForeignItemKind::Fn(_, _, ref generics) => *generics, ForeignItemKind::Fn(_, _, generics) => generics,
ForeignItemKind::Type => NO_GENERICS, ForeignItemKind::Type => NO_GENERICS,
}, },
@ -350,7 +350,7 @@ fn const_evaluatable_predicates_of(
let node = tcx.hir().get(hir_id); let node = tcx.hir().get(hir_id);
let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind { if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(impl_) = item.kind {
if let Some(of_trait) = &impl_.of_trait { if let Some(of_trait) = &impl_.of_trait {
debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
collector.visit_trait_ref(of_trait); collector.visit_trait_ref(of_trait);
@ -511,8 +511,8 @@ pub(super) fn super_predicates_that_define_assoc_type(
}; };
let (generics, bounds) = match item.kind { let (generics, bounds) = match item.kind {
hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits), hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits), hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
_ => span_bug!(item.span, "super_predicates invoked on non-trait"), _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
}; };
@ -612,18 +612,18 @@ pub(super) fn type_param_predicates(
Node::Item(item) => { Node::Item(item) => {
match item.kind { match item.kind {
ItemKind::Fn(.., ref generics, _) ItemKind::Fn(.., generics, _)
| ItemKind::Impl(hir::Impl { ref generics, .. }) | ItemKind::Impl(&hir::Impl { generics, .. })
| ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, generics)
| ItemKind::OpaqueTy(OpaqueTy { | ItemKind::OpaqueTy(OpaqueTy {
ref generics, generics,
origin: hir::OpaqueTyOrigin::TyAlias, origin: hir::OpaqueTyOrigin::TyAlias,
.. ..
}) })
| ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, generics)
| ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, generics)
| ItemKind::Union(_, ref generics) => generics, | ItemKind::Union(_, generics) => generics,
ItemKind::Trait(_, _, ref generics, ..) => { ItemKind::Trait(_, _, generics, ..) => {
// Implied `Self: Trait` and supertrait bounds. // Implied `Self: Trait` and supertrait bounds.
if param_id == item_hir_id { if param_id == item_hir_id {
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
@ -637,7 +637,7 @@ pub(super) fn type_param_predicates(
} }
Node::ForeignItem(item) => match item.kind { Node::ForeignItem(item) => match item.kind {
ForeignItemKind::Fn(_, _, ref generics) => generics, ForeignItemKind::Fn(_, _, generics) => generics,
_ => return result, _ => return result,
}, },
@ -681,8 +681,8 @@ impl<'tcx> ItemCtxt<'tcx> {
ast_generics ast_generics
.predicates .predicates
.iter() .iter()
.filter_map(|wp| match *wp { .filter_map(|wp| match wp {
hir::WherePredicate::BoundPredicate(ref bp) => Some(bp), hir::WherePredicate::BoundPredicate(bp) => Some(bp),
_ => None, _ => None,
}) })
.flat_map(|bp| { .flat_map(|bp| {

View file

@ -379,7 +379,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
ForeignItemKind::Type => tcx.mk_foreign(def_id.to_def_id()), ForeignItemKind::Type => tcx.mk_foreign(def_id.to_def_id()),
}, },
Node::Ctor(&ref def) | Node::Variant(Variant { data: ref def, .. }) => match *def { Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
VariantData::Unit(..) | VariantData::Struct(..) => { VariantData::Unit(..) | VariantData::Struct(..) => {
tcx.type_of(tcx.hir().get_parent_item(hir_id)) tcx.type_of(tcx.hir().get_parent_item(hir_id))
} }
@ -404,17 +404,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::AnonConst(_) => { Node::AnonConst(_) => {
let parent_node = tcx.hir().get_parent(hir_id); let parent_node = tcx.hir().get_parent(hir_id);
match parent_node { match parent_node {
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) Node::Ty(Ty { kind: TyKind::Array(_, constant), .. })
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
if constant.hir_id() == hir_id => if constant.hir_id() == hir_id =>
{ {
tcx.types.usize tcx.types.usize
} }
Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => { Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => {
tcx.typeck(def_id).node_type(e.hir_id) tcx.typeck(def_id).node_type(e.hir_id)
} }
Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. }) Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. })
if anon_const.hir_id == hir_id => if anon_const.hir_id == hir_id =>
{ {
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
@ -434,18 +434,19 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
tcx.typeck(def_id).node_type(hir_id) tcx.typeck(def_id).node_type(hir_id)
} }
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
} }
Node::TypeBinding( Node::TypeBinding(
binding @ &TypeBinding { TypeBinding {
hir_id: binding_id, hir_id: binding_id,
kind: TypeBindingKind::Equality { term: Term::Const(ref e) }, kind: TypeBindingKind::Equality { term: Term::Const(e) },
ident,
.. ..
}, },
) if let Node::TraitRef(trait_ref) = ) if let Node::TraitRef(trait_ref) =
tcx.hir().get_parent(binding_id) tcx.hir().get_parent(*binding_id)
&& e.hir_id == hir_id => && e.hir_id == hir_id =>
{ {
let Some(trait_def_id) = trait_ref.trait_def_id() else { let Some(trait_def_id) = trait_ref.trait_def_id() else {
@ -454,7 +455,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let assoc_items = tcx.associated_items(trait_def_id); let assoc_items = tcx.associated_items(trait_def_id);
let assoc_item = assoc_items.find_by_name_and_kind( let assoc_item = assoc_items.find_by_name_and_kind(
tcx, tcx,
binding.ident, *ident,
ty::AssocKind::Const, ty::AssocKind::Const,
def_id.to_def_id(), def_id.to_def_id(),
); );
@ -470,9 +471,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
} }
Node::TypeBinding( Node::TypeBinding(
binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. }, TypeBinding { hir_id: binding_id, gen_args, kind, ident, .. },
) if let Node::TraitRef(trait_ref) = ) if let Node::TraitRef(trait_ref) =
tcx.hir().get_parent(binding_id) tcx.hir().get_parent(*binding_id)
&& let Some((idx, _)) = && let Some((idx, _)) =
gen_args.args.iter().enumerate().find(|(_, arg)| { gen_args.args.iter().enumerate().find(|(_, arg)| {
if let GenericArg::Const(ct) = arg { if let GenericArg::Const(ct) = arg {
@ -488,7 +489,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let assoc_items = tcx.associated_items(trait_def_id); let assoc_items = tcx.associated_items(trait_def_id);
let assoc_item = assoc_items.find_by_name_and_kind( let assoc_item = assoc_items.find_by_name_and_kind(
tcx, tcx,
binding.ident, *ident,
match kind { match kind {
// I think `<A: T>` type bindings requires that `A` is a type // I think `<A: T>` type bindings requires that `A` is a type
TypeBindingKind::Constraint { .. } TypeBindingKind::Constraint { .. }

View file

@ -128,7 +128,7 @@ fn diagnostic_hir_wf_check<'tcx>(
}, },
hir::Node::Item(item) => match item.kind { hir::Node::Item(item) => match item.kind {
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty], hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait { hir::ItemKind::Impl(impl_) => match &impl_.of_trait {
Some(t) => t Some(t) => t
.path .path
.segments .segments

View file

@ -114,6 +114,7 @@ use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use std::iter; use std::iter;
use std::ops::Not;
use astconv::AstConv; use astconv::AstConv;
use bounds::Bounds; use bounds::Bounds;
@ -203,12 +204,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
} }
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) { match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, ref generics, _), .. })) => { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
if !generics.params.is_empty() { generics.params.is_empty().not().then(|| generics.span)
Some(generics.span)
} else {
None
}
} }
_ => { _ => {
span_bug!(tcx.def_span(def_id), "main has a non-function type"); span_bug!(tcx.def_span(def_id), "main has a non-function type");
@ -222,7 +219,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
} }
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) { match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, ref generics, _), .. })) => { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
Some(generics.where_clause_span) Some(generics.where_clause_span)
} }
_ => { _ => {
@ -244,7 +241,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
} }
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir().find(hir_id) { match tcx.hir().find(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(ref fn_sig, _, _), .. })) => { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
Some(fn_sig.decl.output.span()) Some(fn_sig.decl.output.span())
} }
_ => { _ => {
@ -374,7 +371,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
match start_t.kind() { match start_t.kind() {
ty::FnDef(..) => { ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.hir().find(start_id) { if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind { if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false; let mut error = false;
if !generics.params.is_empty() { if !generics.params.is_empty() {
struct_span_err!( struct_span_err!(

View file

@ -727,8 +727,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id) if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
&& let Some(parent_node) = self.tcx.hir().find(parent_node) && let Some(parent_node) = self.tcx.hir().find(parent_node)
&& let hir::Node::Expr(expr) = parent_node { && let hir::Node::Expr(expr) = parent_node {
match expr.kind { match &expr.kind {
hir::ExprKind::Path(ref qpath) => { hir::ExprKind::Path(qpath) => {
self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
err, err,
qpath, qpath,

View file

@ -28,8 +28,8 @@ pub fn solve_constraints<'tcx>(
let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()]; let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()];
for &(id, ref variances) in &terms_cx.lang_items { for (id, variances) in &terms_cx.lang_items {
let InferredIndex(start) = terms_cx.inferred_starts[&id]; let InferredIndex(start) = terms_cx.inferred_starts[id];
for (i, &variance) in variances.iter().enumerate() { for (i, &variance) in variances.iter().enumerate() {
solutions[start + i] = variance; solutions[start + i] = variance;
} }

View file

@ -251,7 +251,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
VarValue::Empty(a_universe) => { VarValue::Empty(a_universe) => {
let b_data = var_values.value_mut(b_vid); let b_data = var_values.value_mut(b_vid);
let changed = (|| match *b_data { let changed = match *b_data {
VarValue::Empty(b_universe) => { VarValue::Empty(b_universe) => {
// Empty regions are ordered according to the universe // Empty regions are ordered according to the universe
// they are associated with. // they are associated with.
@ -280,9 +280,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}; };
if lub == cur_region { if lub == cur_region {
return false; false
} } else {
debug!( debug!(
"Expanding value of {:?} from {:?} to {:?}", "Expanding value of {:?} from {:?} to {:?}",
b_vid, cur_region, lub b_vid, cur_region, lub
@ -291,9 +290,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
*b_data = VarValue::Value(lub); *b_data = VarValue::Value(lub);
true true
} }
}
VarValue::ErrorValue => false, VarValue::ErrorValue => false,
})(); };
if changed { if changed {
changes.push(b_vid); changes.push(b_vid);

View file

@ -3,6 +3,7 @@
#![feature(internal_output_capture)] #![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)] #![feature(thread_spawn_unchecked)]
#![feature(once_cell)] #![feature(once_cell)]
#![feature(try_blocks)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)] #![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]

View file

@ -558,7 +558,7 @@ fn write_out_deps(
} }
let deps_filename = outputs.path(OutputType::DepInfo); let deps_filename = outputs.path(OutputType::DepInfo);
let result = (|| -> io::Result<()> { let result: io::Result<()> = try {
// Build a list of files used to compile the output and // Build a list of files used to compile the output and
// write Makefile-compatible dependency rules // write Makefile-compatible dependency rules
let mut files: Vec<String> = sess let mut files: Vec<String> = sess
@ -645,9 +645,7 @@ fn write_out_deps(
writeln!(file)?; writeln!(file)?;
} }
} }
};
Ok(())
})();
match result { match result {
Ok(_) => { Ok(_) => {

View file

@ -159,7 +159,8 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
} }
chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)), chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)),
chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)), chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)),
chalk_ir::TyKind::Tuple(len, substs) => Some((|| { chalk_ir::TyKind::Tuple(len, substs) => Some(
try {
write!(fmt, "(")?; write!(fmt, "(")?;
for (idx, substitution) in substs.interned().iter().enumerate() { for (idx, substitution) in substs.interned().iter().enumerate() {
if idx == *len && *len != 1 { if idx == *len && *len != 1 {
@ -169,8 +170,9 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
write!(fmt, "{:?},", substitution)?; write!(fmt, "{:?},", substitution)?;
} }
} }
write!(fmt, ")") write!(fmt, ")")?;
})()), },
),
_ => None, _ => None,
} }
} }

View file

@ -86,10 +86,10 @@ pub(super) fn build_custom_mir<'tcx>(
block_map: FxHashMap::default(), block_map: FxHashMap::default(),
}; };
let res = (|| { let res: PResult<_> = try {
pctxt.parse_args(&params)?; pctxt.parse_args(&params)?;
pctxt.parse_body(expr) pctxt.parse_body(expr)?;
})(); };
if let Err(err) = res { if let Err(err) = res {
tcx.sess.diagnostic().span_fatal( tcx.sess.diagnostic().span_fatal(
err.span, err.span,

View file

@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// //
// it is usually better to focus on `the_value` rather // it is usually better to focus on `the_value` rather
// than the entirety of block(s) surrounding it. // than the entirety of block(s) surrounding it.
let adjusted_span = (|| { let adjusted_span =
if let ExprKind::Block { block } = expr.kind if let ExprKind::Block { block } = expr.kind
&& let Some(tail_ex) = this.thir[block].expr && let Some(tail_ex) = this.thir[block].expr
{ {
@ -135,10 +135,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
tail_result_is_ignored: true, tail_result_is_ignored: true,
span: expr.span, span: expr.span,
}); });
return Some(expr.span); Some(expr.span)
} } else {
None None
})(); };
let temp = let temp =
unpack!(block = this.as_temp(block, statement_scope, expr, Mutability::Not)); unpack!(block = this.as_temp(block, statement_scope, expr, Mutability::Not));

View file

@ -141,27 +141,22 @@ impl IntRange {
) -> Option<IntRange> { ) -> Option<IntRange> {
let ty = value.ty(); let ty = value.ty();
if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) { if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
let val = (|| { let val = if let mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) = value {
match value {
mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) => {
// For this specific pattern we can skip a lot of effort and go // For this specific pattern we can skip a lot of effort and go
// straight to the result, after doing a bit of checking. (We // straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which // could remove this branch and just fall through, which
// is more general but much slower.) // is more general but much slower.)
return scalar.to_bits_or_ptr_internal(target_size).unwrap().left(); scalar.to_bits_or_ptr_internal(target_size).unwrap().left()?
} } else {
mir::ConstantKind::Ty(c) => match c.kind() { if let mir::ConstantKind::Ty(c) = value
ty::ConstKind::Value(_) => bug!( && let ty::ConstKind::Value(_) = c.kind()
"encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val" {
), bug!("encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val");
_ => {}
},
_ => {}
} }
// This is a more general form of the previous case. // This is a more general form of the previous case.
value.try_eval_bits(tcx, param_env, ty) value.try_eval_bits(tcx, param_env, ty)?
})()?; };
let val = val ^ bias; let val = val ^ bias;
Some(IntRange { range: val..=val, bias }) Some(IntRange { range: val..=val, bias })
} else { } else {

View file

@ -201,7 +201,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// wait to fold the substs. // wait to fold the substs.
// Wrap this in a closure so we don't accidentally return from the outer function // Wrap this in a closure so we don't accidentally return from the outer function
let res = (|| match *ty.kind() { let res = match *ty.kind() {
// This is really important. While we *can* handle this, this has // This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with // severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark. // late-bound regions. See `issue-88862` benchmark.
@ -210,7 +210,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
{ {
// Only normalize `impl Trait` outside of type inference, usually in codegen. // Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() { match self.param_env.reveal() {
Reveal::UserFacing => ty.try_super_fold_with(self), Reveal::UserFacing => ty.try_super_fold_with(self)?,
Reveal::All => { Reveal::All => {
let substs = substs.try_fold_with(self)?; let substs = substs.try_fold_with(self)?;
@ -239,7 +239,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
} }
let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty)); let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
self.anon_depth -= 1; self.anon_depth -= 1;
folded_ty folded_ty?
} }
} }
} }
@ -287,9 +287,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// `tcx.normalize_projection_ty` may normalize to a type that still has // `tcx.normalize_projection_ty` may normalize to a type that still has
// unevaluated consts, so keep normalizing here if that's the case. // unevaluated consts, so keep normalizing here if that's the case.
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
Ok(res.try_super_fold_with(self)?) res.try_super_fold_with(self)?
} else { } else {
Ok(res) res
} }
} }
@ -344,14 +344,14 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// `tcx.normalize_projection_ty` may normalize to a type that still has // `tcx.normalize_projection_ty` may normalize to a type that still has
// unevaluated consts, so keep normalizing here if that's the case. // unevaluated consts, so keep normalizing here if that's the case.
if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
Ok(res.try_super_fold_with(self)?) res.try_super_fold_with(self)?
} else { } else {
Ok(res) res
} }
} }
_ => ty.try_super_fold_with(self), _ => ty.try_super_fold_with(self)?,
})()?; };
self.cache.insert(ty, res); self.cache.insert(ty, res);
Ok(res) Ok(res)

View file

@ -110,9 +110,18 @@ impl ProcOutput {
fn into_bytes(self) -> Vec<u8> { fn into_bytes(self) -> Vec<u8> {
match self { match self {
ProcOutput::Full { bytes, .. } => bytes, ProcOutput::Full { bytes, .. } => bytes,
ProcOutput::Abbreviated { mut head, skipped, tail } => { ProcOutput::Abbreviated { mut head, mut skipped, tail } => {
let mut tail = &*tail;
// Skip over '{' at the start of the tail, so we don't later wrongfully consider this as json.
// See <https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Weird.20CI.20failure/near/321797811>
while tail.get(0) == Some(&b'{') {
tail = &tail[1..];
skipped += 1;
}
write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap(); write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
head.extend_from_slice(&tail); head.extend_from_slice(tail);
head head
} }
} }