diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b14352d7f4ba0..7fc089d18f113 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1099,6 +1099,13 @@ impl<'a> Builder<'a> { if self.config.deny_warnings { rustflags.arg("-Dwarnings"); + + // FIXME(#58633) hide "unused attribute" errors in incremental + // builds of the standard library, as the underlying checks are + // not yet properly integrated with incremental recompilation. + if mode == Mode::Std && compiler.stage == 0 && self.config.incremental { + rustflags.arg("-Aunused-attributes"); + } } } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 23e39f433f53b..fd67b088c93cf 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -254,6 +254,14 @@ pub trait Machine<'mir, 'tcx>: Sized { kind: Option>, ) -> (Cow<'b, Allocation>, Self::PointerTag); + /// Called to notify the machine before a deallocation occurs. + fn before_deallocation( + _memory_extra: &mut Self::MemoryExtra, + _id: AllocId, + ) -> InterpResult<'tcx> { + Ok(()) + } + /// Return the "base" tag for the given *global* allocation: the one that is used for direct /// accesses to this static/const/fn allocation. If `id` is not a global allocation, /// this will return an unusable tag (i.e., accesses will be UB)! diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index c16c59715e40c..539537e9de80c 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -254,6 +254,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ); } + M::before_deallocation(&mut self.extra, ptr.alloc_id)?; + let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { Some(alloc) => alloc, None => { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index d25fd8ebb0c2b..033ba17f65855 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -721,15 +721,18 @@ fn compute_layout<'tcx>( _ => bug!(), }; + let param_env = tcx.param_env(source.def_id()); + for (local, decl) in body.local_decls.iter_enumerated() { // Ignore locals which are internal or not live if !live_locals.contains(local) || decl.internal { continue; } + let decl_ty = tcx.normalize_erasing_regions(param_env, decl.ty); // Sanity check that typeck knows about the type of locals which are // live across a suspension point - if !allowed.contains(&decl.ty) && !allowed_upvars.contains(&decl.ty) { + if !allowed.contains(&decl_ty) && !allowed_upvars.contains(&decl_ty) { span_bug!( body.span, "Broken MIR: generator contains type {} in MIR, \ diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 5de0184f2bba9..38d0c42e1588b 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -536,7 +536,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { match self.expr_ty.kind { ty::FnDef(..) => { // Attempt a coercion to a fn pointer type. - let f = self.expr_ty.fn_sig(fcx.tcx); + let f = fcx.normalize_associated_types_in( + self.expr.span, + &self.expr_ty.fn_sig(fcx.tcx), + ); let res = fcx.try_coerce( self.expr, self.expr_ty, diff --git a/src/test/ui/binding/issue-53114-borrow-checks.rs b/src/test/ui/binding/issue-53114-borrow-checks.rs new file mode 100644 index 0000000000000..7646472f45fac --- /dev/null +++ b/src/test/ui/binding/issue-53114-borrow-checks.rs @@ -0,0 +1,84 @@ +// Issue #53114: NLL's borrow check had some deviations from the old borrow +// checker, and both had some deviations from our ideal state. This test +// captures the behavior of how `_` bindings are handled with respect to how we +// flag expressions that are meant to request unsafe blocks. +#![allow(irrefutable_let_patterns)] +struct M; + +fn let_wild_gets_moved_expr() { + let m = M; + drop(m); + let _ = m; // accepted, and want it to continue to be + + let mm = (M, M); // variation on above with `_` in substructure + let (_x, _) = mm; + let (_, _y) = mm; + let (_, _) = mm; +} + +fn match_moved_expr_to_wild() { + let m = M; + drop(m); + match m { _ => { } } // #53114: should eventually be accepted too + //~^ ERROR [E0382] + + let mm = (M, M); // variation on above with `_` in substructure + match mm { (_x, _) => { } } + match mm { (_, _y) => { } } + //~^ ERROR [E0382] + match mm { (_, _) => { } } + //~^ ERROR [E0382] +} + +fn if_let_moved_expr_to_wild() { + let m = M; + drop(m); + if let _ = m { } // #53114: should eventually be accepted too + //~^ ERROR [E0382] + + let mm = (M, M); // variation on above with `_` in substructure + if let (_x, _) = mm { } + if let (_, _y) = mm { } + //~^ ERROR [E0382] + if let (_, _) = mm { } + //~^ ERROR [E0382] +} + +fn let_wild_gets_borrowed_expr() { + let mut m = M; + let r = &mut m; + let _ = m; // accepted, and want it to continue to be + // let _x = m; // (compare with this error.) + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + let (_, _) = mm; + drop((r1, r2)); +} + +fn match_borrowed_expr_to_wild() { + let mut m = M; + let r = &mut m; + match m { _ => {} } ; // accepted, and want it to continue to be + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + match mm { (_, _) => { } } + drop((r1, r2)); +} + +fn if_let_borrowed_expr_to_wild() { + let mut m = M; + let r = &mut m; + if let _ = m { } // accepted, and want it to continue to be + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + if let (_, _) = mm { } + drop((r1, r2)); +} + +fn main() { } diff --git a/src/test/ui/binding/issue-53114-borrow-checks.stderr b/src/test/ui/binding/issue-53114-borrow-checks.stderr new file mode 100644 index 0000000000000..2a7a721324d69 --- /dev/null +++ b/src/test/ui/binding/issue-53114-borrow-checks.stderr @@ -0,0 +1,65 @@ +error[E0382]: use of moved value: `m` + --> $DIR/issue-53114-borrow-checks.rs:22:11 + | +LL | let m = M; + | - move occurs because `m` has type `M`, which does not implement the `Copy` trait +LL | drop(m); + | - value moved here +LL | match m { _ => { } } // #53114: should eventually be accepted too + | ^ value used here after move + +error[E0382]: use of moved value: `mm` + --> $DIR/issue-53114-borrow-checks.rs:27:11 + | +LL | match mm { (_x, _) => { } } + | -- value moved here +LL | match mm { (_, _y) => { } } + | ^^ value used here after partial move + | + = note: move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `mm` + --> $DIR/issue-53114-borrow-checks.rs:29:11 + | +LL | match mm { (_, _y) => { } } + | -- value moved here +LL | +LL | match mm { (_, _) => { } } + | ^^ value used here after partial move + | + = note: move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `m` + --> $DIR/issue-53114-borrow-checks.rs:36:16 + | +LL | let m = M; + | - move occurs because `m` has type `M`, which does not implement the `Copy` trait +LL | drop(m); + | - value moved here +LL | if let _ = m { } // #53114: should eventually be accepted too + | ^ value used here after move + +error[E0382]: use of moved value: `mm` + --> $DIR/issue-53114-borrow-checks.rs:41:22 + | +LL | if let (_x, _) = mm { } + | -- value moved here +LL | if let (_, _y) = mm { } + | ^^ value used here after partial move + | + = note: move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `mm` + --> $DIR/issue-53114-borrow-checks.rs:43:21 + | +LL | if let (_, _y) = mm { } + | -- value moved here +LL | +LL | if let (_, _) = mm { } + | ^^ value used here after partial move + | + = note: move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/binding/issue-53114-safety-checks.rs b/src/test/ui/binding/issue-53114-safety-checks.rs new file mode 100644 index 0000000000000..28adb7571a98b --- /dev/null +++ b/src/test/ui/binding/issue-53114-safety-checks.rs @@ -0,0 +1,51 @@ +// Issue #53114: NLL's borrow check had some deviations from the old borrow +// checker, and both had some deviations from our ideal state. This test +// captures the behavior of how `_` bindings are handled with respect to how we +// flag expressions that are meant to request unsafe blocks. + +#![feature(untagged_unions)] + +struct I(i64); +struct F(f64); + +union U { a: I, b: F } + +#[repr(packed)] +struct P { + a: &'static i8, + b: &'static u32, +} + +fn let_wild_gets_unsafe_field() { + let u1 = U { a: I(0) }; + let u2 = U { a: I(1) }; + let p = P { a: &2, b: &3 }; + let _ = &p.b; //~ WARN E0133 + //~^ WARN will become a hard error + let _ = u1.a; // #53114: should eventually signal error as well + let _ = &u2.a; //~ ERROR [E0133] + + // variation on above with `_` in substructure + let (_,) = (&p.b,); //~ WARN E0133 + //~^ WARN will become a hard error + let (_,) = (u1.a,); //~ ERROR [E0133] + let (_,) = (&u2.a,); //~ ERROR [E0133] +} + +fn match_unsafe_field_to_wild() { + let u1 = U { a: I(0) }; + let u2 = U { a: I(1) }; + let p = P { a: &2, b: &3 }; + match &p.b { _ => { } } //~ WARN E0133 + //~^ WARN will become a hard error + match u1.a { _ => { } } //~ ERROR [E0133] + match &u2.a { _ => { } } //~ ERROR [E0133] + + // variation on above with `_` in substructure + match (&p.b,) { (_,) => { } } //~ WARN E0133 + //~^ WARN will become a hard error + match (u1.a,) { (_,) => { } } //~ ERROR [E0133] + match (&u2.a,) { (_,) => { } } //~ ERROR [E0133] +} + +fn main() { } diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr new file mode 100644 index 0000000000000..fc714a78bf648 --- /dev/null +++ b/src/test/ui/binding/issue-53114-safety-checks.stderr @@ -0,0 +1,100 @@ +warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) + --> $DIR/issue-53114-safety-checks.rs:23:13 + | +LL | let _ = &p.b; + | ^^^^ + | + = note: `#[warn(safe_packed_borrows)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46043 + = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:26:13 + | +LL | let _ = &u2.a; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) + --> $DIR/issue-53114-safety-checks.rs:29:17 + | +LL | let (_,) = (&p.b,); + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46043 + = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:31:17 + | +LL | let (_,) = (u1.a,); + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:32:17 + | +LL | let (_,) = (&u2.a,); + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) + --> $DIR/issue-53114-safety-checks.rs:39:11 + | +LL | match &p.b { _ => { } } + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46043 + = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:41:11 + | +LL | match u1.a { _ => { } } + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:42:11 + | +LL | match &u2.a { _ => { } } + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) + --> $DIR/issue-53114-safety-checks.rs:45:12 + | +LL | match (&p.b,) { (_,) => { } } + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46043 + = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:47:12 + | +LL | match (u1.a,) { (_,) => { } } + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:48:12 + | +LL | match (&u2.a,) { (_,) => { } } + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/issues/issue-54094.rs b/src/test/ui/issues/issue-54094.rs new file mode 100644 index 0000000000000..ec38dc40e610a --- /dev/null +++ b/src/test/ui/issues/issue-54094.rs @@ -0,0 +1,14 @@ +// check-pass +trait Zoo { + type X; +} + +impl Zoo for u16 { + type X = usize; +} + +fn foo(abc: ::X) {} + +fn main() { + let x: *const u8 = foo as _; +} diff --git a/src/test/ui/repeat_count_const_in_async_fn.rs b/src/test/ui/repeat_count_const_in_async_fn.rs new file mode 100644 index 0000000000000..ebabc3fbf10f9 --- /dev/null +++ b/src/test/ui/repeat_count_const_in_async_fn.rs @@ -0,0 +1,10 @@ +// check-pass +// edition:2018 +// compile-flags: --crate-type=lib + +pub async fn test() { + const C: usize = 4; + foo(&mut [0u8; C]).await; +} + +async fn foo(_: &mut [u8]) {}