diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 5a362a37f2bed..b1e4e3ba39521 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -236,9 +236,9 @@ fn test_lints_tracking_hash_different_values() { (String::from("d"), Level::Deny), ]; - assert_different_hash(&v1, &v2); - assert_different_hash(&v1, &v3); - assert_different_hash(&v2, &v3); + assert_non_crate_hash_different(&v1, &v2); + assert_non_crate_hash_different(&v1, &v3); + assert_non_crate_hash_different(&v2, &v3); } #[test] @@ -261,7 +261,21 @@ fn test_lints_tracking_hash_different_construction_order() { ]; // The hash should be order-dependent - assert_different_hash(&v1, &v2); + assert_non_crate_hash_different(&v1, &v2); +} + +#[test] +fn test_lint_cap_hash_different() { + let mut v1 = Options::default(); + let mut v2 = Options::default(); + let v3 = Options::default(); + + v1.lint_cap = Some(Level::Forbid); + v2.lint_cap = Some(Level::Allow); + + assert_non_crate_hash_different(&v1, &v2); + assert_non_crate_hash_different(&v1, &v3); + assert_non_crate_hash_different(&v2, &v3); } #[test] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 474cd86f43bea..8e2e33f2d5150 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -133,9 +133,9 @@ top_level_options!( /// can influence whether overflow checks are done or not. debug_assertions: bool [TRACKED], debuginfo: DebugInfo [TRACKED], - lint_opts: Vec<(String, lint::Level)> [TRACKED], - lint_cap: Option [TRACKED], - force_warns: Vec [TRACKED], + lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH], + lint_cap: Option [TRACKED_NO_CRATE_HASH], + force_warns: Vec [TRACKED_NO_CRATE_HASH], describe_lints: bool [UNTRACKED], output_types: OutputTypes [TRACKED], search_paths: Vec [UNTRACKED], diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 9a39a32f6d5d3..39874f48eb014 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -1528,20 +1528,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { &mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId, - mode: euv::ConsumeMode, ) { debug!( - "adjust_upvar_borrow_kind_for_consume(place_with_id={:?}, diag_expr_id={:?}, mode={:?})", - place_with_id, diag_expr_id, mode + "adjust_upvar_borrow_kind_for_consume(place_with_id={:?}, diag_expr_id={:?})", + place_with_id, diag_expr_id ); - - // Copy type being used as ByValue are equivalent to ImmBorrow and don't require any - // escalation. - match mode { - euv::ConsumeMode::Copy => return, - euv::ConsumeMode::Move => {} - }; - let tcx = self.fcx.tcx; let upvar_id = if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base { upvar_id @@ -1716,22 +1707,14 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { } } - fn consume( - &mut self, - place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, - mode: euv::ConsumeMode, - ) { - debug!( - "consume(place_with_id={:?}, diag_expr_id={:?}, mode={:?})", - place_with_id, diag_expr_id, mode - ); + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + debug!("consume(place_with_id={:?}, diag_expr_id={:?})", place_with_id, diag_expr_id); if !self.capture_information.contains_key(&place_with_id.place) { self.init_capture_info_for_place(&place_with_id, diag_expr_id); } - self.adjust_upvar_borrow_kind_for_consume(&place_with_id, diag_expr_id, mode); + self.adjust_upvar_borrow_kind_for_consume(&place_with_id, diag_expr_id); } fn borrow( diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index f174941279484..806f1a2711c01 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -2,8 +2,6 @@ //! normal visitor, which just walks the entire body in one shot, the //! `ExprUseVisitor` determines how expressions are being used. -pub use self::ConsumeMode::*; - // Export these here so that Clippy can use them. pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; @@ -28,19 +26,20 @@ use crate::mem_categorization as mc; /// This trait defines the callbacks you can expect to receive when /// employing the ExprUseVisitor. pub trait Delegate<'tcx> { - // The value found at `place` is either copied or moved, depending + // The value found at `place` is moved, depending // on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`. // + // Use of a `Copy` type in a ByValue context is considered a use + // by `ImmBorrow` and `borrow` is called instead. This is because + // a shared borrow is the "minimum access" that would be needed + // to perform a copy. + // + // // The parameter `diag_expr_id` indicates the HIR id that ought to be used for // diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic // id will be the id of the expression `expr` but the place itself will have // the id of the binding in the pattern `pat`. - fn consume( - &mut self, - place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, - mode: ConsumeMode, - ); + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); // The value found at `place` is being borrowed with kind `bk`. // `diag_expr_id` is the id used for diagnostics (see `consume` for more details). @@ -60,7 +59,7 @@ pub trait Delegate<'tcx> { } #[derive(Copy, Clone, PartialEq, Debug)] -pub enum ConsumeMode { +enum ConsumeMode { Copy, // reference to x where x has a type that copies Move, // reference to x where x has a type that moves } @@ -141,10 +140,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { - debug!("delegate_consume(place_with_id={:?})", place_with_id); - - let mode = copy_or_move(&self.mc, place_with_id); - self.delegate.consume(place_with_id, diag_expr_id, mode); + delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) } fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) { @@ -256,12 +252,16 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | PatKind::Path(..) | PatKind::Struct(..) | PatKind::Tuple(..) => { - // If the PatKind is a TupleStruct, Struct or Tuple then we want to check + // If the PatKind is a TupleStruct, Path, Struct or Tuple then we want to check // whether the Variant is a MultiVariant or a SingleVariant. We only want // to borrow discr if it is a MultiVariant. // If it is a SingleVariant and creates a binding we will handle that when // this callback gets called again. - if let ty::Adt(def, _) = place.place.base_ty.kind() { + + // Get the type of the Place after all projections have been applied + let place_ty = place.place.ty(); + + if let ty::Adt(def, _) = place_ty.kind() { if def.variants.len() > 1 { needs_to_be_read = true; } @@ -653,9 +653,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { delegate.borrow(place, discr_place.hir_id, bk); } ty::BindByValue(..) => { - let mode = copy_or_move(mc, &place); debug!("walk_pat binding consuming pat"); - delegate.consume(place, discr_place.hir_id, mode); + delegate_consume(mc, *delegate, place, discr_place.hir_id); } } } @@ -773,8 +772,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match capture_info.capture_kind { ty::UpvarCapture::ByValue(_) => { - let mode = copy_or_move(&self.mc, &place_with_id); - self.delegate.consume(&place_with_id, place_with_id.hir_id, mode); + self.delegate_consume(&place_with_id, place_with_id.hir_id); } ty::UpvarCapture::ByRef(upvar_borrow) => { self.delegate.borrow( @@ -798,8 +796,28 @@ fn copy_or_move<'a, 'tcx>( place_with_id.place.ty(), mc.tcx().hir().span(place_with_id.hir_id), ) { - Move + ConsumeMode::Move } else { - Copy + ConsumeMode::Copy + } +} + +// - If a place is used in a `ByValue` context then move it if it's not a `Copy` type. +// - If the place that is a `Copy` type consider it a `ImmBorrow`. +fn delegate_consume<'a, 'tcx>( + mc: &mc::MemCategorizationContext<'a, 'tcx>, + delegate: &mut (dyn Delegate<'tcx> + 'a), + place_with_id: &PlaceWithHirId<'tcx>, + diag_expr_id: hir::HirId, +) { + debug!("delegate_consume(place_with_id={:?})", place_with_id); + + let mode = copy_or_move(&mc, place_with_id); + + match mode { + ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), + ConsumeMode::Copy => { + delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) + } } } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 4a86d6a100abe..b9387ef49e5fb 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -30,7 +30,7 @@ pub trait Step: Clone + PartialOrd + Sized { /// For any `a`, `b`, and `n`: /// /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)` - /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&a, n) == Some(a)` + /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)` /// * `steps_between(&a, &b) == Some(n)` only if `a <= b` /// * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b` /// * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`; diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 52e5d37c83fbd..558536fa613a5 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -1,8 +1,8 @@ - {data_ptr,[length]s8} - data_ptr,[length]s8 + {(char*)data_ptr,[length]s8} + (char*)data_ptr,[length]s8 length diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index 9cc60fc7b47e5..d001f40fccbc7 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -48,6 +48,7 @@ vec.len vec.buf.cap + {(char*)vec.buf.ptr.pointer,[vec.len]s8} vec.len @@ -57,22 +58,38 @@ + {ptr.pointer->value} ptr.pointer->value + ptr.pointer->strong + ptr.pointer->weak + + {ptr.pointer->value} + + ptr.pointer->value + ptr.pointer->strong + ptr.pointer->weak + + + {ptr.pointer->data} ptr.pointer->data + ptr.pointer->strong + ptr.pointer->weak {ptr.pointer->data} ptr.pointer->data + ptr.pointer->strong + ptr.pointer->weak diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index c8196d5c713b2..fa8ee2d70bbab 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -1,23 +1,163 @@ - - {{ Unique {pointer} }} + + {value.value} - pointer + value.value + + + + {value} + + value + + + + {value} + + value + + + + {value.value} + + "Unborrowed",sb + "Immutably borrowed",sb + "Mutably borrowed",sb + value.value + + + + {value} + + value - - {{ Shared {pointer} }} + + {value} - pointer + value + + + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + {__0} + + + + {__0} + + + + ({start}..{end}) + + + ({start}..) + + + ({start}..={end}) + + + (..{end}) + + + (..={end}) + + + + Pin({(void*)pointer}: {pointer}) + + pointer - {(void*) pointer} + NonNull({(void*) pointer}: {pointer}) + + pointer + + + + + Unique({(void*)pointer}: {pointer}) + + pointer + + + + + {(bool)v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + {v.value} + + + + {secs,d}s {nanos,d}ns - *pointer + secs,d + nanos,d - \ No newline at end of file + diff --git a/src/etc/natvis/libstd.natvis b/src/etc/natvis/libstd.natvis index 3ccd2e9c30ed5..c7be0167de9fd 100644 --- a/src/etc/natvis/libstd.natvis +++ b/src/etc/natvis/libstd.natvis @@ -74,9 +74,10 @@ - {inner.data_ptr,s} + {(char*)inner.data_ptr} + {(char*)inner.data_ptr} inner.length @@ -101,4 +102,19 @@ + + + {(char*)inner.inner.bytes.buf.ptr.pointer,[inner.inner.bytes.len]} + + + {(char*)inner.inner.bytes.buf.ptr.pointer,[inner.inner.bytes.len]} + + + inner.inner.bytes.len + (char*)inner.inner.bytes.buf.ptr.pointer + + + + + diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 208e8f723f407..89dbc4d825f3d 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -247,6 +247,9 @@ code, pre, a.test-arrow { pre { padding: 14px; } +.type-decl pre { + overflow-x: auto; +} .source .content pre { padding: 20px; @@ -1631,15 +1634,18 @@ details.undocumented[open] > summary::before { display: none; } + /* We do NOT hide this element so that alternative device readers still have this information + available. */ .sidebar-elems { position: fixed; z-index: 1; - left: 0; top: 45px; bottom: 0; + width: 246px; + /* We move the sidebar to the left by its own width so it doesn't appear. */ + left: -246px; overflow-y: auto; border-right: 1px solid; - display: none; } .sidebar > .block.version { @@ -1727,8 +1733,7 @@ details.undocumented[open] > summary::before { } .show-it { - display: block; - width: 246px; + left: 0; } .show-it > .block.items { diff --git a/src/test/debuginfo/duration-type.rs b/src/test/debuginfo/duration-type.rs new file mode 100644 index 0000000000000..bc0266d644ec1 --- /dev/null +++ b/src/test/debuginfo/duration-type.rs @@ -0,0 +1,22 @@ +// only-cdb +// compile-flags:-g + +// === CDB TESTS ================================================================================== + +// cdb-command: g + +// cdb-command: dx duration +// cdb-check:duration : 5s 12ns [Type: core::time::Duration] +// cdb-check: [] [Type: core::time::Duration] +// cdb-check: seconds : 5 [Type: unsigned __int64] +// cdb-check: nanoseconds : 12 [Type: unsigned int] + +use std::time::Duration; + +fn main() { + let duration = Duration::new(5, 12); + + zzz(); // #break +} + +fn zzz() { } diff --git a/src/test/debuginfo/marker-types.rs b/src/test/debuginfo/marker-types.rs new file mode 100644 index 0000000000000..8373d7856bb37 --- /dev/null +++ b/src/test/debuginfo/marker-types.rs @@ -0,0 +1,49 @@ +// only-cdb +// compile-flags:-g + +// === CDB TESTS ================================================================================== + +// cdb-command: g + +// cdb-command: dx nonnull +// cdb-check:nonnull : NonNull(0x[...]: 0xc) [Type: core::ptr::non_null::NonNull] +// cdb-check: [] [Type: core::ptr::non_null::NonNull] +// cdb-check: 0xc [Type: unsigned int] + +// cdb-command: dx manuallydrop +// cdb-check:manuallydrop : 12345 [Type: core::mem::manually_drop::ManuallyDrop] +// cdb-check: [] [Type: core::mem::manually_drop::ManuallyDrop] + +// cdb-command: dx pin +// cdb-check:pin : Pin(0x[...]: "this") [Type: core::pin::Pin >] +// cdb-check: [] [Type: core::pin::Pin >] +// cdb-check: [len] : 0x4 [Type: unsigned [...]] +// cdb-check: [capacity] : 0x4 [Type: unsigned [...]] +// cdb-check: [chars] : "this" + +// cdb-command: dx unique +// cdb-check:unique : Unique(0x[...]: (0x2a, 4321)) [Type: core::ptr::unique::Unique >] +// cdb-check: [] [Type: core::ptr::unique::Unique >] +// cdb-check: [0] : 0x2a [Type: unsigned __int64] +// cdb-check: [1] : 4321 [Type: int] + +#![feature(ptr_internals)] + +use std::mem::ManuallyDrop; +use std::pin::Pin; +use std::ptr::{NonNull, Unique}; + +fn main() { + let nonnull: NonNull<_> = (&12u32).into(); + + let manuallydrop = ManuallyDrop::new(12345i32); + + let mut s = "this".to_string(); + let pin = Pin::new(&mut s); + + let unique: Unique<_> = (&mut (42u64, 4321i32)).into(); + + zzz(); // #break +} + +fn zzz() { } diff --git a/src/test/debuginfo/mutable-locs.rs b/src/test/debuginfo/mutable-locs.rs index 428a7e8d9c09b..688483e43e4db 100644 --- a/src/test/debuginfo/mutable-locs.rs +++ b/src/test/debuginfo/mutable-locs.rs @@ -9,26 +9,64 @@ // cdb-command: g // cdb-command:dx static_c,d -// cdb-check:static_c,d [Type: core::cell::Cell] -// cdb-check: [...] value [Type: core::cell::UnsafeCell] +// cdb-check:static_c,d : 10 [Type: core::cell::Cell] +// cdb-check: [] [Type: core::cell::Cell] // cdb-command: dx static_c.value,d -// cdb-check:static_c.value,d [Type: core::cell::UnsafeCell] -// cdb-check: [...] value : 10 [Type: int] +// cdb-check:static_c.value,d : 10 [Type: core::cell::UnsafeCell] +// cdb-check: [] [Type: core::cell::UnsafeCell] // cdb-command: dx dynamic_c,d -// cdb-check:dynamic_c,d [Type: core::cell::RefCell] -// cdb-check: [...] borrow [Type: core::cell::Cell] -// cdb-check: [...] value [Type: core::cell::UnsafeCell] +// cdb-check:dynamic_c,d : 15 [Type: core::cell::RefCell] +// cdb-check: [] [Type: core::cell::RefCell] +// cdb-check: [Borrow state] : Unborrowed // cdb-command: dx dynamic_c.value,d -// cdb-check:dynamic_c.value,d [Type: core::cell::UnsafeCell] -// cdb-check: [...] value : 15 [Type: int] +// cdb-check:dynamic_c.value,d : 15 [Type: core::cell::UnsafeCell] +// cdb-check: [] [Type: core::cell::UnsafeCell] // cdb-command: dx b,d -// cdb-check:b,d [Type: core::cell::RefMut] -// cdb-check: [...] value : [...] : 42 [Type: int *] -// cdb-check: [...] borrow [Type: core::cell::BorrowRefMut] +// cdb-check:b,d : 42 [Type: core::cell::RefMut] +// cdb-check: [] [Type: core::cell::RefMut] +// cdb-check: 42 [Type: int] + +// cdb-command: g + +// cdb-command: dx dynamic_c,d +// cdb-check:dynamic_c,d : 15 [Type: core::cell::RefCell] +// cdb-check: [] [Type: core::cell::RefCell] +// cdb-check: [Borrow state] : Immutably borrowed + +// cdb-command: dx r_borrow,d +// cdb-check:r_borrow,d : 15 [Type: core::cell::Ref] +// cdb-check: [] [Type: core::cell::Ref] +// cdb-check: 15 [Type: int] + +// cdb-command: g + +// cdb-command: dx dynamic_c,d +// cdb-check:dynamic_c,d : 15 [Type: core::cell::RefCell] +// cdb-check: [] [Type: core::cell::RefCell] +// cdb-check: [Borrow state] : Unborrowed + +// cdb-command: g + +// cdb-command: dx dynamic_c,d +// cdb-check:dynamic_c,d : 15 [Type: core::cell::RefCell] +// cdb-check: [] [Type: core::cell::RefCell] +// cdb-check: [Borrow state] : Mutably borrowed + +// cdb-command: dx r_borrow_mut,d +// cdb-check:r_borrow_mut,d : 15 [Type: core::cell::RefMut] +// cdb-check: [] [Type: core::cell::RefMut] +// cdb-check: 15 [Type: int] + +// cdb-command: g + +// cdb-command: dx dynamic_c,d +// cdb-check:dynamic_c,d : 15 [Type: core::cell::RefCell] +// cdb-check: [] [Type: core::cell::RefCell] +// cdb-check: [Borrow state] : Unborrowed #![allow(unused_variables)] @@ -46,6 +84,21 @@ fn main() { *b = 42; zzz(); // #break + + // Check that `RefCell`'s borrow state visualizes correctly + { + let r_borrow = dynamic_c.borrow(); + zzz(); // #break + } + + zzz(); // #break + + { + let r_borrow_mut = dynamic_c.borrow_mut(); + zzz(); // #break + } + + zzz(); // #break } fn zzz() {()} diff --git a/src/test/debuginfo/numeric-types.rs b/src/test/debuginfo/numeric-types.rs new file mode 100644 index 0000000000000..2eae9239b6118 --- /dev/null +++ b/src/test/debuginfo/numeric-types.rs @@ -0,0 +1,206 @@ +// only-cdb +// compile-flags:-g + +// Tests the visualizations for `NonZero{I,U}{8,16,32,64,128,size}`, `Wrapping` and +// `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`. + +// === CDB TESTS ================================================================================== +// cdb-command: g + +// cdb-command: dx nz_i8 +// cdb-check:nz_i8 : 11 [Type: core::num::nonzero::NonZeroI8] +// cdb-check: [] [Type: core::num::nonzero::NonZeroI8] + +// cdb-command: dx nz_i16 +// cdb-check:nz_i16 : 22 [Type: core::num::nonzero::NonZeroI16] +// cdb-check: [] [Type: core::num::nonzero::NonZeroI16] + +// cdb-command: dx nz_i32 +// cdb-check:nz_i32 : 33 [Type: core::num::nonzero::NonZeroI32] +// cdb-check: [] [Type: core::num::nonzero::NonZeroI32] + +// cdb-command: dx nz_i64 +// cdb-check:nz_i64 : 44 [Type: core::num::nonzero::NonZeroI64] +// cdb-check: [] [Type: core::num::nonzero::NonZeroI64] + +// 128-bit integers don't seem to work in CDB +// cdb-command: dx nz_i128 +// cdb-check: [] [Type: core::num::nonzero::NonZeroI128] + +// cdb-command: dx nz_isize +// cdb-check:nz_isize : 66 [Type: core::num::nonzero::NonZeroIsize] +// cdb-check: [] [Type: core::num::nonzero::NonZeroIsize] + +// cdb-command: dx nz_u8 +// cdb-check:nz_u8 : 0x4d [Type: core::num::nonzero::NonZeroU8] +// cdb-check: [] [Type: core::num::nonzero::NonZeroU8] + +// cdb-command: dx nz_u16 +// cdb-check:nz_u16 : 0x58 [Type: core::num::nonzero::NonZeroU16] +// cdb-check: [] [Type: core::num::nonzero::NonZeroU16] + +// cdb-command: dx nz_u32 +// cdb-check:nz_u32 : 0x63 [Type: core::num::nonzero::NonZeroU32] +// cdb-check: [] [Type: core::num::nonzero::NonZeroU32] + +// cdb-command: dx nz_u64 +// cdb-check:nz_u64 : 0x64 [Type: core::num::nonzero::NonZeroU64] +// cdb-check: [] [Type: core::num::nonzero::NonZeroU64] + +// 128-bit integers don't seem to work in CDB +// cdb-command: dx nz_u128 +// cdb-check: [] [Type: core::num::nonzero::NonZeroU128] + +// cdb-command: dx nz_usize +// cdb-check:nz_usize : 0x7a [Type: core::num::nonzero::NonZeroUsize] +// cdb-check: [] [Type: core::num::nonzero::NonZeroUsize] + +// cdb-command: dx w_i8 +// cdb-check:w_i8 : 10 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_i16 +// cdb-check:w_i16 : 20 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_i32 +// cdb-check:w_i32 : 30 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_i64 +// cdb-check:w_i64 : 40 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// 128-bit integers don't seem to work in CDB +// cdb-command: dx w_i128 +// cdb-check:w_i128 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_isize +// cdb-check:w_isize : 60 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_u8 +// cdb-check:w_u8 : 0x46 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_u16 +// cdb-check:w_u16 : 0x50 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_u32 +// cdb-check:w_u32 : 0x5a [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_u64 +// cdb-check:w_u64 : 0x64 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// 128-bit integers don't seem to work in CDB +// cdb-command: dx w_u128 +// cdb-check:w_u128 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx w_usize +// cdb-check:w_usize : 0x78 [Type: core::num::wrapping::Wrapping] +// cdb-check: [] [Type: core::num::wrapping::Wrapping] + +// cdb-command: dx a_bool_t +// cdb-check:a_bool_t : true [Type: core::sync::atomic::AtomicBool] +// cdb-check: [] [Type: core::sync::atomic::AtomicBool] + +// cdb-command: dx a_bool_f +// cdb-check:a_bool_f : false [Type: core::sync::atomic::AtomicBool] +// cdb-check: [] [Type: core::sync::atomic::AtomicBool] + +// cdb-command: dx a_i8 +// cdb-check:a_i8 : 2 [Type: core::sync::atomic::AtomicI8] +// cdb-check: [] [Type: core::sync::atomic::AtomicI8] + +// cdb-command: dx a_i16 +// cdb-check:a_i16 : 4 [Type: core::sync::atomic::AtomicI16] +// cdb-check: [] [Type: core::sync::atomic::AtomicI16] + +// cdb-command: dx a_i32 +// cdb-check:a_i32 : 8 [Type: core::sync::atomic::AtomicI32] +// cdb-check: [] [Type: core::sync::atomic::AtomicI32] + +// cdb-command: dx a_i64 +// cdb-check:a_i64 : 16 [Type: core::sync::atomic::AtomicI64] +// cdb-check: [] [Type: core::sync::atomic::AtomicI64] + +// cdb-command: dx a_isize +// cdb-check:a_isize : 32 [Type: core::sync::atomic::AtomicIsize] +// cdb-check: [] [Type: core::sync::atomic::AtomicIsize] + +// cdb-command: dx a_u8 +// cdb-check:a_u8 : 0x40 [Type: core::sync::atomic::AtomicU8] +// cdb-check: [] [Type: core::sync::atomic::AtomicU8] + +// cdb-command: dx a_u16 +// cdb-check:a_u16 : 0x80 [Type: core::sync::atomic::AtomicU16] +// cdb-check: [] [Type: core::sync::atomic::AtomicU16] + +// cdb-command: dx a_u32 +// cdb-check:a_u32 : 0x100 [Type: core::sync::atomic::AtomicU32] +// cdb-check: [] [Type: core::sync::atomic::AtomicU32] + +// cdb-command: dx a_u64 +// cdb-check:a_u64 : 0x200 [Type: core::sync::atomic::AtomicU64] +// cdb-check: [] [Type: core::sync::atomic::AtomicU64] + +// cdb-command: dx a_usize +// cdb-check:a_usize : 0x400 [Type: core::sync::atomic::AtomicUsize] +// cdb-check: [] [Type: core::sync::atomic::AtomicUsize] + +use std::num::*; +use std::sync::atomic::*; + +fn main() { + let nz_i8 = NonZeroI8::new(11).unwrap(); + let nz_i16 = NonZeroI16::new(22).unwrap(); + let nz_i32 = NonZeroI32::new(33).unwrap(); + let nz_i64 = NonZeroI64::new(44).unwrap(); + let nz_i128 = NonZeroI128::new(55).unwrap(); + let nz_isize = NonZeroIsize::new(66).unwrap(); + + let nz_u8 = NonZeroU8::new(77).unwrap(); + let nz_u16 = NonZeroU16::new(88).unwrap(); + let nz_u32 = NonZeroU32::new(99).unwrap(); + let nz_u64 = NonZeroU64::new(100).unwrap(); + let nz_u128 = NonZeroU128::new(111).unwrap(); + let nz_usize = NonZeroUsize::new(122).unwrap(); + + let w_i8 = Wrapping(10i8); + let w_i16 = Wrapping(20i16); + let w_i32 = Wrapping(30i32); + let w_i64 = Wrapping(40i64); + let w_i128 = Wrapping(50i128); + let w_isize = Wrapping(60isize); + + let w_u8 = Wrapping(70u8); + let w_u16 = Wrapping(80u16); + let w_u32 = Wrapping(90u32); + let w_u64 = Wrapping(100u64); + let w_u128 = Wrapping(110u128); + let w_usize = Wrapping(120usize); + + let a_bool_t = AtomicBool::new(true); + let a_bool_f = AtomicBool::new(false); + + let a_i8 = AtomicI8::new(2); + let a_i16 = AtomicI16::new(4); + let a_i32 = AtomicI32::new(8); + let a_i64 = AtomicI64::new(16); + let a_isize = AtomicIsize::new(32); + + let a_u8 = AtomicU8::new(64); + let a_u16 = AtomicU16::new(128); + let a_u32 = AtomicU32::new(256); + let a_u64 = AtomicU64::new(512); + let a_usize = AtomicUsize::new(1024); + + zzz(); // #break +} + +fn zzz() { } diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs index 7ed76beb8c6d9..d5a6e148b7a66 100644 --- a/src/test/debuginfo/pretty-std.rs +++ b/src/test/debuginfo/pretty-std.rs @@ -111,8 +111,9 @@ // cdb-check: [11] : 33 '!' [Type: char] // cdb-command: dx os_string -// cdb-check:os_string [Type: [...]::OsString] -// NOTE: OsString doesn't have a .natvis entry yet. +// cdb-check:os_string : "IAMA OS string 😃" [Type: std::ffi::os_str::OsString] +// cdb-check: [] [Type: std::ffi::os_str::OsString] +// cdb-check: [chars] : "IAMA OS string 😃" // cdb-command: dx some // cdb-check:some : Some [Type: enum$ >] @@ -129,10 +130,24 @@ // NOTE: cdb fails to interpret debug info of Option enums on i686. // cdb-check:some_string [Type: enum$, 1, [...], Some>] +// cdb-command: dx linkedlist +// cdb-check:linkedlist : { len=0x2 } [Type: alloc::collections::linked_list::LinkedList] +// cdb-check: [] [Type: alloc::collections::linked_list::LinkedList] +// cdb-check: [0x0] : 128 [Type: int] +// cdb-check: [0x1] : 42 [Type: int] + +// cdb-command: dx vecdeque +// cdb-check:vecdeque : { len=0x2 } [Type: alloc::collections::vec_deque::VecDeque] +// cdb-check: [] [Type: alloc::collections::vec_deque::VecDeque] +// cdb-check: [len] : 0x2 +// cdb-check: [capacity] : 0x8 [Type: unsigned [...]] +// cdb-check: [0x0] : 90 [Type: int] +// cdb-check: [0x1] : 20 [Type: int] + #![allow(unused_variables)] +use std::collections::{LinkedList, VecDeque}; use std::ffi::OsString; - fn main() { // &[] @@ -156,6 +171,16 @@ fn main() { let some_string = Some("IAMA optional string!".to_owned()); + // LinkedList + let mut linkedlist = LinkedList::new(); + linkedlist.push_back(42); + linkedlist.push_front(128); + + // VecDeque + let mut vecdeque = VecDeque::new(); + vecdeque.push_back(20); + vecdeque.push_front(90); + zzz(); // #break } diff --git a/src/test/debuginfo/range-types.rs b/src/test/debuginfo/range-types.rs index c0288b6ba80e0..7362a50a03015 100644 --- a/src/test/debuginfo/range-types.rs +++ b/src/test/debuginfo/range-types.rs @@ -9,26 +9,27 @@ // cdb-command: g // cdb-command: dx r1,d -// cdb-check:r1,d [Type: core::ops::range::Range] -// cdb-check: [...] start : 3 [Type: int] -// cdb-check: [...] end : 5 [Type: int] +// cdb-check:r1,d : (3..5) [Type: core::ops::range::Range] +// cdb-check: [] [Type: core::ops::range::Range] // cdb-command: dx r2,d -// cdb-check:r2,d [Type: core::ops::range::RangeFrom] -// cdb-check: [...] start : 2 [Type: int] +// cdb-check:r2,d : (2..) [Type: core::ops::range::RangeFrom] +// cdb-check: [] [Type: core::ops::range::RangeFrom] // cdb-command: dx r3,d -// cdb-check:r3,d [Type: core::ops::range::RangeInclusive] -// cdb-check: [...] start : 1 [Type: int] -// cdb-check: [...] end : 4 [Type: int] -// cdb-check: [...] exhausted : false [Type: bool] +// cdb-check:r3,d : (1..=4) [Type: core::ops::range::RangeInclusive] +// cdb-check: [] [Type: core::ops::range::RangeInclusive] // cdb-command: dx r4,d -// cdb-check:r4,d [Type: core::ops::range::RangeToInclusive] -// cdb-check: [...] end : 3 [Type: int] +// cdb-check:r4,d : (..10) [Type: core::ops::range::RangeTo] +// cdb-check: [] [Type: core::ops::range::RangeTo] // cdb-command: dx r5,d -// cdb-check:r5,d [Type: core::ops::range::RangeFull] +// cdb-check:r5,d : (..=3) [Type: core::ops::range::RangeToInclusive] +// cdb-check: [] [Type: core::ops::range::RangeToInclusive] + +// cdb-command: dx r6,d +// cdb-check:r6,d [Type: core::ops::range::RangeFull] #[allow(unused_variables)] @@ -36,11 +37,12 @@ use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeToInclusive}; fn main() { - let r1 = Range{start: 3, end: 5}; - let r2 = RangeFrom{start: 2}; - let r3 = RangeInclusive::new(1, 4); - let r4 = RangeToInclusive{end: 3}; - let r5 = RangeFull{}; + let r1 = (3..5); + let r2 = (2..); + let r3 = (1..=4); + let r4 = (..10); + let r5 = (..=3); + let r6 = (..); zzz(); // #break } diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs index 6e558bd3c13aa..55cddf7c6c6b4 100644 --- a/src/test/debuginfo/rc_arc.rs +++ b/src/test/debuginfo/rc_arc.rs @@ -29,22 +29,39 @@ // cdb-command:dx r,d // cdb-check:r,d : 42 [Type: alloc::rc::Rc] +// cdb-check: [] [Type: alloc::rc::Rc] +// cdb-check: [Reference count] : 2 [Type: core::cell::Cell] +// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] // cdb-command:dx r1,d // cdb-check:r1,d : 42 [Type: alloc::rc::Rc] +// cdb-check: [] [Type: alloc::rc::Rc] +// cdb-check: [Reference count] : 2 [Type: core::cell::Cell] +// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] // cdb-command:dx w1,d -// cdb-check:w1,d [Type: alloc::rc::Weak] -// cdb-check: [...] ptr : [...] [Type: core::ptr::non_null::NonNull >] +// cdb-check:w1,d : 42 [Type: alloc::rc::Weak] +// cdb-check: [] [Type: alloc::rc::Weak] +// cdb-check: [Reference count] : 2 [Type: core::cell::Cell] +// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell] // cdb-command:dx a,d // cdb-check:a,d : 42 [Type: alloc::sync::Arc] +// cdb-check: [] [Type: alloc::sync::Arc] +// cdb-check: [Reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] // cdb-command:dx a1,d // cdb-check:a1,d : 42 [Type: alloc::sync::Arc] +// cdb-check: [] [Type: alloc::sync::Arc] +// cdb-check: [Reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] // cdb-command:dx w2,d // cdb-check:w2,d : 42 [Type: alloc::sync::Weak] +// cdb-check: [] [Type: alloc::sync::Weak] +// cdb-check: [Reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] use std::rc::Rc; use std::sync::Arc; diff --git a/src/test/debuginfo/rwlock-read.rs b/src/test/debuginfo/rwlock-read.rs index ac652c8ccf4cc..e1c10a4d37fc3 100644 --- a/src/test/debuginfo/rwlock-read.rs +++ b/src/test/debuginfo/rwlock-read.rs @@ -11,15 +11,15 @@ // cdb-command:dx l // cdb-check:l [Type: std::sync::rwlock::RwLock] // cdb-check: [...] poison [Type: std::sync::poison::Flag] -// cdb-check: [...] data [Type: core::cell::UnsafeCell] +// cdb-check: [...] data : 0 [Type: core::cell::UnsafeCell] // // cdb-command:dx r // cdb-check:r [Type: std::sync::rwlock::RwLockReadGuard] // cdb-check: [...] lock : [...] [Type: std::sync::rwlock::RwLock *] // // cdb-command:dx r.lock->data,d -// cdb-check:r.lock->data,d [Type: core::cell::UnsafeCell] -// cdb-check: [...] value : 0 [Type: int] +// cdb-check:r.lock->data,d : 0 [Type: core::cell::UnsafeCell] +// cdb-check: [] [Type: core::cell::UnsafeCell] #[allow(unused_variables)] diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml new file mode 100644 index 0000000000000..9a1442e48a9ea --- /dev/null +++ b/src/test/rustdoc-gui/sidebar-mobile.goml @@ -0,0 +1,10 @@ +// This test ensure that the sidebar isn't "hidden" on mobile but instead moved out of the viewport. +// This is especially important for devices for "text-first" content (like for users with +// sight issues). +goto: file://|DOC_PATH|/test_docs/struct.Foo.html +// Switching to "mobile view" by reducing the width to 600px. +size: (600, 600) +assert-css: (".sidebar-elems", {"display": "block", "left": "-246px"}) +// Opening the sidebar menu. +click: ".sidebar-menu" +assert-css: (".sidebar-elems", {"display": "block", "left": "0px"}) diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index ec8ab339e2804..0466909479b67 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -47,3 +47,10 @@ pub mod sub_mod { /// ``` pub struct Foo; } + +pub mod long_trait { + use std::ops::DerefMut; + + pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut + + From + Send + Sync + AsRef + 'static {} +} diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml new file mode 100644 index 0000000000000..0a316e220a42c --- /dev/null +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -0,0 +1,8 @@ +// This test ensures that the type declaration content overflow is handled inside the
 directly.
+goto: file://|DOC_PATH|/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// Logically, the  scroll width should be the width of the window.
+assert-property: ("body", {"scrollWidth": "1100"})
+// However, since there is overflow in the type declaration, its scroll width is bigger.
+assert-property: (".type-decl pre", {"scrollWidth": "1324"})
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.rs b/src/test/ui/closures/2229_closure_analysis/issue-87097.rs
new file mode 100644
index 0000000000000..241ddcb83e109
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-87097.rs
@@ -0,0 +1,35 @@
+// run-pass
+// edition:2021
+
+enum Variant {
+    A,
+    B, //~ WARNING: variant is never constructed: `B`
+}
+
+struct A {
+    field: Variant,
+}
+
+fn discriminant_is_a_ref() {
+    let here = A { field: Variant::A };
+    let out_ref = &here.field;
+
+    || match out_ref { //~ WARNING: unused closure that must be used
+        Variant::A => (),
+        Variant::B => (),
+    };
+}
+
+fn discriminant_is_a_field() {
+    let here = A { field: Variant::A };
+
+    || match here.field { //~ WARNING: unused closure that must be used
+        Variant::A => (),
+        Variant::B => (),
+    };
+}
+
+fn main() {
+    discriminant_is_a_ref();
+    discriminant_is_a_field();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/issue-87097.stderr
new file mode 100644
index 0000000000000..38f2929a05f2d
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-87097.stderr
@@ -0,0 +1,33 @@
+warning: variant is never constructed: `B`
+  --> $DIR/issue-87097.rs:6:5
+   |
+LL |     B,
+   |     ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: unused closure that must be used
+  --> $DIR/issue-87097.rs:17:5
+   |
+LL | /     || match out_ref {
+LL | |         Variant::A => (),
+LL | |         Variant::B => (),
+LL | |     };
+   | |______^
+   |
+   = note: `#[warn(unused_must_use)]` on by default
+   = note: closures are lazy and do nothing unless called
+
+warning: unused closure that must be used
+  --> $DIR/issue-87097.rs:26:5
+   |
+LL | /     || match here.field {
+LL | |         Variant::A => (),
+LL | |         Variant::B => (),
+LL | |     };
+   | |______^
+   |
+   = note: closures are lazy and do nothing unless called
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
index 3b284eadbd0e3..0e7abf64fab06 100644
--- a/src/test/ui/closures/2229_closure_analysis/move_closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
@@ -195,6 +195,21 @@ fn box_mut_2() {
     //~| NOTE: Min Capture p_foo[Deref,Deref,(0, 0)] -> UniqueImmBorrow
 }
 
+// Test that move closures can take ownership of Copy type
+fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 {
+    let x = 10;
+
+    let c = #[rustc_capture_analysis] move || x;
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 
+    //~| First Pass analysis includes:
+    //~| NOTE: Capturing x[] -> ImmBorrow
+    //~| Min Capture analysis includes:
+    //~| NOTE: Min Capture x[] -> ByValue
+
+    c
+}
+
 fn main() {
     simple_move_closure();
     simple_ref();
diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
index c8e2708feee31..82ed99f9444d3 100644
--- a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
@@ -88,6 +88,39 @@ LL |     let c = #[rustc_capture_analysis] move || p_foo.x += 10;
    = note: see issue #15701  for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:202:13
+   |
+LL |     let c = #[rustc_capture_analysis] move || x;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701  for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:202:39
+   |
+LL |     let c = #[rustc_capture_analysis] move || x;
+   |                                       ^^^^^^^^^
+   |
+note: Capturing x[] -> ImmBorrow
+  --> $DIR/move_closure.rs:202:47
+   |
+LL |     let c = #[rustc_capture_analysis] move || x;
+   |                                               ^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:202:39
+   |
+LL |     let c = #[rustc_capture_analysis] move || x;
+   |                                       ^^^^^^^^^
+   |
+note: Min Capture x[] -> ByValue
+  --> $DIR/move_closure.rs:202:47
+   |
+LL |     let c = #[rustc_capture_analysis] move || x;
+   |                                               ^
+
 error: First Pass analysis includes:
   --> $DIR/move_closure.rs:15:5
    |
@@ -424,6 +457,6 @@ note: Min Capture p_foo[Deref,Deref,(0, 0)] -> UniqueImmBorrow
 LL |     let c = #[rustc_capture_analysis] move || p_foo.x += 10;
    |                                               ^^^^^^^
 
-error: aborting due to 30 previous errors
+error: aborting due to 33 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
index 65c8a5a7850fe..e1b61e85ec192 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
@@ -3,6 +3,8 @@
 
 // Test that move closures compile properly with `capture_disjoint_fields` enabled.
 
+#![allow(unused)]
+
 fn simple_ref() {
     let mut s = 10;
     let ref_s = &mut s;
@@ -92,6 +94,15 @@ fn data_moved_but_not_fn_once() {
     c();
 }
 
+// Test that move closures can take ownership of Copy type
+fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 {
+    let x = 10;
+
+    let c = move || x;
+
+    c
+}
+
 fn main() {
     simple_ref();
     struct_contains_ref_to_another_struct();
@@ -100,4 +111,6 @@ fn main() {
 
     disjoint_via_ref();
     data_moved_but_not_fn_once();
+
+    returned_closure_owns_copy_type_data();
 }
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 3581ab41906f4..5f400d079da2f 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -11,7 +11,7 @@ use rustc_span::source_map::Span;
 use rustc_span::symbol::kw;
 use rustc_target::abi::LayoutOf;
 use rustc_target::spec::abi::Abi;
-use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
+use rustc_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 
 #[derive(Copy, Clone)]
 pub struct BoxedLocal {
@@ -133,13 +133,10 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
 }
 
 impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
-    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, mode: ConsumeMode) {
+    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
         if cmt.place.projections.is_empty() {
             if let PlaceBase::Local(lid) = cmt.place.base {
-                if let ConsumeMode::Move = mode {
-                    // moved out or in. clearly can't be localized
-                    self.set.remove(&lid);
-                }
+                self.set.remove(&lid);
                 let map = &self.cx.tcx.hir();
                 if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
                     if self.set.contains(&lid) {
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index d07b5a93b67c0..1e54a1e2de165 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -7,7 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::{mir::FakeReadCause, ty};
 use rustc_span::source_map::Span;
-use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
+use rustc_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 
 pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) {
     if let Some(higher::Range {
@@ -82,7 +82,7 @@ struct MutatePairDelegate<'a, 'tcx> {
 }
 
 impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
-    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ConsumeMode) {}
+    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {
         if let ty::BorrowKind::MutBorrow = bk {
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index e33a33e238633..57fd03f4e12a6 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -326,10 +326,8 @@ impl MovedVariablesCtxt {
 }
 
 impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
-    fn consume(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _: HirId, mode: euv::ConsumeMode) {
-        if let euv::ConsumeMode::Move = mode {
-            self.move_common(cmt);
-        }
+    fn consume(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _: HirId) {
+        self.move_common(cmt);
     }
 
     fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 182d8cb11ea80..ac885e9994404 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -10,7 +10,7 @@ use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty;
-use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
+use rustc_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 
 /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
 pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> Option {
@@ -67,7 +67,7 @@ impl<'tcx> MutVarsDelegate {
 }
 
 impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
-    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ConsumeMode) {}
+    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) {
         if let ty::BorrowKind::MutBorrow = bk {