Skip to content

Commit

Permalink
Auto merge of rust-lang#126093 - cuviper:beta-next, r=cuviper
Browse files Browse the repository at this point in the history
[beta] backports

- Fix insufficient logic when searching for the underlying allocation rust-lang#124761
- Handle field projections like slice indexing in invalid_reference_casting rust-lang#124908
- Handle Deref expressions in invalid_reference_casting rust-lang#124978
- Fix ICE in non-operand `aggregate_raw_ptr` instrinsic codegen rust-lang#125184
- Wrap Context.ext in AssertUnwindSafe rust-lang#125392
- Revert problematic opaque type change rust-lang#125489
- ast: Revert a breaking attribute visiting order change rust-lang#125734
- Update to LLVM 18.1.7 rust-lang#126061

r? cuviper
  • Loading branch information
bors committed Jun 7, 2024
2 parents 81ed1ce + ac45caa commit 49f3109
Show file tree
Hide file tree
Showing 21 changed files with 458 additions and 106 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,10 +826,10 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
ctxt: AssocCtxt,
) -> V::Result {
let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident));
try_visit!(kind.walk(item, ctxt, visitor));
walk_list!(visitor, visit_attribute, attrs);
V::Result::output()
}

Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.write_operand_repeatedly(cg_elem, count, dest);
}

mir::Rvalue::Aggregate(ref kind, ref operands) => {
// This implementation does field projection, so never use it for `RawPtr`,
// which will always be fine with the `codegen_rvalue_operand` path below.
mir::Rvalue::Aggregate(ref kind, ref operands)
if !matches!(**kind, mir::AggregateKind::RawPtr(..)) =>
{
let (variant_index, variant_dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
let variant_dest = dest.project_downcast(bx, variant_index);
Expand Down
17 changes: 2 additions & 15 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,27 +945,14 @@ impl<'tcx> InferCtxt<'tcx> {
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
return Err((a_vid, b_vid));
}
// We don't silently want to constrain hidden types here, so we assert that either one side is
// an infer var, so it'll get constrained to whatever the other side is, or there are no opaque
// types involved.
// We don't expect this to actually get hit, but if it does, we now at least know how to write
// a test for it.
(_, ty::Infer(ty::TyVar(_))) => {}
(ty::Infer(ty::TyVar(_)), _) => {}
_ if r_a != r_b && (r_a, r_b).has_opaque_types() => {
span_bug!(
cause.span(),
"opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}"
)
}
_ => {}
}

self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
if a_is_expected {
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
} else {
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
}
})
}
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_lint/src/reference_casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
let e_alloc = cx.expr_or_init(e);
let e_alloc =
if let ExprKind::AddrOf(_, _, inner_expr) = e_alloc.kind { inner_expr } else { e_alloc };

// if the current expr looks like this `&mut expr[index]` then just looking
// at `expr[index]` won't give us the underlying allocation, so we just skip it
// the same logic applies field access `&mut expr.field` and reborrows `&mut *expr`.
if let ExprKind::Index(..) | ExprKind::Field(..) | ExprKind::Unary(UnOp::Deref, ..) =
e_alloc.kind
{
return None;
}

let alloc_ty = cx.typeck_results().node_type(e_alloc.hir_id);

// if we do not find it we bail out, as this may not be UB
Expand Down
11 changes: 7 additions & 4 deletions library/core/src/task/wake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::mem::transmute;
use crate::any::Any;
use crate::fmt;
use crate::marker::PhantomData;
use crate::panic::AssertUnwindSafe;
use crate::ptr;

/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
Expand Down Expand Up @@ -236,7 +237,7 @@ enum ExtData<'a> {
pub struct Context<'a> {
waker: &'a Waker,
local_waker: &'a LocalWaker,
ext: ExtData<'a>,
ext: AssertUnwindSafe<ExtData<'a>>,
// Ensure we future-proof against variance changes by forcing
// the lifetime to be invariant (argument-position lifetimes
// are contravariant while return-position lifetimes are
Expand Down Expand Up @@ -279,7 +280,9 @@ impl<'a> Context<'a> {
#[unstable(feature = "context_ext", issue = "123392")]
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
pub const fn ext(&mut self) -> &mut dyn Any {
match &mut self.ext {
// FIXME: this field makes Context extra-weird about unwind safety
// can we justify AssertUnwindSafe if we stabilize this? do we care?
match &mut *self.ext {
ExtData::Some(data) => *data,
ExtData::None(unit) => unit,
}
Expand Down Expand Up @@ -353,7 +356,7 @@ impl<'a> ContextBuilder<'a> {
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
#[unstable(feature = "context_ext", issue = "123392")]
pub const fn from(cx: &'a mut Context<'_>) -> Self {
let ext = match &mut cx.ext {
let ext = match &mut *cx.ext {
ExtData::Some(ext) => ExtData::Some(*ext),
ExtData::None(()) => ExtData::None(()),
};
Expand Down Expand Up @@ -396,7 +399,7 @@ impl<'a> ContextBuilder<'a> {
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
pub const fn build(self) -> Context<'a> {
let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self;
Context { waker, local_waker, ext, _marker, _marker2 }
Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 }
}
}

Expand Down
48 changes: 24 additions & 24 deletions src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:5
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
LL | /// - first one
| ^^^^ help: consider using four spaces per tab
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:13
--> tests/ui/tabs_in_doc_comments.rs:11:9
|
LL | /// - first one
| ^^^^^^^^ help: consider using four spaces per tab
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:5
--> tests/ui/tabs_in_doc_comments.rs:14:9
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
LL | /// - Second String:
| ^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:14
--> tests/ui/tabs_in_doc_comments.rs:15:9
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:10:9
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
LL | /// - first one
| ^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:11:9
--> tests/ui/tabs_in_doc_comments.rs:6:13
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
LL | /// - first one
| ^^^^^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:14:9
--> tests/ui/tabs_in_doc_comments.rs:7:5
|
LL | /// - Second String:
| ^^^^ help: consider using four spaces per tab
LL | /// - second one
| ^^^^ help: consider using four spaces per tab

error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:15:9
--> tests/ui/tabs_in_doc_comments.rs:7:14
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
LL | /// - second one
| ^^^^ help: consider using four spaces per tab

error: aborting due to 8 previous errors

23 changes: 23 additions & 0 deletions tests/codegen/intrinsics/aggregate-thin-pointer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ compile-flags: -O -C no-prepopulate-passes -Z mir-enable-passes=-InstSimplify
//@ only-64bit (so I don't need to worry about usize)

#![crate_type = "lib"]
#![feature(core_intrinsics)]

use std::intrinsics::aggregate_raw_ptr;

// InstSimplify replaces these with casts if it can, which means they're almost
// never seen in codegen, but PR#121571 found a way, so add a test for it.

#[inline(never)]
pub fn opaque(_p: &*const i32) {}

// CHECK-LABEL: @thin_ptr_via_aggregate(
#[no_mangle]
pub unsafe fn thin_ptr_via_aggregate(p: *const ()) {
// CHECK: %mem = alloca
// CHECK: store ptr %p, ptr %mem
// CHECK: call {{.+}}aggregate_thin_pointer{{.+}} %mem)
let mem = aggregate_raw_ptr(p, ());
opaque(&mem);
}
1 change: 0 additions & 1 deletion tests/ui/async-await/async-is-unwindsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ fn main() {

is_unwindsafe(async {
//~^ ERROR the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
//~| ERROR the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
use std::ptr::null;
use std::task::{Context, RawWaker, RawWakerVTable, Waker};
let waker = unsafe {
Expand Down
43 changes: 6 additions & 37 deletions tests/ui/async-await/async-is-unwindsafe.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ LL | is_unwindsafe(async {
| |_____|
| ||
LL | ||
LL | ||
LL | || use std::ptr::null;
LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker};
... ||
LL | || drop(cx_ref);
LL | || });
| ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
| |_____|
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
|
= help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}: UnwindSafe`
= help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}: UnwindSafe`
= note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
note: future does not implement `UnwindSafe` as this value is used across an await
--> $DIR/async-is-unwindsafe.rs:26:18
--> $DIR/async-is-unwindsafe.rs:25:18
|
LL | let cx_ref = &mut cx;
| ------ has type `&mut Context<'_>` which does not implement `UnwindSafe`
Expand All @@ -30,38 +31,6 @@ note: required by a bound in `is_unwindsafe`
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`

error[E0277]: the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
--> $DIR/async-is-unwindsafe.rs:12:5
|
LL | is_unwindsafe(async {
| _____^_____________-
| |_____|
| ||
LL | ||
LL | ||
LL | || use std::ptr::null;
... ||
LL | || drop(cx_ref);
LL | || });
| ||_____-^ `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
| |_____|
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`
|
= help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`, the trait `UnwindSafe` is not implemented for `&mut (dyn Any + 'static)`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}: UnwindSafe`
note: future does not implement `UnwindSafe` as this value is used across an await
--> $DIR/async-is-unwindsafe.rs:26:18
|
LL | let mut cx = Context::from_waker(&waker);
| ------ has type `Context<'_>` which does not implement `UnwindSafe`
...
LL | async {}.await; // this needs an inner await point
| ^^^^^ await occurs here, with `mut cx` maybe used later
note: required by a bound in `is_unwindsafe`
--> $DIR/async-is-unwindsafe.rs:3:26
|
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
14 changes: 14 additions & 0 deletions tests/ui/async-await/context-is-sorta-unwindsafe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ run-pass
// Tests against a regression surfaced by crater in https://github.com/rust-lang/rust/issues/125193
// Unwind Safety is not a very coherent concept, but we'd prefer no regressions until we kibosh it
// and this is an unstable feature anyways sooo...

use std::panic::UnwindSafe;
use std::task::Context;

fn unwind_safe<T: UnwindSafe>() {}

fn main() {
unwind_safe::<Context<'_>>(); // test UnwindSafe
unwind_safe::<&Context<'_>>(); // test RefUnwindSafe
}
64 changes: 64 additions & 0 deletions tests/ui/attributes/key-value-expansion-scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#![doc = in_root!()] // FIXME, this is a bug
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] // FIXME, this is a bug
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope

#[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
fn before() {
#![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
}

macro_rules! in_root { () => { "" } }

mod macros_stay {
#![doc = in_mod!()] // FIXME, this is a bug

macro_rules! in_mod { () => { "" } }

#[doc = in_mod!()] // OK
fn f() {
#![doc = in_mod!()] // OK
}
}

#[macro_use]
mod macros_escape {
#![doc = in_mod_escape!()] // FIXME, this is a bug

macro_rules! in_mod_escape { () => { "" } }

#[doc = in_mod_escape!()] // OK
fn f() {
#![doc = in_mod_escape!()] // OK
}
}

fn block() {
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope

macro_rules! in_block { () => { "" } }

#[doc = in_block!()] // OK
fn f() {
#![doc = in_block!()] // OK
}
}

#[doc = in_root!()] // OK
#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#[doc = in_mod_escape!()] // OK
#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
fn after() {
#![doc = in_root!()] // OK
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] // OK
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
}

fn main() {}
Loading

0 comments on commit 49f3109

Please sign in to comment.