Auto merge of #126093 - cuviper:beta-next, r=cuviper

[beta] backports

- Fix insufficient logic when searching for the underlying allocation #124761
- Handle field projections like slice indexing in invalid_reference_casting #124908
- Handle Deref expressions in invalid_reference_casting #124978
- Fix ICE in non-operand `aggregate_raw_ptr` instrinsic codegen #125184
- Wrap Context.ext in AssertUnwindSafe #125392
- Revert problematic opaque type change #125489
- ast: Revert a breaking attribute visiting order change #125734
- Update to LLVM 18.1.7 #126061
- Revert "Disallow ambiguous attributes on expressions" on beta #126102 / #126101
- Silence double-symlink errors while building solaris toolchain #126011

r? cuviper
This commit is contained in:
bors 2024-06-07 11:26:27 +00:00
commit 7bb6510fc1
37 changed files with 511 additions and 251 deletions

View file

@ -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()
}

View file

@ -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);

View file

@ -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))
}
})
}

View file

@ -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

View file

@ -624,8 +624,6 @@ parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allo
parse_out_of_range_hex_escape = out of range hex escape
.label = must be a character in the range [\x00-\x7f]
parse_outer_attr_ambiguous = ambiguous outer attributes
parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches

View file

@ -495,15 +495,6 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse {
pub attributes: Span,
}
#[derive(Diagnostic)]
#[diag(parse_outer_attr_ambiguous)]
pub(crate) struct AmbiguousOuterAttributes {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub sugg: WrapInParentheses,
}
#[derive(Diagnostic)]
#[diag(parse_missing_in_in_for_loop)]
pub(crate) struct MissingInInForLoop {

View file

@ -327,9 +327,7 @@ impl<'a> Parser<'a> {
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
})?;
self.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
let span = lhs_span.to(rhs.span);
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
lhs = match op {
AssocOp::Add
| AssocOp::Subtract
@ -428,18 +426,6 @@ impl<'a> Parser<'a> {
});
}
fn error_ambiguous_outer_attrs(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) {
if let Some(attr) = lhs.attrs.iter().find(|a| a.style == AttrStyle::Outer) {
self.dcx().emit_err(errors::AmbiguousOuterAttributes {
span: attr.span.to(rhs_span),
sugg: errors::WrapInParentheses::Expression {
left: attr.span.shrink_to_lo(),
right: lhs_span.shrink_to_hi(),
},
});
}
}
/// Possibly translate the current token to an associative operator.
/// The method does not advance the current token.
///
@ -520,8 +506,7 @@ impl<'a> Parser<'a> {
None
};
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
self.error_ambiguous_outer_attrs(&lhs, lhs.span, rhs_span);
let span = lhs.span.to(rhs_span);
let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span);
let limits =
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
let range = self.mk_range(Some(lhs), rhs, limits);
@ -737,8 +722,7 @@ impl<'a> Parser<'a> {
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
) -> PResult<'a, P<Expr>> {
let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
this.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs))
this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
};
// Save the state of the parser before parsing type normally, in case there is a
@ -3829,6 +3813,16 @@ impl<'a> Parser<'a> {
self.mk_expr(span, ExprKind::Err(guar))
}
/// Create expression span ensuring the span of the parent node
/// is larger than the span of lhs and rhs, including the attributes.
fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) -> Span {
lhs.attrs
.iter()
.find(|a| a.style == AttrStyle::Outer)
.map_or(lhs_span, |a| a.span)
.to(rhs_span)
}
fn collect_tokens_for_expr(
&mut self,
attrs: AttrWrapper,

View file

@ -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`]
@ -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
@ -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,
}
@ -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(()),
};
@ -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 }
}
}

View file

@ -54,7 +54,7 @@ apt-get clean
# This makes all those symlinks.
for lib in $(find -name '*.so.*'); do
target=${lib%.so.*}.so
[ -e $target ] || ln -s ${lib##*/} $target
ln -s ${lib##*/} $target || echo "warning: silenced error symlinking $lib"
done
# Remove Solaris 11 functions that are optionally used by libbacktrace.

@ -1 +1 @@
Subproject commit b31c30a9bb4dbbd13c359d0e2bea7f65d20adf3f
Subproject commit 5a5152f653959d14d68613a3a8a033fb65eec021

View file

@ -16,7 +16,7 @@ fn foo(
fn skip_on_statements() {
#[rustfmt::skip]
{ 5+3; }
5+3;
}
#[rustfmt::skip]
@ -33,11 +33,11 @@ mod foo {
#[clippy::msrv = "1.29"]
fn msrv_1_29() {
#[cfg_attr(rustfmt, rustfmt::skip)]
{ 1+29; }
1+29;
}
#[clippy::msrv = "1.30"]
fn msrv_1_30() {
#[rustfmt::skip]
{ 1+30; }
1+30;
}

View file

@ -16,7 +16,7 @@ fn foo(
fn skip_on_statements() {
#[cfg_attr(rustfmt, rustfmt::skip)]
{ 5+3; }
5+3;
}
#[cfg_attr(rustfmt, rustfmt_skip)]
@ -33,11 +33,11 @@ mod foo {
#[clippy::msrv = "1.29"]
fn msrv_1_29() {
#[cfg_attr(rustfmt, rustfmt::skip)]
{ 1+29; }
1+29;
}
#[clippy::msrv = "1.30"]
fn msrv_1_30() {
#[cfg_attr(rustfmt, rustfmt::skip)]
{ 1+30; }
1+30;
}

View file

@ -1,35 +1,11 @@
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
LL | /// - first one
| ^^^^ 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
|
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:7:5
|
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:7:14
|
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:10:9
|
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:11:9
@ -49,5 +25,29 @@ error: using tabs in doc comments is not recommended
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:6:5
|
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:6:13
|
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:7:5
|
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:7:14
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: aborting due to 8 previous errors

View file

@ -214,8 +214,8 @@ type Os = NoSource;
// #3313
fn stmt_expr_attributes() {
let foo ;
(#[must_use]
foo) = false ;
#[must_use]
foo = false ;
}
// #3509

View file

@ -248,8 +248,8 @@ type Os = NoSource;
// #3313
fn stmt_expr_attributes() {
let foo;
(#[must_use]
foo) = false;
#[must_use]
foo = false;
}
// #3509

View file

@ -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);
}

View file

@ -13,17 +13,17 @@ fn syntax() {
let _ = #[attr] ();
let _ = #[attr] (#[attr] 0,);
let _ = #[attr] (#[attr] 0, 0);
let _ = (#[attr] 0) + #[attr] 0;
let _ = (#[attr] 0) / #[attr] 0;
let _ = (#[attr] 0) & #[attr] 0;
let _ = (#[attr] 0) % #[attr] 0;
let _ = #[attr] 0 + #[attr] 0;
let _ = #[attr] 0 / #[attr] 0;
let _ = #[attr] 0 & #[attr] 0;
let _ = #[attr] 0 % #[attr] 0;
let _ = #[attr] (0 + 0);
let _ = #[attr] !0;
let _ = #[attr] -0;
let _ = #[attr] false;
let _ = #[attr] 0;
let _ = #[attr] 'c';
let _ = (#[attr] x) as Y;
let _ = #[attr] x as Y;
let _ = #[attr] (x as Y);
let _ =
#[attr] while true {
@ -88,9 +88,9 @@ fn syntax() {
let _ = ();
foo
};
let _ = (#[attr] x) = y;
let _ = #[attr] x = y;
let _ = #[attr] (x = y);
let _ = (#[attr] x) += y;
let _ = #[attr] x += y;
let _ = #[attr] (x += y);
let _ = #[attr] foo.bar;
let _ = (#[attr] foo).bar;
@ -98,8 +98,8 @@ fn syntax() {
let _ = (#[attr] foo).0;
let _ = #[attr] foo[bar];
let _ = (#[attr] foo)[bar];
let _ = (#[attr] 0)..#[attr] 0;
let _ = (#[attr] 0)..;
let _ = #[attr] 0..#[attr] 0;
let _ = #[attr] 0..;
let _ = #[attr] (0..0);
let _ = #[attr] (0..);
let _ = #[attr] (..0);

View file

@ -147,13 +147,13 @@ fn _11() {
let _ = #[rustc_dummy] (0);
let _ = #[rustc_dummy] (0,);
let _ = #[rustc_dummy] (0, 0);
let _ = (#[rustc_dummy] 0) + #[rustc_dummy] 0;
let _ = #[rustc_dummy] 0 + #[rustc_dummy] 0;
let _ = #[rustc_dummy] !0;
let _ = #[rustc_dummy] -0i32;
let _ = #[rustc_dummy] false;
let _ = #[rustc_dummy] 'c';
let _ = #[rustc_dummy] 0;
let _ = (#[rustc_dummy] 0) as usize;
let _ = #[rustc_dummy] 0 as usize;
let _ =
#[rustc_dummy] while false {
#![rustc_dummy]
@ -213,8 +213,8 @@ fn _11() {
#![rustc_dummy]
};
let mut x = 0;
let _ = (#[rustc_dummy] x) = 15;
let _ = (#[rustc_dummy] x) += 15;
let _ = #[rustc_dummy] x = 15;
let _ = #[rustc_dummy] x += 15;
let s = Foo { data: () };
let _ = #[rustc_dummy] s.data;
let _ = (#[rustc_dummy] s).data;
@ -224,8 +224,8 @@ fn _11() {
let v = vec!(0);
let _ = #[rustc_dummy] v[0];
let _ = (#[rustc_dummy] v)[0];
let _ = (#[rustc_dummy] 0)..#[rustc_dummy] 0;
let _ = (#[rustc_dummy] 0)..;
let _ = #[rustc_dummy] 0..#[rustc_dummy] 0;
let _ = #[rustc_dummy] 0..;
let _ = #[rustc_dummy] (0..0);
let _ = #[rustc_dummy] (0..);
let _ = #[rustc_dummy] (..0);

View file

@ -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 {

View file

@ -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`
@ -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`.

View file

@ -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
}

View file

@ -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() {}

View file

@ -0,0 +1,122 @@
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:2:10
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:4:10
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_root` in this scope
--> $DIR/key-value-expansion-scope.rs:6:9
|
LL | #[doc = in_root!()]
| ^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:7:9
|
LL | #[doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod_escape` in this scope
--> $DIR/key-value-expansion-scope.rs:8:9
|
LL | #[doc = in_mod_escape!()]
| ^^^^^^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:9:9
|
LL | #[doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_root` in this scope
--> $DIR/key-value-expansion-scope.rs:11:14
|
LL | #![doc = in_root!()]
| ^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:12:14
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod_escape` in this scope
--> $DIR/key-value-expansion-scope.rs:13:14
|
LL | #![doc = in_mod_escape!()]
| ^^^^^^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:14:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:43:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:54:9
|
LL | #[doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:56:9
|
LL | #[doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:59:14
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:61:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: aborting due to 15 previous errors

View file

@ -1,13 +1,3 @@
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:7:1
|
@ -38,6 +28,16 @@ LL | #[optimize(banana)]
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:2:1
|

View file

@ -1,9 +1,3 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:14:9
|
@ -34,6 +28,12 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:7:1
|

View file

@ -1,9 +1,3 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:14:9
|
@ -34,6 +28,12 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:7:1
|

View file

@ -0,0 +1,59 @@
//! This test checks that we allow subtyping predicates that contain opaque types.
//! No hidden types are being constrained in the subtyping predicate, but type and
//! lifetime variables get subtyped in the generic parameter list of the opaque.
use std::iter;
mod either {
pub enum Either<L, R> {
Left(L),
Right(R),
}
impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> {
type Item = L::Item;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
pub use self::Either::{Left, Right};
}
pub enum BabeConsensusLogRef<'a> {
NextEpochData(BabeNextEpochRef<'a>),
NextConfigData,
}
impl<'a> BabeConsensusLogRef<'a> {
pub fn scale_encoding(
&self,
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
//~^ ERROR is not satisfied
//~| ERROR is not satisfied
//~| ERROR is not satisfied
match self {
BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left(
digest.scale_encoding().map(either::Left).map(either::Left),
)),
BabeConsensusLogRef::NextConfigData => either::Right(
// The Opaque type from ``scale_encoding` gets used opaquely here, while the `R`
// generic parameter of `Either` contains type variables that get subtyped and the
// opaque type contains lifetime variables that get subtyped.
iter::once(either::Right(either::Left([1])))
.chain(std::iter::once([1]).map(either::Right).map(either::Right)),
),
}
}
}
pub struct BabeNextEpochRef<'a>(&'a ());
impl<'a> BabeNextEpochRef<'a> {
pub fn scale_encoding(
&self,
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
std::iter::once([1])
}
}
fn main() {}

View file

@ -0,0 +1,21 @@
error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:10
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>`
error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:31
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:31
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -247,6 +247,27 @@ unsafe fn bigger_layout() {
unsafe fn from_ref(this: &i32) -> &i64 {
&*(this as *const i32 as *const i64)
}
// https://github.com/rust-lang/rust/issues/124685
unsafe fn slice_index(array: &mut [u8], offset: usize) {
let a1 = &mut array[offset];
let a2 = a1 as *mut u8;
let a3 = a2 as *mut u64;
unsafe { *a3 = 3 };
}
unsafe fn field_access(v: &mut Vec3<i32>) {
let r = &mut v.0;
let ptr = r as *mut i32 as *mut Vec3<i32>;
unsafe { *ptr = Vec3(0, 0, 0) }
}
unsafe fn deref(v: &mut Vec3<i32>) {
let r = &mut v.0;
let r = &mut *r;
let ptr = &mut *(r as *mut i32 as *mut Vec3<i32>);
unsafe { *ptr = Vec3(0, 0, 0) }
}
}
const RAW_PTR: *mut u8 = 1 as *mut u8;

View file

@ -20,10 +20,10 @@ fn doc_comment_between_if_else(num: u8) -> bool {
}
fn doc_comment_on_expr(num: u8) -> bool {
(/// useless doc comment
/// useless doc comment
//~^ ERROR: attributes on expressions are experimental
//~| ERROR: unused doc comment
num) == 3
num == 3
}
fn doc_comment_on_expr_field() -> bool {

View file

@ -5,10 +5,10 @@ LL | else {
| ^^^^ expected expression
error[E0658]: attributes on expressions are experimental
--> $DIR/unused-doc-comments-edge-cases.rs:23:6
--> $DIR/unused-doc-comments-edge-cases.rs:23:5
|
LL | (/// useless doc comment
| ^^^^^^^^^^^^^^^^^^^^^^^
LL | /// useless doc comment
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
@ -32,12 +32,12 @@ LL | #![deny(unused_doc_comments)]
| ^^^^^^^^^^^^^^^^^^^
error: unused doc comment
--> $DIR/unused-doc-comments-edge-cases.rs:23:6
--> $DIR/unused-doc-comments-edge-cases.rs:23:5
|
LL | (/// useless doc comment
| ^^^^^^^^^^^^^^^^^^^^^^^
LL | /// useless doc comment
| ^^^^^^^^^^^^^^^^^^^^^^^
...
LL | num) == 3
LL | num == 3
| --- rustdoc does not generate documentation for expressions
|
= help: use `//` for a plain comment

View file

@ -1,15 +0,0 @@
//@ run-rustfix
#![feature(stmt_expr_attributes)]
#![allow(unused_assignments, unused_attributes)]
fn main() {
let mut x = (#[deprecated] 1) + 2; //~ ERROR ambiguous
(#[deprecated] x) = 4; //~ ERROR ambiguous
x = (#[deprecated] 5) as i32; //~ ERROR ambiguous
let _r = (#[deprecated] 1)..6; //~ ERROR ambiguous
println!("{}", x);
}

View file

@ -1,15 +0,0 @@
//@ run-rustfix
#![feature(stmt_expr_attributes)]
#![allow(unused_assignments, unused_attributes)]
fn main() {
let mut x = #[deprecated] 1 + 2; //~ ERROR ambiguous
#[deprecated] x = 4; //~ ERROR ambiguous
x = #[deprecated] 5 as i32; //~ ERROR ambiguous
let _r = #[deprecated] 1..6; //~ ERROR ambiguous
println!("{}", x);
}

View file

@ -1,46 +0,0 @@
error: ambiguous outer attributes
--> $DIR/attr-binary-expr-ambigous.rs:6:17
|
LL | let mut x = #[deprecated] 1 + 2;
| ^^^^^^^^^^^^^^^^^^^
|
help: wrap the expression in parentheses
|
LL | let mut x = (#[deprecated] 1) + 2;
| + +
error: ambiguous outer attributes
--> $DIR/attr-binary-expr-ambigous.rs:8:5
|
LL | #[deprecated] x = 4;
| ^^^^^^^^^^^^^^^^^^^
|
help: wrap the expression in parentheses
|
LL | (#[deprecated] x) = 4;
| + +
error: ambiguous outer attributes
--> $DIR/attr-binary-expr-ambigous.rs:10:9
|
LL | x = #[deprecated] 5 as i32;
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: wrap the expression in parentheses
|
LL | x = (#[deprecated] 5) as i32;
| + +
error: ambiguous outer attributes
--> $DIR/attr-binary-expr-ambigous.rs:12:14
|
LL | let _r = #[deprecated] 1..6;
| ^^^^^^^^^^^^^^^^^^
|
help: wrap the expression in parentheses
|
LL | let _r = (#[deprecated] 1)..6;
| + +
error: aborting due to 4 previous errors

View file

@ -10,5 +10,6 @@ use test_macros::identity_attr;
fn main() {
let _x;
let y = ();
(#[identity_attr] _x) = y;
#[identity_attr]
_x = y;
}

View file

@ -0,0 +1,30 @@
#![feature(type_alias_impl_trait)]
//! This test used to ICE rust-lang/rust#124891
//! because we added an assertion for catching cases where opaque types get
//! registered during the processing of subtyping predicates.
type Tait = impl FnOnce() -> ();
fn reify_as_tait() -> Thunk<Tait> {
Thunk::new(|cont| cont)
//~^ ERROR: mismatched types
//~| ERROR: mismatched types
}
struct Thunk<F>(F);
impl<F> Thunk<F> {
fn new(f: F)
where
F: ContFn,
{
todo!();
}
}
trait ContFn {}
impl<F: FnOnce(Tait) -> ()> ContFn for F {}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0308]: mismatched types
--> $DIR/lazy_subtyping_of_opaques.rs:10:23
|
LL | type Tait = impl FnOnce() -> ();
| ------------------- the found opaque type
...
LL | Thunk::new(|cont| cont)
| ^^^^ expected `()`, found opaque type
|
= note: expected unit type `()`
found opaque type `Tait`
error[E0308]: mismatched types
--> $DIR/lazy_subtyping_of_opaques.rs:10:5
|
LL | fn reify_as_tait() -> Thunk<Tait> {
| ----------- expected `Thunk<_>` because of return type
LL | Thunk::new(|cont| cont)
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()`
|
= note: expected struct `Thunk<_>`
found unit type `()`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.