mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-22 02:00:00 +03:00
Auto merge of #98910 - Dylan-DPC:rollup-9x82wdg, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #97300 (Implement `FusedIterator` for `std::net::[Into]Incoming`) - #98761 (more `need_type_info` improvements) - #98811 (Interpret: AllocRange Debug impl, and use it more consistently) - #98847 (fix interpreter validity check on Box) - #98854 (clean up the borrowing in rustc_hir_pretty) - #98873 (Suggest `#[derive(Default)]` to enums with `#[default]`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -276,7 +276,7 @@ pub fn deallocate_ptr(
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let (alloc_id, offset, tag) = self.ptr_get_alloc_id(ptr)?;
|
||||
trace!("deallocating: {}", alloc_id);
|
||||
trace!("deallocating: {alloc_id:?}");
|
||||
|
||||
if offset.bytes() != 0 {
|
||||
throw_ub_format!(
|
||||
@@ -289,10 +289,10 @@ pub fn deallocate_ptr(
|
||||
// Deallocating global memory -- always an error
|
||||
return Err(match self.tcx.get_global_alloc(alloc_id) {
|
||||
Some(GlobalAlloc::Function(..)) => {
|
||||
err_ub_format!("deallocating {}, which is a function", alloc_id)
|
||||
err_ub_format!("deallocating {alloc_id:?}, which is a function")
|
||||
}
|
||||
Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
|
||||
err_ub_format!("deallocating {}, which is static memory", alloc_id)
|
||||
err_ub_format!("deallocating {alloc_id:?}, which is static memory")
|
||||
}
|
||||
None => err_ub!(PointerUseAfterFree(alloc_id)),
|
||||
}
|
||||
@@ -302,21 +302,17 @@ pub fn deallocate_ptr(
|
||||
debug!(?alloc);
|
||||
|
||||
if alloc.mutability == Mutability::Not {
|
||||
throw_ub_format!("deallocating immutable allocation {}", alloc_id);
|
||||
throw_ub_format!("deallocating immutable allocation {alloc_id:?}");
|
||||
}
|
||||
if alloc_kind != kind {
|
||||
throw_ub_format!(
|
||||
"deallocating {}, which is {} memory, using {} deallocation operation",
|
||||
alloc_id,
|
||||
alloc_kind,
|
||||
kind
|
||||
"deallocating {alloc_id:?}, which is {alloc_kind} memory, using {kind} deallocation operation"
|
||||
);
|
||||
}
|
||||
if let Some((size, align)) = old_size_and_align {
|
||||
if size != alloc.size() || align != alloc.align {
|
||||
throw_ub_format!(
|
||||
"incorrect layout on deallocation: {} has size {} and alignment {}, but gave size {} and alignment {}",
|
||||
alloc_id,
|
||||
"incorrect layout on deallocation: {alloc_id:?} has size {} and alignment {}, but gave size {} and alignment {}",
|
||||
alloc.size().bytes(),
|
||||
alloc.align.bytes(),
|
||||
size.bytes(),
|
||||
@@ -815,7 +811,7 @@ fn write_allocation_track_relocs<'tcx, Tag: Provenance, Extra>(
|
||||
continue;
|
||||
}
|
||||
|
||||
write!(fmt, "{}", id)?;
|
||||
write!(fmt, "{id:?}")?;
|
||||
match self.ecx.memory.alloc_map.get(id) {
|
||||
Some(&(kind, ref alloc)) => {
|
||||
// normal alloc
|
||||
@@ -859,25 +855,21 @@ fn write_allocation_track_relocs<'tcx, Tag: Provenance, Extra>(
|
||||
|
||||
/// Reading and writing.
|
||||
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn write_scalar(
|
||||
&mut self,
|
||||
range: AllocRange,
|
||||
val: ScalarMaybeUninit<Tag>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let range = self.range.subrange(range);
|
||||
debug!(
|
||||
"write_scalar in {} at {:#x}, size {}: {:?}",
|
||||
self.alloc_id,
|
||||
range.start.bytes(),
|
||||
range.size.bytes(),
|
||||
val
|
||||
);
|
||||
debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id);
|
||||
Ok(self
|
||||
.alloc
|
||||
.write_scalar(&self.tcx, range, val)
|
||||
.map_err(|e| e.to_interp_error(self.alloc_id))?)
|
||||
}
|
||||
|
||||
/// `offset` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn write_ptr_sized(
|
||||
&mut self,
|
||||
offset: Size,
|
||||
@@ -896,6 +888,7 @@ pub fn write_uninit(&mut self) -> InterpResult<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn read_scalar(
|
||||
&self,
|
||||
range: AllocRange,
|
||||
@@ -906,24 +899,16 @@ pub fn read_scalar(
|
||||
.alloc
|
||||
.read_scalar(&self.tcx, range, read_provenance)
|
||||
.map_err(|e| e.to_interp_error(self.alloc_id))?;
|
||||
debug!(
|
||||
"read_scalar in {} at {:#x}, size {}: {:?}",
|
||||
self.alloc_id,
|
||||
range.start.bytes(),
|
||||
range.size.bytes(),
|
||||
res
|
||||
);
|
||||
debug!("read_scalar at {:?}{range:?}: {res:?}", self.alloc_id);
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn read_integer(
|
||||
&self,
|
||||
offset: Size,
|
||||
size: Size,
|
||||
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
|
||||
self.read_scalar(alloc_range(offset, size), /*read_provenance*/ false)
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
|
||||
self.read_scalar(range, /*read_provenance*/ false)
|
||||
}
|
||||
|
||||
/// `offset` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
|
||||
self.read_scalar(
|
||||
alloc_range(offset, self.tcx.data_layout().pointer_size),
|
||||
@@ -931,6 +916,7 @@ pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit
|
||||
)
|
||||
}
|
||||
|
||||
/// `range` is relative to this allocation reference, not the base of the allocation.
|
||||
pub fn check_bytes(
|
||||
&self,
|
||||
range: AllocRange,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic};
|
||||
use rustc_middle::mir::interpret::{alloc_range, InterpResult, Pointer, PointerArithmetic};
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, COMMON_VTABLE_ENTRIES_ALIGN, COMMON_VTABLE_ENTRIES_DROPINPLACE,
|
||||
COMMON_VTABLE_ENTRIES_SIZE,
|
||||
@@ -102,18 +102,18 @@ pub fn read_size_and_align_from_vtable(
|
||||
)?
|
||||
.expect("cannot be a ZST");
|
||||
let size = vtable
|
||||
.read_integer(
|
||||
.read_integer(alloc_range(
|
||||
pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap(),
|
||||
pointer_size,
|
||||
)?
|
||||
))?
|
||||
.check_init()?;
|
||||
let size = size.to_machine_usize(self)?;
|
||||
let size = Size::from_bytes(size);
|
||||
let align = vtable
|
||||
.read_integer(
|
||||
.read_integer(alloc_range(
|
||||
pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap(),
|
||||
pointer_size,
|
||||
)?
|
||||
))?
|
||||
.check_init()?;
|
||||
let align = align.to_machine_usize(self)?;
|
||||
let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?;
|
||||
|
||||
@@ -593,16 +593,6 @@ fn try_visit_primitive(
|
||||
self.check_safe_pointer(value, "reference")?;
|
||||
Ok(true)
|
||||
}
|
||||
ty::Adt(def, ..) if def.is_box() => {
|
||||
let unique = self.ecx.operand_field(value, 0)?;
|
||||
let nonnull = self.ecx.operand_field(&unique, 0)?;
|
||||
let ptr = self.ecx.operand_field(&nonnull, 0)?;
|
||||
self.check_safe_pointer(&ptr, "box")?;
|
||||
|
||||
// Check other fields of Box
|
||||
self.walk_value(value)?;
|
||||
Ok(true)
|
||||
}
|
||||
ty::FnPtr(_sig) => {
|
||||
let value = try_validation!(
|
||||
self.ecx.read_scalar(value).and_then(|v| v.check_init()),
|
||||
@@ -813,6 +803,12 @@ fn visit_union(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_box(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
|
||||
self.check_safe_pointer(op, "box")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
|
||||
trace!("visit_value: {:?}, {:?}", *op, op.layout);
|
||||
@@ -821,8 +817,6 @@ fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
|
||||
if self.try_visit_primitive(op)? {
|
||||
return Ok(());
|
||||
}
|
||||
// Sanity check: `builtin_deref` does not know any pointers that are not primitive.
|
||||
assert!(op.layout.ty.builtin_deref(true).is_none());
|
||||
|
||||
// Special check preventing `UnsafeCell` in the inner part of constants
|
||||
if let Some(def) = op.layout.ty.ty_adt_def() {
|
||||
|
||||
@@ -151,6 +151,14 @@ fn visit_union(&mut self, _v: &Self::V, _fields: NonZeroUsize) -> InterpResult<'
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
/// Visits the given value as the pointer of a `Box`. There is nothing to recurse into.
|
||||
/// The type of `v` will be a raw pointer, but this is a field of `Box<T>` and the
|
||||
/// pointee type is the actual `T`.
|
||||
#[inline(always)]
|
||||
fn visit_box(&mut self, _v: &Self::V) -> InterpResult<'tcx>
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
/// Visits this value as an aggregate, you are getting an iterator yielding
|
||||
/// all the fields (still in an `InterpResult`, you have to do error handling yourself).
|
||||
/// Recurses into the fields.
|
||||
@@ -221,6 +229,47 @@ fn walk_value(&mut self, v: &Self::V) -> InterpResult<'tcx>
|
||||
// Slices do not need special handling here: they have `Array` field
|
||||
// placement with length 0, so we enter the `Array` case below which
|
||||
// indirectly uses the metadata to determine the actual length.
|
||||
|
||||
// However, `Box`... let's talk about `Box`.
|
||||
ty::Adt(def, ..) if def.is_box() => {
|
||||
// `Box` is a hybrid primitive-library-defined type that one the one hand is
|
||||
// a dereferenceable pointer, on the other hand has *basically arbitrary
|
||||
// user-defined layout* since the user controls the 'allocator' field. So it
|
||||
// cannot be treated like a normal pointer, since it does not fit into an
|
||||
// `Immediate`. Yeah, it is quite terrible. But many visitors want to do
|
||||
// something with "all boxed pointers", so we handle this mess for them.
|
||||
//
|
||||
// When we hit a `Box`, we do not do the usual `visit_aggregate`; instead,
|
||||
// we (a) call `visit_box` on the pointer value, and (b) recurse on the
|
||||
// allocator field. We also assert tons of things to ensure we do not miss
|
||||
// any other fields.
|
||||
|
||||
// `Box` has two fields: the pointer we care about, and the allocator.
|
||||
assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields");
|
||||
let (unique_ptr, alloc) =
|
||||
(v.project_field(self.ecx(), 0)?, v.project_field(self.ecx(), 1)?);
|
||||
// Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`...
|
||||
// (which means another 2 fields, the second of which is a `PhantomData`)
|
||||
assert_eq!(unique_ptr.layout().fields.count(), 2);
|
||||
let (nonnull_ptr, phantom) = (
|
||||
unique_ptr.project_field(self.ecx(), 0)?,
|
||||
unique_ptr.project_field(self.ecx(), 1)?,
|
||||
);
|
||||
assert!(
|
||||
phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()),
|
||||
"2nd field of `Unique` should be PhantomData but is {:?}",
|
||||
phantom.layout().ty,
|
||||
);
|
||||
// ... that contains a `NonNull`... (gladly, only a single field here)
|
||||
assert_eq!(nonnull_ptr.layout().fields.count(), 1);
|
||||
let raw_ptr = nonnull_ptr.project_field(self.ecx(), 0)?; // the actual raw ptr
|
||||
// ... whose only field finally is a raw ptr we can dereference.
|
||||
self.visit_box(&raw_ptr)?;
|
||||
|
||||
// The second `Box` field is the allocator, which we recursively check for validity
|
||||
// like in regular structs.
|
||||
self.visit_field(v, 1, &alloc)?;
|
||||
}
|
||||
_ => {},
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
#![feature(is_some_with)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ fn nested(&self, state: &mut State<'_>, nested: Nested) {
|
||||
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
|
||||
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
|
||||
Nested::Body(id) => state.print_expr(&self.body(id).value),
|
||||
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
|
||||
Nested::BodyParamPat(id, i) => state.print_pat(self.body(id).params[i].pat),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,37 +74,37 @@ pub struct State<'a> {
|
||||
impl<'a> State<'a> {
|
||||
pub fn print_node(&mut self, node: Node<'_>) {
|
||||
match node {
|
||||
Node::Param(a) => self.print_param(&a),
|
||||
Node::Item(a) => self.print_item(&a),
|
||||
Node::ForeignItem(a) => self.print_foreign_item(&a),
|
||||
Node::Param(a) => self.print_param(a),
|
||||
Node::Item(a) => self.print_item(a),
|
||||
Node::ForeignItem(a) => self.print_foreign_item(a),
|
||||
Node::TraitItem(a) => self.print_trait_item(a),
|
||||
Node::ImplItem(a) => self.print_impl_item(a),
|
||||
Node::Variant(a) => self.print_variant(&a),
|
||||
Node::AnonConst(a) => self.print_anon_const(&a),
|
||||
Node::Expr(a) => self.print_expr(&a),
|
||||
Node::Stmt(a) => self.print_stmt(&a),
|
||||
Node::PathSegment(a) => self.print_path_segment(&a),
|
||||
Node::Ty(a) => self.print_type(&a),
|
||||
Node::TypeBinding(a) => self.print_type_binding(&a),
|
||||
Node::TraitRef(a) => self.print_trait_ref(&a),
|
||||
Node::Pat(a) => self.print_pat(&a),
|
||||
Node::Arm(a) => self.print_arm(&a),
|
||||
Node::Variant(a) => self.print_variant(a),
|
||||
Node::AnonConst(a) => self.print_anon_const(a),
|
||||
Node::Expr(a) => self.print_expr(a),
|
||||
Node::Stmt(a) => self.print_stmt(a),
|
||||
Node::PathSegment(a) => self.print_path_segment(a),
|
||||
Node::Ty(a) => self.print_type(a),
|
||||
Node::TypeBinding(a) => self.print_type_binding(a),
|
||||
Node::TraitRef(a) => self.print_trait_ref(a),
|
||||
Node::Pat(a) => self.print_pat(a),
|
||||
Node::Arm(a) => self.print_arm(a),
|
||||
Node::Infer(_) => self.word("_"),
|
||||
Node::Block(a) => {
|
||||
// Containing cbox, will be closed by print-block at `}`.
|
||||
self.cbox(INDENT_UNIT);
|
||||
// Head-ibox, will be closed by print-block after `{`.
|
||||
self.ibox(0);
|
||||
self.print_block(&a)
|
||||
self.print_block(a);
|
||||
}
|
||||
Node::Lifetime(a) => self.print_lifetime(&a),
|
||||
Node::Lifetime(a) => self.print_lifetime(a),
|
||||
Node::GenericParam(_) => panic!("cannot print Node::GenericParam"),
|
||||
Node::Field(_) => panic!("cannot print Node::Field"),
|
||||
// These cases do not carry enough information in the
|
||||
// `hir_map` to reconstruct their full structure for pretty
|
||||
// printing.
|
||||
Node::Ctor(..) => panic!("cannot print isolated Ctor"),
|
||||
Node::Local(a) => self.print_local_decl(&a),
|
||||
Node::Local(a) => self.print_local_decl(a),
|
||||
Node::Crate(..) => panic!("cannot print Crate"),
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,7 @@ pub fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut g
|
||||
}
|
||||
|
||||
pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr<'_>]) {
|
||||
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
|
||||
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span);
|
||||
}
|
||||
|
||||
pub fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[ast::Attribute]) {
|
||||
@@ -287,9 +287,9 @@ pub fn print_type(&mut self, ty: &hir::Ty<'_>) {
|
||||
self.maybe_print_comment(ty.span.lo());
|
||||
self.ibox(0);
|
||||
match ty.kind {
|
||||
hir::TyKind::Slice(ref ty) => {
|
||||
hir::TyKind::Slice(ty) => {
|
||||
self.word("[");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
self.word("]");
|
||||
}
|
||||
hir::TyKind::Ptr(ref mt) => {
|
||||
@@ -304,23 +304,16 @@ pub fn print_type(&mut self, ty: &hir::Ty<'_>) {
|
||||
hir::TyKind::Never => {
|
||||
self.word("!");
|
||||
}
|
||||
hir::TyKind::Tup(ref elts) => {
|
||||
hir::TyKind::Tup(elts) => {
|
||||
self.popen();
|
||||
self.commasep(Inconsistent, &elts, |s, ty| s.print_type(&ty));
|
||||
self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty));
|
||||
if elts.len() == 1 {
|
||||
self.word(",");
|
||||
}
|
||||
self.pclose();
|
||||
}
|
||||
hir::TyKind::BareFn(ref f) => {
|
||||
self.print_ty_fn(
|
||||
f.abi,
|
||||
f.unsafety,
|
||||
&f.decl,
|
||||
None,
|
||||
&f.generic_params,
|
||||
f.param_names,
|
||||
);
|
||||
hir::TyKind::BareFn(f) => {
|
||||
self.print_ty_fn(f.abi, f.unsafety, f.decl, None, f.generic_params, f.param_names);
|
||||
}
|
||||
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
||||
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
||||
@@ -344,9 +337,9 @@ pub fn print_type(&mut self, ty: &hir::Ty<'_>) {
|
||||
self.print_lifetime(lifetime);
|
||||
}
|
||||
}
|
||||
hir::TyKind::Array(ref ty, ref length) => {
|
||||
hir::TyKind::Array(ty, ref length) => {
|
||||
self.word("[");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
self.word("; ");
|
||||
self.print_array_length(length);
|
||||
self.word("]");
|
||||
@@ -373,7 +366,7 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
|
||||
self.maybe_print_comment(item.span.lo());
|
||||
self.print_outer_attributes(self.attrs(item.hir_id()));
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => {
|
||||
hir::ForeignItemKind::Fn(decl, arg_names, generics) => {
|
||||
self.head("");
|
||||
self.print_fn(
|
||||
decl,
|
||||
@@ -392,14 +385,14 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
|
||||
self.word(";");
|
||||
self.end() // end the outer fn box
|
||||
}
|
||||
hir::ForeignItemKind::Static(ref t, m) => {
|
||||
hir::ForeignItemKind::Static(t, m) => {
|
||||
self.head("static");
|
||||
if m == hir::Mutability::Mut {
|
||||
self.word_space("mut");
|
||||
}
|
||||
self.print_ident(item.ident);
|
||||
self.word_space(":");
|
||||
self.print_type(&t);
|
||||
self.print_type(t);
|
||||
self.word(";");
|
||||
self.end(); // end the head-ibox
|
||||
self.end() // end the outer cbox
|
||||
@@ -442,7 +435,7 @@ fn print_associated_type(
|
||||
) {
|
||||
self.word_space("type");
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
if let Some(bounds) = bounds {
|
||||
self.print_bounds(":", bounds);
|
||||
}
|
||||
@@ -463,7 +456,7 @@ fn print_item_type(
|
||||
) {
|
||||
self.head("type");
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
self.print_where_clause(generics);
|
||||
@@ -494,7 +487,7 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
}
|
||||
hir::ItemKind::Use(ref path, kind) => {
|
||||
hir::ItemKind::Use(path, kind) => {
|
||||
self.head("use");
|
||||
self.print_path(path, false);
|
||||
|
||||
@@ -513,14 +506,14 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
}
|
||||
hir::ItemKind::Static(ref ty, m, expr) => {
|
||||
hir::ItemKind::Static(ty, m, expr) => {
|
||||
self.head("static");
|
||||
if m == hir::Mutability::Mut {
|
||||
self.word_space("mut");
|
||||
}
|
||||
self.print_ident(item.ident);
|
||||
self.word_space(":");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
self.space();
|
||||
self.end(); // end the head-ibox
|
||||
|
||||
@@ -529,11 +522,11 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
hir::ItemKind::Const(ref ty, expr) => {
|
||||
hir::ItemKind::Const(ty, expr) => {
|
||||
self.head("const");
|
||||
self.print_ident(item.ident);
|
||||
self.word_space(":");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
self.space();
|
||||
self.end(); // end the head-ibox
|
||||
|
||||
@@ -542,10 +535,10 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
hir::ItemKind::Fn(ref sig, ref param_names, body) => {
|
||||
hir::ItemKind::Fn(ref sig, param_names, body) => {
|
||||
self.head("");
|
||||
self.print_fn(
|
||||
&sig.decl,
|
||||
sig.decl,
|
||||
sig.header,
|
||||
Some(item.ident.name),
|
||||
param_names,
|
||||
@@ -578,22 +571,22 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
}
|
||||
self.bclose(item.span);
|
||||
}
|
||||
hir::ItemKind::GlobalAsm(ref asm) => {
|
||||
hir::ItemKind::GlobalAsm(asm) => {
|
||||
self.head("global_asm!");
|
||||
self.print_inline_asm(asm);
|
||||
self.end()
|
||||
}
|
||||
hir::ItemKind::TyAlias(ref ty, ref generics) => {
|
||||
self.print_item_type(item, &generics, |state| {
|
||||
hir::ItemKind::TyAlias(ty, generics) => {
|
||||
self.print_item_type(item, generics, |state| {
|
||||
state.word_space("=");
|
||||
state.print_type(&ty);
|
||||
state.print_type(ty);
|
||||
});
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(ref opaque_ty) => {
|
||||
self.print_item_type(item, &opaque_ty.generics, |state| {
|
||||
self.print_item_type(item, opaque_ty.generics, |state| {
|
||||
let mut real_bounds = Vec::with_capacity(opaque_ty.bounds.len());
|
||||
for b in opaque_ty.bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||
for b in opaque_ty.bounds {
|
||||
if let GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = b {
|
||||
state.space();
|
||||
state.word_space("for ?");
|
||||
state.print_trait_ref(&ptr.trait_ref);
|
||||
@@ -604,39 +597,39 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
state.print_bounds("= impl", real_bounds);
|
||||
});
|
||||
}
|
||||
hir::ItemKind::Enum(ref enum_definition, ref params) => {
|
||||
hir::ItemKind::Enum(ref enum_definition, params) => {
|
||||
self.print_enum_def(enum_definition, params, item.ident.name, item.span);
|
||||
}
|
||||
hir::ItemKind::Struct(ref struct_def, ref generics) => {
|
||||
hir::ItemKind::Struct(ref struct_def, generics) => {
|
||||
self.head("struct");
|
||||
self.print_struct(struct_def, generics, item.ident.name, item.span, true);
|
||||
}
|
||||
hir::ItemKind::Union(ref struct_def, ref generics) => {
|
||||
hir::ItemKind::Union(ref struct_def, generics) => {
|
||||
self.head("union");
|
||||
self.print_struct(struct_def, generics, item.ident.name, item.span, true);
|
||||
}
|
||||
hir::ItemKind::Impl(hir::Impl {
|
||||
hir::ItemKind::Impl(&hir::Impl {
|
||||
unsafety,
|
||||
polarity,
|
||||
defaultness,
|
||||
constness,
|
||||
defaultness_span: _,
|
||||
ref generics,
|
||||
generics,
|
||||
ref of_trait,
|
||||
ref self_ty,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
self.head("");
|
||||
self.print_defaultness(*defaultness);
|
||||
self.print_unsafety(*unsafety);
|
||||
self.print_defaultness(defaultness);
|
||||
self.print_unsafety(unsafety);
|
||||
self.word_nbsp("impl");
|
||||
|
||||
if !generics.params.is_empty() {
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
self.space();
|
||||
}
|
||||
|
||||
if *constness == hir::Constness::Const {
|
||||
if constness == hir::Constness::Const {
|
||||
self.word_nbsp("const");
|
||||
}
|
||||
|
||||
@@ -644,33 +637,33 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word("!");
|
||||
}
|
||||
|
||||
if let Some(ref t) = of_trait {
|
||||
if let Some(t) = of_trait {
|
||||
self.print_trait_ref(t);
|
||||
self.space();
|
||||
self.word_space("for");
|
||||
}
|
||||
|
||||
self.print_type(&self_ty);
|
||||
self.print_type(self_ty);
|
||||
self.print_where_clause(generics);
|
||||
|
||||
self.space();
|
||||
self.bopen();
|
||||
self.print_inner_attributes(attrs);
|
||||
for impl_item in *items {
|
||||
for impl_item in items {
|
||||
self.ann.nested(self, Nested::ImplItem(impl_item.id));
|
||||
}
|
||||
self.bclose(item.span);
|
||||
}
|
||||
hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, trait_items) => {
|
||||
hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, trait_items) => {
|
||||
self.head("");
|
||||
self.print_is_auto(is_auto);
|
||||
self.print_unsafety(unsafety);
|
||||
self.word_nbsp("trait");
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||
for b in bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||
for b in bounds {
|
||||
if let GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = b {
|
||||
self.space();
|
||||
self.word_space("for ?");
|
||||
self.print_trait_ref(&ptr.trait_ref);
|
||||
@@ -687,14 +680,14 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
}
|
||||
self.bclose(item.span);
|
||||
}
|
||||
hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||
hir::ItemKind::TraitAlias(generics, bounds) => {
|
||||
self.head("trait");
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||
// FIXME(durka) this seems to be some quite outdated syntax
|
||||
for b in bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||
for b in bounds {
|
||||
if let GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = b {
|
||||
self.space();
|
||||
self.word_space("for ?");
|
||||
self.print_trait_ref(&ptr.trait_ref);
|
||||
@@ -714,7 +707,7 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
}
|
||||
|
||||
pub fn print_trait_ref(&mut self, t: &hir::TraitRef<'_>) {
|
||||
self.print_path(&t.path, false)
|
||||
self.print_path(t.path, false);
|
||||
}
|
||||
|
||||
fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) {
|
||||
@@ -726,8 +719,8 @@ fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_
|
||||
}
|
||||
|
||||
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) {
|
||||
self.print_formal_generic_params(&t.bound_generic_params);
|
||||
self.print_trait_ref(&t.trait_ref)
|
||||
self.print_formal_generic_params(t.bound_generic_params);
|
||||
self.print_trait_ref(&t.trait_ref);
|
||||
}
|
||||
|
||||
pub fn print_enum_def(
|
||||
@@ -739,10 +732,10 @@ pub fn print_enum_def(
|
||||
) {
|
||||
self.head("enum");
|
||||
self.print_name(name);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
self.print_where_clause(generics);
|
||||
self.space();
|
||||
self.print_variants(&enum_definition.variants, span)
|
||||
self.print_variants(enum_definition.variants, span);
|
||||
}
|
||||
|
||||
pub fn print_variants(&mut self, variants: &[hir::Variant<'_>], span: rustc_span::Span) {
|
||||
@@ -776,7 +769,7 @@ pub fn print_struct(
|
||||
print_finalizer: bool,
|
||||
) {
|
||||
self.print_name(name);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
match struct_def {
|
||||
hir::VariantData::Tuple(..) | hir::VariantData::Unit(..) => {
|
||||
if let hir::VariantData::Tuple(..) = struct_def {
|
||||
@@ -784,7 +777,7 @@ pub fn print_struct(
|
||||
self.commasep(Inconsistent, struct_def.fields(), |s, field| {
|
||||
s.maybe_print_comment(field.span.lo());
|
||||
s.print_outer_attributes(s.attrs(field.hir_id));
|
||||
s.print_type(&field.ty)
|
||||
s.print_type(field.ty);
|
||||
});
|
||||
self.pclose();
|
||||
}
|
||||
@@ -807,7 +800,7 @@ pub fn print_struct(
|
||||
self.print_outer_attributes(self.attrs(field.hir_id));
|
||||
self.print_ident(field.ident);
|
||||
self.word_nbsp(":");
|
||||
self.print_type(&field.ty);
|
||||
self.print_type(field.ty);
|
||||
self.word(",");
|
||||
}
|
||||
|
||||
@@ -819,7 +812,7 @@ pub fn print_struct(
|
||||
pub fn print_variant(&mut self, v: &hir::Variant<'_>) {
|
||||
self.head("");
|
||||
let generics = hir::Generics::empty();
|
||||
self.print_struct(&v.data, &generics, v.ident.name, v.span, false);
|
||||
self.print_struct(&v.data, generics, v.ident.name, v.span, false);
|
||||
if let Some(ref d) = v.disr_expr {
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
@@ -834,7 +827,7 @@ pub fn print_method_sig(
|
||||
arg_names: &[Ident],
|
||||
body_id: Option<hir::BodyId>,
|
||||
) {
|
||||
self.print_fn(&m.decl, m.header, Some(ident.name), generics, arg_names, body_id)
|
||||
self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_names, body_id);
|
||||
}
|
||||
|
||||
pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
|
||||
@@ -843,28 +836,23 @@ pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
|
||||
self.maybe_print_comment(ti.span.lo());
|
||||
self.print_outer_attributes(self.attrs(ti.hir_id()));
|
||||
match ti.kind {
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
self.print_associated_const(ti.ident, &ty, default);
|
||||
hir::TraitItemKind::Const(ty, default) => {
|
||||
self.print_associated_const(ti.ident, ty, default);
|
||||
}
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(ref arg_names)) => {
|
||||
self.print_method_sig(ti.ident, sig, &ti.generics, arg_names, None);
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_names)) => {
|
||||
self.print_method_sig(ti.ident, sig, ti.generics, arg_names, None);
|
||||
self.word(";");
|
||||
}
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
|
||||
self.head("");
|
||||
self.print_method_sig(ti.ident, sig, &ti.generics, &[], Some(body));
|
||||
self.print_method_sig(ti.ident, sig, ti.generics, &[], Some(body));
|
||||
self.nbsp();
|
||||
self.end(); // need to close a box
|
||||
self.end(); // need to close a box
|
||||
self.ann.nested(self, Nested::Body(body));
|
||||
}
|
||||
hir::TraitItemKind::Type(ref bounds, ref default) => {
|
||||
self.print_associated_type(
|
||||
ti.ident,
|
||||
&ti.generics,
|
||||
Some(bounds),
|
||||
default.as_ref().map(|ty| &**ty),
|
||||
);
|
||||
hir::TraitItemKind::Type(bounds, default) => {
|
||||
self.print_associated_type(ti.ident, ti.generics, Some(bounds), default);
|
||||
}
|
||||
}
|
||||
self.ann.post(self, AnnNode::SubItem(ti.hir_id()))
|
||||
@@ -877,19 +865,19 @@ pub fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) {
|
||||
self.print_outer_attributes(self.attrs(ii.hir_id()));
|
||||
|
||||
match ii.kind {
|
||||
hir::ImplItemKind::Const(ref ty, expr) => {
|
||||
self.print_associated_const(ii.ident, &ty, Some(expr));
|
||||
hir::ImplItemKind::Const(ty, expr) => {
|
||||
self.print_associated_const(ii.ident, ty, Some(expr));
|
||||
}
|
||||
hir::ImplItemKind::Fn(ref sig, body) => {
|
||||
self.head("");
|
||||
self.print_method_sig(ii.ident, sig, &ii.generics, &[], Some(body));
|
||||
self.print_method_sig(ii.ident, sig, ii.generics, &[], Some(body));
|
||||
self.nbsp();
|
||||
self.end(); // need to close a box
|
||||
self.end(); // need to close a box
|
||||
self.ann.nested(self, Nested::Body(body));
|
||||
}
|
||||
hir::ImplItemKind::TyAlias(ref ty) => {
|
||||
self.print_associated_type(ii.ident, &ii.generics, None, Some(ty));
|
||||
hir::ImplItemKind::TyAlias(ty) => {
|
||||
self.print_associated_type(ii.ident, ii.generics, None, Some(ty));
|
||||
}
|
||||
}
|
||||
self.ann.post(self, AnnNode::SubItem(ii.hir_id()))
|
||||
@@ -904,10 +892,10 @@ pub fn print_local(&mut self, init: Option<&hir::Expr<'_>>, decl: impl Fn(&mut S
|
||||
decl(self);
|
||||
self.end();
|
||||
|
||||
if let Some(ref init) = init {
|
||||
if let Some(init) = init {
|
||||
self.nbsp();
|
||||
self.word_space("=");
|
||||
self.print_expr(&init);
|
||||
self.print_expr(init);
|
||||
}
|
||||
self.end()
|
||||
}
|
||||
@@ -915,17 +903,17 @@ pub fn print_local(&mut self, init: Option<&hir::Expr<'_>>, decl: impl Fn(&mut S
|
||||
pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
|
||||
self.maybe_print_comment(st.span.lo());
|
||||
match st.kind {
|
||||
hir::StmtKind::Local(ref loc) => {
|
||||
self.print_local(loc.init, |this| this.print_local_decl(&loc));
|
||||
hir::StmtKind::Local(loc) => {
|
||||
self.print_local(loc.init, |this| this.print_local_decl(loc));
|
||||
}
|
||||
hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
|
||||
hir::StmtKind::Expr(ref expr) => {
|
||||
hir::StmtKind::Expr(expr) => {
|
||||
self.space_if_not_bol();
|
||||
self.print_expr(&expr);
|
||||
self.print_expr(expr);
|
||||
}
|
||||
hir::StmtKind::Semi(ref expr) => {
|
||||
hir::StmtKind::Semi(expr) => {
|
||||
self.space_if_not_bol();
|
||||
self.print_expr(&expr);
|
||||
self.print_expr(expr);
|
||||
self.word(";");
|
||||
}
|
||||
}
|
||||
@@ -966,9 +954,9 @@ pub fn print_block_maybe_unclosed(
|
||||
for st in blk.stmts {
|
||||
self.print_stmt(st);
|
||||
}
|
||||
if let Some(ref expr) = blk.expr {
|
||||
if let Some(expr) = blk.expr {
|
||||
self.space_if_not_bol();
|
||||
self.print_expr(&expr);
|
||||
self.print_expr(expr);
|
||||
self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
|
||||
}
|
||||
self.bclose_maybe_open(blk.span, close_box);
|
||||
@@ -979,21 +967,21 @@ fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
|
||||
if let Some(els_inner) = els {
|
||||
match els_inner.kind {
|
||||
// Another `else if` block.
|
||||
hir::ExprKind::If(ref i, ref then, ref e) => {
|
||||
hir::ExprKind::If(i, then, e) => {
|
||||
self.cbox(INDENT_UNIT - 1);
|
||||
self.ibox(0);
|
||||
self.word(" else if ");
|
||||
self.print_expr_as_cond(&i);
|
||||
self.print_expr_as_cond(i);
|
||||
self.space();
|
||||
self.print_expr(&then);
|
||||
self.print_else(e.as_ref().map(|e| &**e))
|
||||
self.print_expr(then);
|
||||
self.print_else(e);
|
||||
}
|
||||
// Final `else` block.
|
||||
hir::ExprKind::Block(ref b, _) => {
|
||||
hir::ExprKind::Block(b, _) => {
|
||||
self.cbox(INDENT_UNIT - 1);
|
||||
self.ibox(0);
|
||||
self.word(" else ");
|
||||
self.print_block(&b)
|
||||
self.print_block(b);
|
||||
}
|
||||
// Constraints would be great here!
|
||||
_ => {
|
||||
@@ -1048,7 +1036,7 @@ fn print_expr_cond_paren(&mut self, expr: &hir::Expr<'_>, needs_par: bool) {
|
||||
if needs_par {
|
||||
self.popen();
|
||||
}
|
||||
if let hir::ExprKind::DropTemps(ref actual_expr) = expr.kind {
|
||||
if let hir::ExprKind::DropTemps(actual_expr) = expr.kind {
|
||||
self.print_expr(actual_expr);
|
||||
} else {
|
||||
self.print_expr(expr);
|
||||
@@ -1114,7 +1102,7 @@ fn print_expr_struct(
|
||||
&mut self,
|
||||
qpath: &hir::QPath<'_>,
|
||||
fields: &[hir::ExprField<'_>],
|
||||
wth: &Option<&hir::Expr<'_>>,
|
||||
wth: Option<&hir::Expr<'_>>,
|
||||
) {
|
||||
self.print_qpath(qpath, true);
|
||||
self.word("{");
|
||||
@@ -1127,28 +1115,24 @@ fn print_expr_struct(
|
||||
s.print_ident(field.ident);
|
||||
s.word_space(":");
|
||||
}
|
||||
s.print_expr(&field.expr);
|
||||
s.print_expr(field.expr);
|
||||
s.end()
|
||||
},
|
||||
|f| f.span,
|
||||
);
|
||||
match *wth {
|
||||
Some(ref expr) => {
|
||||
self.ibox(INDENT_UNIT);
|
||||
if !fields.is_empty() {
|
||||
self.word(",");
|
||||
self.space();
|
||||
}
|
||||
self.word("..");
|
||||
self.print_expr(&expr);
|
||||
self.end();
|
||||
}
|
||||
_ => {
|
||||
if !fields.is_empty() {
|
||||
self.word(",")
|
||||
}
|
||||
if let Some(expr) = wth {
|
||||
self.ibox(INDENT_UNIT);
|
||||
if !fields.is_empty() {
|
||||
self.word(",");
|
||||
self.space();
|
||||
}
|
||||
self.word("..");
|
||||
self.print_expr(expr);
|
||||
self.end();
|
||||
} else if !fields.is_empty() {
|
||||
self.word(",");
|
||||
}
|
||||
|
||||
self.word("}");
|
||||
}
|
||||
|
||||
@@ -1249,18 +1233,17 @@ enum AsmArg<'a> {
|
||||
Options(ast::InlineAsmOptions),
|
||||
}
|
||||
|
||||
let mut args =
|
||||
vec![AsmArg::Template(ast::InlineAsmTemplatePiece::to_string(&asm.template))];
|
||||
let mut args = vec![AsmArg::Template(ast::InlineAsmTemplatePiece::to_string(asm.template))];
|
||||
args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o)));
|
||||
if !asm.options.is_empty() {
|
||||
args.push(AsmArg::Options(asm.options));
|
||||
}
|
||||
|
||||
self.popen();
|
||||
self.commasep(Consistent, &args, |s, arg| match arg {
|
||||
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
|
||||
AsmArg::Operand(op) => match op {
|
||||
hir::InlineAsmOperand::In { reg, expr } => {
|
||||
self.commasep(Consistent, &args, |s, arg| match *arg {
|
||||
AsmArg::Template(ref template) => s.print_string(template, ast::StrStyle::Cooked),
|
||||
AsmArg::Operand(op) => match *op {
|
||||
hir::InlineAsmOperand::In { reg, ref expr } => {
|
||||
s.word("in");
|
||||
s.popen();
|
||||
s.word(format!("{}", reg));
|
||||
@@ -1268,8 +1251,8 @@ enum AsmArg<'a> {
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
hir::InlineAsmOperand::Out { reg, late, expr } => {
|
||||
s.word(if *late { "lateout" } else { "out" });
|
||||
hir::InlineAsmOperand::Out { reg, late, ref expr } => {
|
||||
s.word(if late { "lateout" } else { "out" });
|
||||
s.popen();
|
||||
s.word(format!("{}", reg));
|
||||
s.pclose();
|
||||
@@ -1279,16 +1262,16 @@ enum AsmArg<'a> {
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
hir::InlineAsmOperand::InOut { reg, late, expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
hir::InlineAsmOperand::InOut { reg, late, ref expr } => {
|
||||
s.word(if late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
s.word(format!("{}", reg));
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
hir::InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
|
||||
s.word(if late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
s.word(format!("{}", reg));
|
||||
s.pclose();
|
||||
@@ -1301,17 +1284,17 @@ enum AsmArg<'a> {
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
hir::InlineAsmOperand::Const { anon_const } => {
|
||||
hir::InlineAsmOperand::Const { ref anon_const } => {
|
||||
s.word("const");
|
||||
s.space();
|
||||
s.print_anon_const(anon_const);
|
||||
}
|
||||
hir::InlineAsmOperand::SymFn { anon_const } => {
|
||||
hir::InlineAsmOperand::SymFn { ref anon_const } => {
|
||||
s.word("sym_fn");
|
||||
s.space();
|
||||
s.print_anon_const(anon_const);
|
||||
}
|
||||
hir::InlineAsmOperand::SymStatic { path, def_id: _ } => {
|
||||
hir::InlineAsmOperand::SymStatic { ref path, def_id: _ } => {
|
||||
s.word("sym_static");
|
||||
s.space();
|
||||
s.print_qpath(path, true);
|
||||
@@ -1363,57 +1346,57 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
self.ibox(INDENT_UNIT);
|
||||
self.ann.pre(self, AnnNode::Expr(expr));
|
||||
match expr.kind {
|
||||
hir::ExprKind::Box(ref expr) => {
|
||||
hir::ExprKind::Box(expr) => {
|
||||
self.word_space("box");
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
|
||||
}
|
||||
hir::ExprKind::Array(ref exprs) => {
|
||||
hir::ExprKind::Array(exprs) => {
|
||||
self.print_expr_vec(exprs);
|
||||
}
|
||||
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||
self.print_expr_anon_const(anon_const);
|
||||
}
|
||||
hir::ExprKind::Repeat(ref element, ref count) => {
|
||||
self.print_expr_repeat(&element, count);
|
||||
hir::ExprKind::Repeat(element, ref count) => {
|
||||
self.print_expr_repeat(element, count);
|
||||
}
|
||||
hir::ExprKind::Struct(ref qpath, fields, ref wth) => {
|
||||
hir::ExprKind::Struct(qpath, fields, wth) => {
|
||||
self.print_expr_struct(qpath, fields, wth);
|
||||
}
|
||||
hir::ExprKind::Tup(ref exprs) => {
|
||||
hir::ExprKind::Tup(exprs) => {
|
||||
self.print_expr_tup(exprs);
|
||||
}
|
||||
hir::ExprKind::Call(ref func, ref args) => {
|
||||
self.print_expr_call(&func, args);
|
||||
hir::ExprKind::Call(func, args) => {
|
||||
self.print_expr_call(func, args);
|
||||
}
|
||||
hir::ExprKind::MethodCall(ref segment, ref args, _) => {
|
||||
hir::ExprKind::MethodCall(segment, args, _) => {
|
||||
self.print_expr_method_call(segment, args);
|
||||
}
|
||||
hir::ExprKind::Binary(op, ref lhs, ref rhs) => {
|
||||
self.print_expr_binary(op, &lhs, &rhs);
|
||||
hir::ExprKind::Binary(op, lhs, rhs) => {
|
||||
self.print_expr_binary(op, lhs, rhs);
|
||||
}
|
||||
hir::ExprKind::Unary(op, ref expr) => {
|
||||
self.print_expr_unary(op, &expr);
|
||||
hir::ExprKind::Unary(op, expr) => {
|
||||
self.print_expr_unary(op, expr);
|
||||
}
|
||||
hir::ExprKind::AddrOf(k, m, ref expr) => {
|
||||
self.print_expr_addr_of(k, m, &expr);
|
||||
hir::ExprKind::AddrOf(k, m, expr) => {
|
||||
self.print_expr_addr_of(k, m, expr);
|
||||
}
|
||||
hir::ExprKind::Lit(ref lit) => {
|
||||
self.print_literal(&lit);
|
||||
self.print_literal(lit);
|
||||
}
|
||||
hir::ExprKind::Cast(ref expr, ref ty) => {
|
||||
hir::ExprKind::Cast(expr, ty) => {
|
||||
let prec = AssocOp::As.precedence() as i8;
|
||||
self.print_expr_maybe_paren(&expr, prec);
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.space();
|
||||
self.word_space("as");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
}
|
||||
hir::ExprKind::Type(ref expr, ref ty) => {
|
||||
hir::ExprKind::Type(expr, ty) => {
|
||||
let prec = AssocOp::Colon.precedence() as i8;
|
||||
self.print_expr_maybe_paren(&expr, prec);
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.word_space(":");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
}
|
||||
hir::ExprKind::DropTemps(ref init) => {
|
||||
hir::ExprKind::DropTemps(init) => {
|
||||
// Print `{`:
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.ibox(0);
|
||||
@@ -1431,25 +1414,25 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
// Print `}`:
|
||||
self.bclose_maybe_open(expr.span, true);
|
||||
}
|
||||
hir::ExprKind::Let(hir::Let { pat, ty, init, .. }) => {
|
||||
self.print_let(pat, *ty, init);
|
||||
hir::ExprKind::Let(&hir::Let { pat, ty, init, .. }) => {
|
||||
self.print_let(pat, ty, init);
|
||||
}
|
||||
hir::ExprKind::If(ref test, ref blk, ref elseopt) => {
|
||||
self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e));
|
||||
hir::ExprKind::If(test, blk, elseopt) => {
|
||||
self.print_if(test, blk, elseopt);
|
||||
}
|
||||
hir::ExprKind::Loop(ref blk, opt_label, _, _) => {
|
||||
hir::ExprKind::Loop(blk, opt_label, _, _) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
}
|
||||
self.head("loop");
|
||||
self.print_block(&blk);
|
||||
self.print_block(blk);
|
||||
}
|
||||
hir::ExprKind::Match(ref expr, arms, _) => {
|
||||
hir::ExprKind::Match(expr, arms, _) => {
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.ibox(INDENT_UNIT);
|
||||
self.word_nbsp("match");
|
||||
self.print_expr_as_cond(&expr);
|
||||
self.print_expr_as_cond(expr);
|
||||
self.space();
|
||||
self.bopen();
|
||||
for arm in arms {
|
||||
@@ -1460,7 +1443,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
hir::ExprKind::Closure {
|
||||
capture_clause,
|
||||
bound_generic_params,
|
||||
ref fn_decl,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: _,
|
||||
movability: _,
|
||||
@@ -1468,7 +1451,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
self.print_formal_generic_params(bound_generic_params);
|
||||
self.print_capture_clause(capture_clause);
|
||||
|
||||
self.print_closure_params(&fn_decl, body);
|
||||
self.print_closure_params(fn_decl, body);
|
||||
self.space();
|
||||
|
||||
// This is a bare expression.
|
||||
@@ -1480,7 +1463,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
// empty box to satisfy the close.
|
||||
self.ibox(0);
|
||||
}
|
||||
hir::ExprKind::Block(ref blk, opt_label) => {
|
||||
hir::ExprKind::Block(blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@@ -1489,42 +1472,42 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
self.cbox(INDENT_UNIT);
|
||||
// head-box, will be closed by print-block after `{`
|
||||
self.ibox(0);
|
||||
self.print_block(&blk);
|
||||
self.print_block(blk);
|
||||
}
|
||||
hir::ExprKind::Assign(ref lhs, ref rhs, _) => {
|
||||
hir::ExprKind::Assign(lhs, rhs, _) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_maybe_paren(&lhs, prec + 1);
|
||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_expr_maybe_paren(&rhs, prec);
|
||||
self.print_expr_maybe_paren(rhs, prec);
|
||||
}
|
||||
hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
||||
hir::ExprKind::AssignOp(op, lhs, rhs) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_maybe_paren(&lhs, prec + 1);
|
||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||
self.space();
|
||||
self.word(op.node.as_str());
|
||||
self.word_space("=");
|
||||
self.print_expr_maybe_paren(&rhs, prec);
|
||||
self.print_expr_maybe_paren(rhs, prec);
|
||||
}
|
||||
hir::ExprKind::Field(ref expr, ident) => {
|
||||
hir::ExprKind::Field(expr, ident) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word(".");
|
||||
self.print_ident(ident);
|
||||
}
|
||||
hir::ExprKind::Index(ref expr, ref index) => {
|
||||
self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX);
|
||||
hir::ExprKind::Index(expr, index) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(&index);
|
||||
self.print_expr(index);
|
||||
self.word("]");
|
||||
}
|
||||
hir::ExprKind::Path(ref qpath) => self.print_qpath(qpath, true),
|
||||
hir::ExprKind::Break(destination, ref opt_expr) => {
|
||||
hir::ExprKind::Break(destination, opt_expr) => {
|
||||
self.word("break");
|
||||
if let Some(label) = destination.label {
|
||||
self.space();
|
||||
self.print_ident(label.ident);
|
||||
}
|
||||
if let Some(ref expr) = *opt_expr {
|
||||
if let Some(expr) = opt_expr {
|
||||
self.space();
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
@@ -1536,20 +1519,20 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
self.print_ident(label.ident);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Ret(ref result) => {
|
||||
hir::ExprKind::Ret(result) => {
|
||||
self.word("return");
|
||||
if let Some(ref expr) = *result {
|
||||
if let Some(expr) = result {
|
||||
self.word(" ");
|
||||
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::InlineAsm(ref asm) => {
|
||||
hir::ExprKind::InlineAsm(asm) => {
|
||||
self.word("asm!");
|
||||
self.print_inline_asm(asm);
|
||||
}
|
||||
hir::ExprKind::Yield(ref expr, _) => {
|
||||
hir::ExprKind::Yield(expr, _) => {
|
||||
self.word_space("yield");
|
||||
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
hir::ExprKind::Err => {
|
||||
self.popen();
|
||||
@@ -1562,10 +1545,10 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
}
|
||||
|
||||
pub fn print_local_decl(&mut self, loc: &hir::Local<'_>) {
|
||||
self.print_pat(&loc.pat);
|
||||
if let Some(ref ty) = loc.ty {
|
||||
self.print_pat(loc.pat);
|
||||
if let Some(ty) = loc.ty {
|
||||
self.word_space(":");
|
||||
self.print_type(&ty);
|
||||
self.print_type(ty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1596,8 +1579,8 @@ pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) {
|
||||
|
||||
pub fn print_qpath(&mut self, qpath: &hir::QPath<'_>, colons_before_params: bool) {
|
||||
match *qpath {
|
||||
hir::QPath::Resolved(None, ref path) => self.print_path(path, colons_before_params),
|
||||
hir::QPath::Resolved(Some(ref qself), ref path) => {
|
||||
hir::QPath::Resolved(None, path) => self.print_path(path, colons_before_params),
|
||||
hir::QPath::Resolved(Some(qself), path) => {
|
||||
self.word("<");
|
||||
self.print_type(qself);
|
||||
self.space();
|
||||
@@ -1627,11 +1610,11 @@ pub fn print_qpath(&mut self, qpath: &hir::QPath<'_>, colons_before_params: bool
|
||||
colons_before_params,
|
||||
)
|
||||
}
|
||||
hir::QPath::TypeRelative(ref qself, ref item_segment) => {
|
||||
hir::QPath::TypeRelative(qself, item_segment) => {
|
||||
// If we've got a compound-qualified-path, let's push an additional pair of angle
|
||||
// brackets, so that we pretty-print `<<A::B>::C>` as `<A::B>::C`, instead of just
|
||||
// `A::B::C` (since the latter could be ambiguous to the user)
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, _)) = &qself.kind {
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, _)) = qself.kind {
|
||||
self.print_type(qself);
|
||||
} else {
|
||||
self.word("<");
|
||||
@@ -1663,7 +1646,7 @@ fn print_generic_args(
|
||||
) {
|
||||
if generic_args.parenthesized {
|
||||
self.word("(");
|
||||
self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty));
|
||||
self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty));
|
||||
self.word(")");
|
||||
|
||||
self.space_if_not_bol();
|
||||
@@ -1694,7 +1677,7 @@ fn print_generic_args(
|
||||
start_or_comma(self);
|
||||
self.commasep(
|
||||
Inconsistent,
|
||||
&generic_args.args,
|
||||
generic_args.args,
|
||||
|s, generic_arg| match generic_arg {
|
||||
GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
|
||||
GenericArg::Lifetime(_) => {}
|
||||
@@ -1712,7 +1695,7 @@ fn print_generic_args(
|
||||
self.word("..");
|
||||
}
|
||||
|
||||
for binding in generic_args.bindings.iter() {
|
||||
for binding in generic_args.bindings {
|
||||
start_or_comma(self);
|
||||
self.print_type_binding(binding);
|
||||
}
|
||||
@@ -1731,7 +1714,7 @@ pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
|
||||
hir::TypeBindingKind::Equality { ref term } => {
|
||||
self.word_space("=");
|
||||
match term {
|
||||
Term::Ty(ref ty) => self.print_type(ty),
|
||||
Term::Ty(ty) => self.print_type(ty),
|
||||
Term::Const(ref c) => self.print_anon_const(c),
|
||||
}
|
||||
}
|
||||
@@ -1748,7 +1731,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
// is that it doesn't matter
|
||||
match pat.kind {
|
||||
PatKind::Wild => self.word("_"),
|
||||
PatKind::Binding(binding_mode, _, ident, ref sub) => {
|
||||
PatKind::Binding(binding_mode, _, ident, sub) => {
|
||||
match binding_mode {
|
||||
hir::BindingAnnotation::Ref => {
|
||||
self.word_nbsp("ref");
|
||||
@@ -1764,33 +1747,33 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
}
|
||||
}
|
||||
self.print_ident(ident);
|
||||
if let Some(ref p) = *sub {
|
||||
if let Some(p) = sub {
|
||||
self.word("@");
|
||||
self.print_pat(&p);
|
||||
self.print_pat(p);
|
||||
}
|
||||
}
|
||||
PatKind::TupleStruct(ref qpath, ref elts, ddpos) => {
|
||||
PatKind::TupleStruct(ref qpath, elts, ddpos) => {
|
||||
self.print_qpath(qpath, true);
|
||||
self.popen();
|
||||
if let Some(ddpos) = ddpos {
|
||||
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
|
||||
if ddpos != 0 {
|
||||
self.word_space(",");
|
||||
}
|
||||
self.word("..");
|
||||
if ddpos != elts.len() {
|
||||
self.word(",");
|
||||
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p));
|
||||
}
|
||||
} else {
|
||||
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
|
||||
}
|
||||
self.pclose();
|
||||
}
|
||||
PatKind::Path(ref qpath) => {
|
||||
self.print_qpath(qpath, true);
|
||||
}
|
||||
PatKind::Struct(ref qpath, ref fields, etc) => {
|
||||
PatKind::Struct(ref qpath, fields, etc) => {
|
||||
self.print_qpath(qpath, true);
|
||||
self.nbsp();
|
||||
self.word("{");
|
||||
@@ -1800,14 +1783,14 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
}
|
||||
self.commasep_cmnt(
|
||||
Consistent,
|
||||
&fields,
|
||||
fields,
|
||||
|s, f| {
|
||||
s.cbox(INDENT_UNIT);
|
||||
if !f.is_shorthand {
|
||||
s.print_ident(f.ident);
|
||||
s.word_nbsp(":");
|
||||
}
|
||||
s.print_pat(&f.pat);
|
||||
s.print_pat(f.pat);
|
||||
s.end()
|
||||
},
|
||||
|f| f.pat.span,
|
||||
@@ -1823,58 +1806,58 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
}
|
||||
self.word("}");
|
||||
}
|
||||
PatKind::Or(ref pats) => {
|
||||
self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(&p));
|
||||
PatKind::Or(pats) => {
|
||||
self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
|
||||
}
|
||||
PatKind::Tuple(ref elts, ddpos) => {
|
||||
PatKind::Tuple(elts, ddpos) => {
|
||||
self.popen();
|
||||
if let Some(ddpos) = ddpos {
|
||||
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
|
||||
if ddpos != 0 {
|
||||
self.word_space(",");
|
||||
}
|
||||
self.word("..");
|
||||
if ddpos != elts.len() {
|
||||
self.word(",");
|
||||
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p));
|
||||
}
|
||||
} else {
|
||||
self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
|
||||
if elts.len() == 1 {
|
||||
self.word(",");
|
||||
}
|
||||
}
|
||||
self.pclose();
|
||||
}
|
||||
PatKind::Box(ref inner) => {
|
||||
PatKind::Box(inner) => {
|
||||
let is_range_inner = matches!(inner.kind, PatKind::Range(..));
|
||||
self.word("box ");
|
||||
if is_range_inner {
|
||||
self.popen();
|
||||
}
|
||||
self.print_pat(&inner);
|
||||
self.print_pat(inner);
|
||||
if is_range_inner {
|
||||
self.pclose();
|
||||
}
|
||||
}
|
||||
PatKind::Ref(ref inner, mutbl) => {
|
||||
PatKind::Ref(inner, mutbl) => {
|
||||
let is_range_inner = matches!(inner.kind, PatKind::Range(..));
|
||||
self.word("&");
|
||||
self.word(mutbl.prefix_str());
|
||||
if is_range_inner {
|
||||
self.popen();
|
||||
}
|
||||
self.print_pat(&inner);
|
||||
self.print_pat(inner);
|
||||
if is_range_inner {
|
||||
self.pclose();
|
||||
}
|
||||
}
|
||||
PatKind::Lit(ref e) => self.print_expr(&e),
|
||||
PatKind::Range(ref begin, ref end, ref end_kind) => {
|
||||
PatKind::Lit(e) => self.print_expr(e),
|
||||
PatKind::Range(begin, end, end_kind) => {
|
||||
if let Some(expr) = begin {
|
||||
self.print_expr(expr);
|
||||
}
|
||||
match *end_kind {
|
||||
match end_kind {
|
||||
RangeEnd::Included => self.word("..."),
|
||||
RangeEnd::Excluded => self.word(".."),
|
||||
}
|
||||
@@ -1882,24 +1865,24 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
self.print_expr(expr);
|
||||
}
|
||||
}
|
||||
PatKind::Slice(ref before, ref slice, ref after) => {
|
||||
PatKind::Slice(before, slice, after) => {
|
||||
self.word("[");
|
||||
self.commasep(Inconsistent, &before, |s, p| s.print_pat(&p));
|
||||
if let Some(ref p) = *slice {
|
||||
self.commasep(Inconsistent, before, |s, p| s.print_pat(p));
|
||||
if let Some(p) = slice {
|
||||
if !before.is_empty() {
|
||||
self.word_space(",");
|
||||
}
|
||||
if let PatKind::Wild = p.kind {
|
||||
// Print nothing.
|
||||
} else {
|
||||
self.print_pat(&p);
|
||||
self.print_pat(p);
|
||||
}
|
||||
self.word("..");
|
||||
if !after.is_empty() {
|
||||
self.word_space(",");
|
||||
}
|
||||
}
|
||||
self.commasep(Inconsistent, &after, |s, p| s.print_pat(&p));
|
||||
self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
|
||||
self.word("]");
|
||||
}
|
||||
}
|
||||
@@ -1908,7 +1891,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||
|
||||
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
|
||||
self.print_outer_attributes(self.attrs(arg.hir_id));
|
||||
self.print_pat(&arg.pat);
|
||||
self.print_pat(arg.pat);
|
||||
}
|
||||
|
||||
pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
|
||||
@@ -1920,32 +1903,32 @@ pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.ann.pre(self, AnnNode::Arm(arm));
|
||||
self.ibox(0);
|
||||
self.print_outer_attributes(&self.attrs(arm.hir_id));
|
||||
self.print_pat(&arm.pat);
|
||||
self.print_outer_attributes(self.attrs(arm.hir_id));
|
||||
self.print_pat(arm.pat);
|
||||
self.space();
|
||||
if let Some(ref g) = arm.guard {
|
||||
match g {
|
||||
match *g {
|
||||
hir::Guard::If(e) => {
|
||||
self.word_space("if");
|
||||
self.print_expr(&e);
|
||||
self.print_expr(e);
|
||||
self.space();
|
||||
}
|
||||
hir::Guard::IfLet(hir::Let { pat, ty, init, .. }) => {
|
||||
hir::Guard::IfLet(&hir::Let { pat, ty, init, .. }) => {
|
||||
self.word_nbsp("if");
|
||||
self.print_let(pat, *ty, init);
|
||||
self.print_let(pat, ty, init);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.word_space("=>");
|
||||
|
||||
match arm.body.kind {
|
||||
hir::ExprKind::Block(ref blk, opt_label) => {
|
||||
hir::ExprKind::Block(blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
}
|
||||
// the block will close the pattern's ibox
|
||||
self.print_block_unclosed(&blk);
|
||||
self.print_block_unclosed(blk);
|
||||
|
||||
// If it is a user-provided unsafe block, print a comma after it
|
||||
if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = blk.rules
|
||||
@@ -1955,7 +1938,7 @@ pub fn print_arm(&mut self, arm: &hir::Arm<'_>) {
|
||||
}
|
||||
_ => {
|
||||
self.end(); // close the ibox for the pattern
|
||||
self.print_expr(&arm.body);
|
||||
self.print_expr(arm.body);
|
||||
self.word(",");
|
||||
}
|
||||
}
|
||||
@@ -1978,13 +1961,13 @@ pub fn print_fn(
|
||||
self.nbsp();
|
||||
self.print_name(name);
|
||||
}
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_generic_params(generics.params);
|
||||
|
||||
self.popen();
|
||||
let mut i = 0;
|
||||
// Make sure we aren't supplied *both* `arg_names` and `body_id`.
|
||||
assert!(arg_names.is_empty() || body_id.is_none());
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
||||
self.commasep(Inconsistent, decl.inputs, |s, ty| {
|
||||
s.ibox(INDENT_UNIT);
|
||||
if let Some(arg_name) = arg_names.get(i) {
|
||||
s.word(arg_name.to_string());
|
||||
@@ -2011,7 +1994,7 @@ pub fn print_fn(
|
||||
fn print_closure_params(&mut self, decl: &hir::FnDecl<'_>, body_id: hir::BodyId) {
|
||||
self.word("|");
|
||||
let mut i = 0;
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
||||
self.commasep(Inconsistent, decl.inputs, |s, ty| {
|
||||
s.ibox(INDENT_UNIT);
|
||||
|
||||
s.ann.nested(s, Nested::BodyParamPat(body_id, i));
|
||||
@@ -2035,8 +2018,8 @@ fn print_closure_params(&mut self, decl: &hir::FnDecl<'_>, body_id: hir::BodyId)
|
||||
self.space_if_not_bol();
|
||||
self.word_space("->");
|
||||
match decl.output {
|
||||
hir::FnRetTy::Return(ref ty) => {
|
||||
self.print_type(&ty);
|
||||
hir::FnRetTy::Return(ty) => {
|
||||
self.print_type(ty);
|
||||
self.maybe_print_comment(ty.span.lo());
|
||||
}
|
||||
hir::FnRetTy::DefaultReturn(..) => unreachable!(),
|
||||
@@ -2107,20 +2090,20 @@ pub fn print_generic_param(&mut self, param: &GenericParam<'_>) {
|
||||
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {}
|
||||
GenericParamKind::Type { ref default, .. } => {
|
||||
GenericParamKind::Type { default, .. } => {
|
||||
if let Some(default) = default {
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_type(&default)
|
||||
self.print_type(default);
|
||||
}
|
||||
}
|
||||
GenericParamKind::Const { ref ty, ref default } => {
|
||||
GenericParamKind::Const { ty, ref default } => {
|
||||
self.word_space(":");
|
||||
self.print_type(ty);
|
||||
if let Some(ref default) = default {
|
||||
if let Some(default) = default {
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_anon_const(&default)
|
||||
self.print_anon_const(default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2143,7 +2126,7 @@ pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {
|
||||
self.word_space(",");
|
||||
}
|
||||
|
||||
match predicate {
|
||||
match *predicate {
|
||||
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bound_generic_params,
|
||||
bounded_ty,
|
||||
@@ -2151,11 +2134,11 @@ pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {
|
||||
..
|
||||
}) => {
|
||||
self.print_formal_generic_params(bound_generic_params);
|
||||
self.print_type(&bounded_ty);
|
||||
self.print_bounds(":", *bounds);
|
||||
self.print_type(bounded_ty);
|
||||
self.print_bounds(":", bounds);
|
||||
}
|
||||
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
|
||||
lifetime,
|
||||
ref lifetime,
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
@@ -2200,7 +2183,7 @@ pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) {
|
||||
|
||||
pub fn print_mt(&mut self, mt: &hir::MutTy<'_>, print_const: bool) {
|
||||
self.print_mutability(mt.mutbl, print_const);
|
||||
self.print_type(&mt.ty)
|
||||
self.print_type(mt.ty);
|
||||
}
|
||||
|
||||
pub fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) {
|
||||
@@ -2213,11 +2196,11 @@ pub fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) {
|
||||
self.word_space("->");
|
||||
match decl.output {
|
||||
hir::FnRetTy::DefaultReturn(..) => unreachable!(),
|
||||
hir::FnRetTy::Return(ref ty) => self.print_type(&ty),
|
||||
hir::FnRetTy::Return(ty) => self.print_type(ty),
|
||||
}
|
||||
self.end();
|
||||
|
||||
if let hir::FnRetTy::Return(ref output) = decl.output {
|
||||
if let hir::FnRetTy::Return(output) = decl.output {
|
||||
self.maybe_print_comment(output.span.lo());
|
||||
}
|
||||
}
|
||||
@@ -2243,7 +2226,7 @@ pub fn print_ty_fn(
|
||||
asyncness: hir::IsAsync::NotAsync,
|
||||
},
|
||||
name,
|
||||
&generics,
|
||||
generics,
|
||||
arg_names,
|
||||
None,
|
||||
);
|
||||
@@ -2312,7 +2295,7 @@ fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool {
|
||||
match *stmt {
|
||||
hir::StmtKind::Local(_) => true,
|
||||
hir::StmtKind::Item(_) => false,
|
||||
hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e),
|
||||
hir::StmtKind::Expr(e) => expr_requires_semi_to_be_stmt(e),
|
||||
hir::StmtKind::Semi(..) => false,
|
||||
}
|
||||
}
|
||||
@@ -2351,22 +2334,22 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
|
||||
match value.kind {
|
||||
hir::ExprKind::Struct(..) => true,
|
||||
|
||||
hir::ExprKind::Assign(ref lhs, ref rhs, _)
|
||||
| hir::ExprKind::AssignOp(_, ref lhs, ref rhs)
|
||||
| hir::ExprKind::Binary(_, ref lhs, ref rhs) => {
|
||||
hir::ExprKind::Assign(lhs, rhs, _)
|
||||
| hir::ExprKind::AssignOp(_, lhs, rhs)
|
||||
| hir::ExprKind::Binary(_, lhs, rhs) => {
|
||||
// `X { y: 1 } + X { y: 2 }`
|
||||
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
|
||||
contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs)
|
||||
}
|
||||
hir::ExprKind::Unary(_, ref x)
|
||||
| hir::ExprKind::Cast(ref x, _)
|
||||
| hir::ExprKind::Type(ref x, _)
|
||||
| hir::ExprKind::Field(ref x, _)
|
||||
| hir::ExprKind::Index(ref x, _) => {
|
||||
hir::ExprKind::Unary(_, x)
|
||||
| hir::ExprKind::Cast(x, _)
|
||||
| hir::ExprKind::Type(x, _)
|
||||
| hir::ExprKind::Field(x, _)
|
||||
| hir::ExprKind::Index(x, _) => {
|
||||
// `&X { y: 1 }, X { y: 1 }.y`
|
||||
contains_exterior_struct_lit(&x)
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
||||
hir::ExprKind::MethodCall(.., ref exprs, _) => {
|
||||
hir::ExprKind::MethodCall(.., exprs, _) => {
|
||||
// `X { y: 1 }.bar(...)`
|
||||
contains_exterior_struct_lit(&exprs[0])
|
||||
}
|
||||
|
||||
@@ -315,8 +315,6 @@ pub fn emit_inference_failure_err(
|
||||
body_id: Option<hir::BodyId>,
|
||||
failure_span: Span,
|
||||
arg: GenericArg<'tcx>,
|
||||
// FIXME(#94483): Either use this or remove it.
|
||||
_impl_candidates: Vec<ty::TraitRef<'tcx>>,
|
||||
error_code: TypeAnnotationNeeded,
|
||||
should_label_span: bool,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
@@ -534,6 +532,23 @@ enum InferSourceKind<'tcx> {
|
||||
},
|
||||
}
|
||||
|
||||
impl<'tcx> InferSource<'tcx> {
|
||||
fn from_expansion(&self) -> bool {
|
||||
let source_from_expansion = match self.kind {
|
||||
InferSourceKind::LetBinding { insert_span, .. }
|
||||
| InferSourceKind::ClosureArg { insert_span, .. }
|
||||
| InferSourceKind::GenericArg { insert_span, .. } => insert_span.from_expansion(),
|
||||
InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => {
|
||||
receiver.span.from_expansion()
|
||||
}
|
||||
InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
|
||||
data.span().from_expansion() || should_wrap_expr.map_or(false, Span::from_expansion)
|
||||
}
|
||||
};
|
||||
source_from_expansion || self.span.from_expansion()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> InferSourceKind<'tcx> {
|
||||
fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String {
|
||||
match *self {
|
||||
@@ -604,43 +619,65 @@ fn new(
|
||||
/// Sources with a small cost are prefer and should result
|
||||
/// in a clearer and idiomatic suggestion.
|
||||
fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
fn arg_cost<'tcx>(arg: GenericArg<'tcx>) -> usize {
|
||||
match arg.unpack() {
|
||||
GenericArgKind::Lifetime(_) => 0, // erased
|
||||
GenericArgKind::Type(ty) => ty_cost(ty),
|
||||
GenericArgKind::Const(_) => 3, // some non-zero value
|
||||
}
|
||||
#[derive(Clone, Copy)]
|
||||
struct CostCtxt<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
fn ty_cost<'tcx>(ty: Ty<'tcx>) -> usize {
|
||||
match ty.kind() {
|
||||
ty::Closure(..) => 100,
|
||||
ty::FnDef(..) => 20,
|
||||
ty::FnPtr(..) => 10,
|
||||
ty::Infer(..) => 0,
|
||||
_ => 1,
|
||||
impl<'tcx> CostCtxt<'tcx> {
|
||||
fn arg_cost(self, arg: GenericArg<'tcx>) -> usize {
|
||||
match arg.unpack() {
|
||||
GenericArgKind::Lifetime(_) => 0, // erased
|
||||
GenericArgKind::Type(ty) => self.ty_cost(ty),
|
||||
GenericArgKind::Const(_) => 3, // some non-zero value
|
||||
}
|
||||
}
|
||||
fn ty_cost(self, ty: Ty<'tcx>) -> usize {
|
||||
match *ty.kind() {
|
||||
ty::Closure(..) => 1000,
|
||||
ty::FnDef(..) => 150,
|
||||
ty::FnPtr(..) => 30,
|
||||
ty::Adt(def, substs) => {
|
||||
5 + self
|
||||
.tcx
|
||||
.generics_of(def.did())
|
||||
.own_substs_no_defaults(self.tcx, substs)
|
||||
.iter()
|
||||
.map(|&arg| self.arg_cost(arg))
|
||||
.sum::<usize>()
|
||||
}
|
||||
ty::Tuple(args) => 5 + args.iter().map(|arg| self.ty_cost(arg)).sum::<usize>(),
|
||||
ty::Ref(_, ty, _) => 2 + self.ty_cost(ty),
|
||||
ty::Infer(..) => 0,
|
||||
_ => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The sources are listed in order of preference here.
|
||||
match source.kind {
|
||||
InferSourceKind::LetBinding { ty, .. } => ty_cost(ty),
|
||||
InferSourceKind::ClosureArg { ty, .. } => 5 + ty_cost(ty),
|
||||
let tcx = self.infcx.tcx;
|
||||
let ctx = CostCtxt { tcx };
|
||||
let base_cost = match source.kind {
|
||||
InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
|
||||
InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
|
||||
InferSourceKind::GenericArg { def_id, generic_args, .. } => {
|
||||
let variant_cost = match tcx.def_kind(def_id) {
|
||||
DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15, // `None::<u32>` and friends are ugly.
|
||||
_ => 12,
|
||||
// `None::<u32>` and friends are ugly.
|
||||
DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15,
|
||||
_ => 10,
|
||||
};
|
||||
variant_cost + generic_args.iter().map(|&arg| arg_cost(arg)).sum::<usize>()
|
||||
variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>()
|
||||
}
|
||||
InferSourceKind::FullyQualifiedMethodCall { substs, .. } => {
|
||||
20 + substs.iter().map(|arg| arg_cost(arg)).sum::<usize>()
|
||||
20 + substs.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>()
|
||||
}
|
||||
InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
|
||||
30 + ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
|
||||
30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let suggestion_may_apply = if source.from_expansion() { 10000 } else { 0 };
|
||||
|
||||
base_cost + suggestion_may_apply
|
||||
}
|
||||
|
||||
/// Uses `fn source_cost` to determine whether this inference source is preferable to
|
||||
@@ -648,6 +685,7 @@ fn ty_cost<'tcx>(ty: Ty<'tcx>) -> usize {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
|
||||
let cost = self.source_cost(&new_source) + self.attempt;
|
||||
debug!(?cost);
|
||||
self.attempt += 1;
|
||||
if cost < self.infer_source_cost {
|
||||
self.infer_source_cost = cost;
|
||||
@@ -655,6 +693,11 @@ fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn node_substs_opt(&self, hir_id: HirId) -> Option<SubstsRef<'tcx>> {
|
||||
let substs = self.typeck_results.node_substs_opt(hir_id);
|
||||
self.infcx.resolve_vars_if_possible(substs)
|
||||
}
|
||||
|
||||
fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
|
||||
let ty = self.typeck_results.node_type_opt(hir_id);
|
||||
self.infcx.resolve_vars_if_possible(ty)
|
||||
@@ -737,7 +780,7 @@ fn expr_inferred_subst_iter(
|
||||
let tcx = self.infcx.tcx;
|
||||
match expr.kind {
|
||||
hir::ExprKind::Path(ref path) => {
|
||||
if let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id) {
|
||||
if let Some(substs) = self.node_substs_opt(expr.hir_id) {
|
||||
return self.path_inferred_subst_iter(expr.hir_id, substs, path);
|
||||
}
|
||||
}
|
||||
@@ -765,7 +808,7 @@ fn expr_inferred_subst_iter(
|
||||
if generics.has_impl_trait() {
|
||||
None?
|
||||
}
|
||||
let substs = self.typeck_results.node_substs_opt(expr.hir_id)?;
|
||||
let substs = self.node_substs_opt(expr.hir_id)?;
|
||||
let span = tcx.hir().span(segment.hir_id?);
|
||||
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
|
||||
InsertableGenericArgs {
|
||||
@@ -980,8 +1023,10 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
debug!(?args);
|
||||
let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args;
|
||||
let generics = tcx.generics_of(generics_def_id);
|
||||
if let Some(argument_index) =
|
||||
generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
|
||||
if let Some(argument_index) = generics
|
||||
.own_substs(substs)
|
||||
.iter()
|
||||
.position(|&arg| self.generic_arg_contains_target(arg))
|
||||
{
|
||||
let substs = self.infcx.resolve_vars_if_possible(substs);
|
||||
let generic_args = &generics.own_substs_no_defaults(tcx, substs)
|
||||
@@ -1037,7 +1082,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
.any(|generics| generics.has_impl_trait())
|
||||
};
|
||||
if let ExprKind::MethodCall(path, args, span) = expr.kind
|
||||
&& let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id)
|
||||
&& let Some(substs) = self.node_substs_opt(expr.hir_id)
|
||||
&& substs.iter().any(|arg| self.generic_arg_contains_target(arg))
|
||||
&& let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
|
||||
&& self.infcx.tcx.trait_of_item(def_id).is_some()
|
||||
|
||||
@@ -160,12 +160,18 @@ pub fn to_interp_error<'tcx>(self, alloc_id: AllocId) -> InterpError<'tcx> {
|
||||
}
|
||||
|
||||
/// The information that makes up a memory access: offset and size.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct AllocRange {
|
||||
pub start: Size,
|
||||
pub size: Size,
|
||||
}
|
||||
|
||||
impl fmt::Debug for AllocRange {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "[{:#x}..{:#x}]", self.start.bytes(), self.end().bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Free-starting constructor for less syntactic overhead.
|
||||
#[inline(always)]
|
||||
pub fn alloc_range(start: Size, size: Size) -> AllocRange {
|
||||
|
||||
@@ -334,36 +334,30 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
p,
|
||||
),
|
||||
PointerUseAfterFree(a) => {
|
||||
write!(f, "pointer to {} was dereferenced after this allocation got freed", a)
|
||||
write!(f, "pointer to {a:?} was dereferenced after this allocation got freed")
|
||||
}
|
||||
PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => {
|
||||
write!(
|
||||
f,
|
||||
"{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
|
||||
msg,
|
||||
alloc_id = alloc_id,
|
||||
"{msg}{alloc_id:?} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
|
||||
alloc_size = alloc_size.bytes(),
|
||||
ptr_offset = ptr_offset,
|
||||
)
|
||||
}
|
||||
PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!(
|
||||
f,
|
||||
"{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
|
||||
msg,
|
||||
alloc_id = alloc_id,
|
||||
"{msg}{alloc_id:?} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
|
||||
alloc_size = alloc_size.bytes(),
|
||||
ptr_size = ptr_size.bytes(),
|
||||
ptr_size_p = pluralize!(ptr_size.bytes()),
|
||||
ptr_offset = ptr_offset,
|
||||
),
|
||||
DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
|
||||
write!(f, "null pointer is not a valid pointer for this operation")
|
||||
}
|
||||
DanglingIntPointer(0, msg) => {
|
||||
write!(f, "{}null pointer is not a valid pointer", msg)
|
||||
write!(f, "{msg}null pointer is not a valid pointer")
|
||||
}
|
||||
DanglingIntPointer(i, msg) => {
|
||||
write!(f, "{}0x{:x} is not a valid pointer", msg, i)
|
||||
write!(f, "{msg}{i:#x} is not a valid pointer")
|
||||
}
|
||||
AlignmentCheckFailed { required, has } => write!(
|
||||
f,
|
||||
@@ -371,8 +365,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
has.bytes(),
|
||||
required.bytes()
|
||||
),
|
||||
WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a),
|
||||
DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a),
|
||||
WriteToReadOnly(a) => write!(f, "writing to {a:?} which is read-only"),
|
||||
DerefFunctionPointer(a) => write!(f, "accessing {a:?} which contains a function"),
|
||||
ValidationFailure { path: None, msg } => {
|
||||
write!(f, "constructing invalid value: {}", msg)
|
||||
}
|
||||
|
||||
@@ -190,11 +190,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AllocId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
// No "Display" since AllocIds are not usually user-visible.
|
||||
|
||||
#[derive(TyDecodable, TyEncodable)]
|
||||
enum AllocDiscriminant {
|
||||
@@ -470,7 +466,7 @@ fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>) -> AllocId {
|
||||
return alloc_id;
|
||||
}
|
||||
let id = alloc_map.reserve();
|
||||
debug!("creating alloc {:?} with id {}", alloc, id);
|
||||
debug!("creating alloc {alloc:?} with id {id:?}");
|
||||
alloc_map.alloc_map.insert(id, alloc.clone());
|
||||
alloc_map.dedup.insert(alloc, id);
|
||||
id
|
||||
@@ -538,7 +534,7 @@ pub fn get_global_alloc(self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
|
||||
pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> {
|
||||
match self.get_global_alloc(id) {
|
||||
Some(alloc) => alloc,
|
||||
None => bug!("could not find allocation for {}", id),
|
||||
None => bug!("could not find allocation for {id:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +542,7 @@ pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> {
|
||||
/// call this function twice, even with the same `Allocation` will ICE the compiler.
|
||||
pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) {
|
||||
if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
|
||||
bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
|
||||
bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
// Print offset only if it is non-zero.
|
||||
if ptr.offset.bytes() > 0 {
|
||||
write!(f, "+0x{:x}", ptr.offset.bytes())?;
|
||||
write!(f, "+{:#x}", ptr.offset.bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -181,7 +181,7 @@ impl<Tag: Provenance> fmt::Debug for Pointer<Option<Tag>> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.provenance {
|
||||
Some(tag) => Provenance::fmt(&Pointer::new(tag, self.offset), f),
|
||||
None => write!(f, "0x{:x}", self.offset.bytes()),
|
||||
None => write!(f, "{:#x}", self.offset.bytes()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ impl<Tag: Provenance> fmt::LowerHex for Scalar<Tag> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Scalar::Ptr(ptr, _size) => write!(f, "pointer to {:?}", ptr),
|
||||
Scalar::Int(int) => write!(f, "0x{:x}", int),
|
||||
Scalar::Int(int) => write!(f, "{:#x}", int),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,12 +716,12 @@ fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) {
|
||||
}
|
||||
write!(w, "{}", display_allocation(tcx, alloc.inner()))
|
||||
};
|
||||
write!(w, "\n{}", id)?;
|
||||
write!(w, "\n{id:?}")?;
|
||||
match tcx.get_global_alloc(id) {
|
||||
// This can't really happen unless there are bugs, but it doesn't cost us anything to
|
||||
// gracefully handle it and allow buggy rustc to be debugged via allocation printing.
|
||||
None => write!(w, " (deallocated)")?,
|
||||
Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?,
|
||||
Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {inst})")?,
|
||||
Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
|
||||
match tcx.eval_static_initializer(did) {
|
||||
Ok(alloc) => {
|
||||
|
||||
@@ -452,6 +452,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl fmt::LowerHex for ScalarInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.check_data();
|
||||
if f.alternate() {
|
||||
// Like regular ints, alternate flag adds leading `0x`.
|
||||
write!(f, "0x")?;
|
||||
}
|
||||
// Format as hex number wide enough to fit any value of the given `size`.
|
||||
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
|
||||
// Using a block `{self.data}` here to force a copy instead of using `self.data`
|
||||
|
||||
@@ -1495,6 +1495,15 @@ pub(crate) fn unresolved_macro_suggestions(
|
||||
err.help("have you added the `#[macro_use]` on the module/import?");
|
||||
return;
|
||||
}
|
||||
if ident.name == kw::Default
|
||||
&& let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind
|
||||
&& let Some(span) = self.opt_span(def_id)
|
||||
{
|
||||
err.span_help(
|
||||
self.session.source_map().guess_head_span(span),
|
||||
"consider adding `#[derive(Default)]` to this enum",
|
||||
);
|
||||
}
|
||||
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
|
||||
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
|
||||
ident,
|
||||
|
||||
@@ -1980,7 +1980,6 @@ fn maybe_report_ambiguity(
|
||||
body_id,
|
||||
span,
|
||||
trait_ref.self_ty().skip_binder().into(),
|
||||
vec![],
|
||||
ErrorCode::E0282,
|
||||
false,
|
||||
)
|
||||
@@ -2005,19 +2004,7 @@ fn maybe_report_ambiguity(
|
||||
let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
|
||||
|
||||
let mut err = if let Some(subst) = subst {
|
||||
let impl_candidates = self
|
||||
.find_similar_impl_candidates(trait_ref)
|
||||
.into_iter()
|
||||
.map(|candidate| candidate.trait_ref)
|
||||
.collect();
|
||||
self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
subst,
|
||||
impl_candidates,
|
||||
ErrorCode::E0283,
|
||||
true,
|
||||
)
|
||||
self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true)
|
||||
} else {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
@@ -2117,7 +2104,7 @@ fn maybe_report_ambiguity(
|
||||
return;
|
||||
}
|
||||
|
||||
self.emit_inference_failure_err(body_id, span, arg, vec![], ErrorCode::E0282, false)
|
||||
self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, false)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(data) => {
|
||||
@@ -2131,14 +2118,7 @@ fn maybe_report_ambiguity(
|
||||
let SubtypePredicate { a_is_expected: _, a, b } = data;
|
||||
// both must be type variables, or the other would've been instantiated
|
||||
assert!(a.is_ty_var() && b.is_ty_var());
|
||||
self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
a.into(),
|
||||
vec![],
|
||||
ErrorCode::E0282,
|
||||
true,
|
||||
)
|
||||
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
|
||||
}
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||
@@ -2155,7 +2135,6 @@ fn maybe_report_ambiguity(
|
||||
body_id,
|
||||
span,
|
||||
subst,
|
||||
vec![],
|
||||
ErrorCode::E0284,
|
||||
true,
|
||||
);
|
||||
|
||||
@@ -1538,15 +1538,8 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
ty
|
||||
} else {
|
||||
if !self.is_tainted_by_errors() {
|
||||
self.emit_inference_failure_err(
|
||||
(**self).body_id,
|
||||
sp,
|
||||
ty.into(),
|
||||
vec![],
|
||||
E0282,
|
||||
true,
|
||||
)
|
||||
.emit();
|
||||
self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
|
||||
.emit();
|
||||
}
|
||||
let err = self.tcx.ty_error();
|
||||
self.demand_suptype(sp, err, ty);
|
||||
|
||||
@@ -692,7 +692,6 @@ fn report_type_error(&self, t: Ty<'tcx>) {
|
||||
Some(self.body.id()),
|
||||
self.span.to_span(self.tcx),
|
||||
t.into(),
|
||||
vec![],
|
||||
E0282,
|
||||
false,
|
||||
)
|
||||
@@ -707,7 +706,6 @@ fn report_const_error(&self, c: ty::Const<'tcx>) {
|
||||
Some(self.body.id()),
|
||||
self.span.to_span(self.tcx),
|
||||
c.into(),
|
||||
vec![],
|
||||
E0282,
|
||||
false,
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut};
|
||||
use crate::iter::FusedIterator;
|
||||
use crate::net::{Shutdown, SocketAddr, ToSocketAddrs};
|
||||
use crate::sys_common::net as net_imp;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
@@ -1009,6 +1010,9 @@ fn next(&mut self) -> Option<io::Result<TcpStream>> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "tcp_listener_incoming_fused_iterator", since = "1.64.0")]
|
||||
impl FusedIterator for Incoming<'_> {}
|
||||
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
impl Iterator for IntoIncoming {
|
||||
type Item = io::Result<TcpStream>;
|
||||
@@ -1017,6 +1021,9 @@ fn next(&mut self) -> Option<io::Result<TcpStream>> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
impl FusedIterator for IntoIncoming {}
|
||||
|
||||
impl AsInner<net_imp::TcpListener> for TcpListener {
|
||||
fn as_inner(&self) -> &net_imp::TcpListener {
|
||||
&self.0
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
pub enum Test { //~ HELP consider adding `#[derive(Default)]` to this enum
|
||||
#[default]
|
||||
//~^ ERROR cannot find attribute `default` in this scope
|
||||
First,
|
||||
Second,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
error: cannot find attribute `default` in this scope
|
||||
--> $DIR/suggest-default-attribute.rs:2:7
|
||||
|
|
||||
LL | #[default]
|
||||
| ^^^^^^^
|
||||
|
|
||||
help: consider adding `#[derive(Default)]` to this enum
|
||||
--> $DIR/suggest-default-attribute.rs:1:1
|
||||
|
|
||||
LL | pub enum Test {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/ambiguous_type_parameter.rs:16:19
|
||||
|
|
||||
LL | InMemoryStore.get_raw(&String::default());
|
||||
| ^^^^^^^ cannot infer type for type parameter `K`
|
||||
| ^^^^^^^
|
||||
|
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <InMemoryStore as Store<String, HashMap<K, String>>>::get_raw(&InMemoryStore, &String::default());
|
||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ fn infallible() -> Result<(), std::convert::Infallible> {
|
||||
|
||||
fn main() {
|
||||
let x = || -> Result<_, QualifiedError<_>> {
|
||||
//~^ ERROR type annotations needed for `Result<(), QualifiedError<_>>`
|
||||
infallible()?;
|
||||
Ok(())
|
||||
//~^ ERROR type annotations needed
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
error[E0282]: type annotations needed for `Result<(), QualifiedError<_>>`
|
||||
--> $DIR/cannot-infer-partial-try-return.rs:18:13
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cannot-infer-partial-try-return.rs:20:9
|
||||
|
|
||||
LL | let x = || -> Result<_, QualifiedError<_>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | infallible()?;
|
||||
| ------------- type must be known at this point
|
||||
LL | Ok(())
|
||||
| ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: try giving this closure an explicit return type
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | let x = || -> Result<(), QualifiedError<_>> {
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL | Ok::<(), QualifiedError<_>>(())
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Test that we suggest specifying the generic argument of `channel`
|
||||
// instead of the return type of that function, which is a lot more
|
||||
// complex.
|
||||
use std::sync::mpsc::channel;
|
||||
|
||||
fn no_tuple() {
|
||||
let _data =
|
||||
channel(); //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn tuple() {
|
||||
let (_sender, _receiver) =
|
||||
channel(); //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {
|
||||
no_tuple();
|
||||
tuple();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/channel.rs:8:9
|
||||
|
|
||||
LL | channel();
|
||||
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | channel::<T>();
|
||||
| +++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/channel.rs:13:9
|
||||
|
|
||||
LL | channel();
|
||||
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | channel::<T>();
|
||||
| +++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
@@ -1,8 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-23041.rs:6:22
|
||||
--> $DIR/issue-23041.rs:6:7
|
||||
|
|
||||
LL | b.downcast_ref::<fn(_)->_>();
|
||||
| ^^^^^^^^ cannot infer type
|
||||
| ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `downcast_ref`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | b.downcast_ref::<fn(_) -> _>();
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-24013.rs:5:20
|
||||
--> $DIR/issue-24013.rs:5:13
|
||||
|
|
||||
LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
|
||||
| ^^^^^^ cannot infer type
|
||||
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
struct Foo<T> {foo: PhantomData<T>}
|
||||
|
||||
fn main() {
|
||||
let (tx, rx) = //~ ERROR type annotations needed
|
||||
let (tx, rx) =
|
||||
channel();
|
||||
// FIXME(#89862): Suggest adding a generic argument to `channel` instead
|
||||
spawn(move || {
|
||||
tx.send(Foo{ foo: PhantomData });
|
||||
//~^ ERROR type annotations needed
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
error[E0282]: type annotations needed for `(Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`
|
||||
--> $DIR/issue-25368.rs:8:9
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-25368.rs:11:27
|
||||
|
|
||||
LL | let (tx, rx) =
|
||||
| ^^^^^^^^
|
||||
LL | tx.send(Foo{ foo: PhantomData });
|
||||
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData`
|
||||
|
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | let (tx, rx): (Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>) =
|
||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
LL | tx.send(Foo{ foo: PhantomData::<T> });
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7
|
||||
|
|
||||
LL | x.foo();
|
||||
| ^^^ cannot infer type for struct `Vec<_>`
|
||||
| ^^^
|
||||
|
|
||||
note: multiple `impl`s satisfying `Vec<_>: Foo` found
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1
|
||||
@@ -23,6 +23,10 @@ LL | impl Foo for Vec<usize> {
|
||||
...
|
||||
LL | impl Foo for Vec<isize> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <Vec<T> as Foo>::foo(&x);
|
||||
| ++++++++++++++++++++++ ~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20
|
||||
|
||||
Reference in New Issue
Block a user