Auto merge of #150115 - JonathanBrouwer:rollup-3gqipmq, r=JonathanBrouwer

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#149922 (Tidying up tests/ui/issues 14 tests [5/N])
 - rust-lang/rust#150095 (Port `#[rustc_no_implicit_autorefs]`, `#[rustc_lint_opt_ty]`, and `#[rustc_lint_query_instability]` attributes to be parsed)
 - rust-lang/rust#150099 ([rustdoc] Fix invalid handling of field followed by negated macro call)
 - rust-lang/rust#150113 (Update tracking issue for PinCoerceUnsized)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-12-17 23:31:32 +00:00
commit 686f9cefc3
44 changed files with 235 additions and 156 deletions

View file

@ -27,6 +27,21 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNeverReturnsNullPointerParser {
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNeverReturnsNullPointer;
}
pub(crate) struct RustcNoImplicitAutorefsParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitAutorefsParser {
const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitAutorefs;
}
pub(crate) struct RustcLayoutScalarValidRangeStartParser;
@ -102,6 +117,30 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
}
}
pub(crate) struct RustcLintOptTyParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintOptTyParser {
const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
}
pub(crate) struct RustcLintQueryInstabilityParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintQueryInstabilityParser {
const PATH: &[Symbol] = &[sym::rustc_lint_query_instability];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability;
}
pub(crate) struct RustcObjectLifetimeDefaultParser;
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {

View file

@ -61,7 +61,8 @@ use crate::attributes::prototype::CustomMirParser;
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser,
RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser,
RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser,
RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
RustcSimdMonomorphizeLaneLimitParser,
};
@ -255,8 +256,11 @@ attribute_parsers!(
Single<WithoutArgs<ProcMacroParser>>,
Single<WithoutArgs<PubTransparentParser>>,
Single<WithoutArgs<RustcCoherenceIsCoreParser>>,
Single<WithoutArgs<RustcLintOptTyParser>>,
Single<WithoutArgs<RustcLintQueryInstabilityParser>>,
Single<WithoutArgs<RustcMainParser>>,
Single<WithoutArgs<RustcNeverReturnsNullPointerParser>>,
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,
Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
Single<WithoutArgs<SpecializationTraitParser>>,

View file

@ -931,12 +931,21 @@ pub enum AttributeKind {
/// Represents `#[rustc_legacy_const_generics]`
RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span },
/// Represents `#[rustc_lint_opt_ty]`
RustcLintOptTy,
/// Represents `#[rustc_lint_query_instability]`
RustcLintQueryInstability,
/// Represents `#[rustc_main]`.
RustcMain,
/// Represents `#[rustc_never_returns_null_ptr]`
RustcNeverReturnsNullPointer,
/// Represents `#[rustc_no_implicit_autorefs]`
RustcNoImplicitAutorefs,
/// Represents `#[rustc_object_lifetime_default]`.
RustcObjectLifetimeDefault,

View file

@ -94,8 +94,11 @@ impl AttributeKind {
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
RustcLegacyConstGenerics { .. } => Yes,
RustcLintOptTy => Yes,
RustcLintQueryInstability => Yes,
RustcMain => No,
RustcNeverReturnsNullPointer => Yes,
RustcNoImplicitAutorefs => Yes,
RustcObjectLifetimeDefault => No,
RustcPassIndirectlyInNonRusticAbis(..) => No,
RustcScalableVector { .. } => Yes,

View file

@ -1,8 +1,8 @@
use rustc_ast::{BorrowKind, UnOp};
use rustc_hir::{Expr, ExprKind, Mutability};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::{Expr, ExprKind, Mutability, find_attr};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref};
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;
use crate::lints::{
ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin,
@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
_ => None,
}
&& method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true)
&& method_did.map(|did| find_attr!(cx.tcx.get_all_attrs(did), AttributeKind::RustcNoImplicitAutorefs)).unwrap_or(true)
{
cx.emit_span_lint(
DANGEROUS_IMPLICIT_AUTOREFS,

View file

@ -1,9 +1,10 @@
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
//! Clippy.
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, HirId};
use rustc_hir::{Expr, ExprKind, HirId, find_attr};
use rustc_middle::ty::{self, GenericArgsRef, PredicatePolarity, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::hygiene::{ExpnKind, MacroKind};
@ -90,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for QueryStability {
ty::Instance::try_resolve(cx.tcx, cx.typing_env(), callee_def_id, generic_args)
{
let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::RustcLintQueryInstability) {
cx.emit_span_lint(
POTENTIAL_QUERY_INSTABILITY,
span,
@ -150,7 +151,10 @@ fn has_unstable_into_iter_predicate<'tcx>(
};
// Does the input type's `IntoIterator` implementation have the
// `rustc_lint_query_instability` attribute on its `into_iter` method?
if cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_query_instability) {
if find_attr!(
cx.tcx.get_all_attrs(instance.def_id()),
AttributeKind::RustcLintQueryInstability
) {
return true;
}
}
@ -658,7 +662,7 @@ impl LateLintPass<'_> for BadOptAccess {
let Some(adt_def) = cx.typeck_results().expr_ty(base).ty_adt_def() else { return };
// Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be
// avoided.
if !cx.tcx.has_attr(adt_def.did(), sym::rustc_lint_opt_ty) {
if !find_attr!(cx.tcx.get_all_attrs(adt_def.did()), AttributeKind::RustcLintOptTy) {
return;
}

View file

@ -477,10 +477,6 @@ passes_rustc_lint_opt_deny_field_access =
`#[rustc_lint_opt_deny_field_access]` should be applied to a field
.label = not a field
passes_rustc_lint_opt_ty =
`#[rustc_lint_opt_ty]` should be applied to a struct
.label = not a struct
passes_rustc_pub_transparent =
attribute should be applied to `#[repr(transparent)]` types
.label = not a `#[repr(transparent)]` type

View file

@ -255,8 +255,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MacroUse { .. }
| AttributeKind::MacroEscape( .. )
| AttributeKind::NoLink
| AttributeKind::RustcNoImplicitAutorefs
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
| AttributeKind::RustcLintOptTy
| AttributeKind::RustcLintQueryInstability
| AttributeKind::RustcNeverReturnsNullPointer
| AttributeKind::RustcScalableVector { .. }
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
@ -305,19 +308,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_diagnostic_on_const(attr.span(), hir_id, target, item)
}
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
[sym::rustc_no_implicit_autorefs, ..] => {
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
}
[sym::rustc_lint_query_instability, ..] => {
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
}
[sym::rustc_lint_untracked_query_information, ..] => {
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
}
[sym::rustc_lint_diagnostics, ..] => {
self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
}
[sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),
[sym::rustc_lint_opt_deny_field_access, ..] => {
self.check_rustc_lint_opt_deny_field_access(attr, span, target)
}
@ -1255,16 +1251,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
/// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.
fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Target::Struct => {}
_ => {
self.dcx().emit_err(errors::RustcLintOptTy { attr_span: attr.span(), span });
}
}
}
/// Checks that the `#[rustc_lint_opt_deny_field_access]` attribute is only applied to a field.
fn check_rustc_lint_opt_deny_field_access(&self, attr: &Attribute, span: Span, target: Target) {
match target {

View file

@ -412,15 +412,6 @@ pub(crate) struct UnusedMultiple {
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(passes_rustc_lint_opt_ty)]
pub(crate) struct RustcLintOptTy {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_rustc_lint_opt_deny_field_access)]
pub(crate) struct RustcLintOptDenyFieldAccess {

View file

@ -2253,7 +2253,7 @@ impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Box<T, A> {}
// It is quite crucial that we only allow the `Global` allocator here.

View file

@ -2417,14 +2417,14 @@ impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
}
}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {}
//#[unstable(feature = "unique_rc_arc", issue = "112566")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
#[unstable(feature = "deref_pure_trait", issue = "87121")]

View file

@ -2423,10 +2423,10 @@ impl<T: ?Sized, A: Allocator> Deref for Arc<T, A> {
}
}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Arc<T, A> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
#[unstable(feature = "deref_pure_trait", issue = "87121")]
@ -4852,7 +4852,7 @@ impl<T: ?Sized, A: Allocator> Deref for UniqueArc<T, A> {
}
// #[unstable(feature = "unique_rc_arc", issue = "112566")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueArc<T> {}
#[unstable(feature = "unique_rc_arc", issue = "112566")]

View file

@ -2696,20 +2696,20 @@ fn assert_coerce_unsized(
let _: RefCell<&dyn Send> = d;
}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for UnsafeCell<T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for SyncUnsafeCell<T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for Cell<T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for RefCell<T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<'b, T: ?Sized> PinCoerceUnsized for Ref<'b, T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<'b, T: ?Sized> PinCoerceUnsized for RefMut<'b, T> {}

View file

@ -1825,7 +1825,7 @@ where
{
}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
/// Trait that indicates that this is a pointer or a wrapper for one, where
/// unsizing can be performed on the pointee when it is pinned.
///

View file

@ -176,7 +176,7 @@ impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> wh
#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: PointeeSized> PinCoerceUnsized for Unique<T> {}
#[unstable(feature = "ptr_internals", issue = "none")]

View file

@ -773,7 +773,7 @@ where
#[unstable(feature = "sgx_platform", issue = "56975")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {}
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")]
unsafe impl<T: ?Sized> PinCoerceUnsized for UserRef<T> {}
#[unstable(feature = "sgx_platform", issue = "56975")]

View file

@ -832,6 +832,20 @@ impl<'a> PeekIter<'a> {
.copied()
}
fn peek_next_if<F: Fn((TokenKind, &'a str)) -> bool>(
&mut self,
f: F,
) -> Option<(TokenKind, &'a str)> {
let next = self.peek_next()?;
if f(next) {
Some(next)
} else {
// We go one step back.
self.peek_pos -= 1;
None
}
}
fn stop_peeking(&mut self) {
self.peek_pos = 0;
}
@ -903,18 +917,17 @@ fn classify<'src>(
}
}
if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() {
let tokens = classifier.get_full_ident_path();
for &(token, start, end) in &tokens {
let text = &classifier.src[start..end];
classifier.advance(token, text, sink, start as u32);
classifier.byte_pos += text.len() as u32;
}
if !tokens.is_empty() {
continue;
}
}
if let Some((token, text, before)) = classifier.next() {
if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek()
&& let Some(nb_items) = classifier.get_full_ident_path()
{
let start = classifier.byte_pos as usize;
let len: usize = iter::from_fn(|| classifier.next())
.take(nb_items)
.map(|(_, text, _)| text.len())
.sum();
let text = &classifier.src[start..start + len];
classifier.advance(TokenKind::Ident, text, sink, start as u32);
} else if let Some((token, text, before)) = classifier.next() {
classifier.advance(token, text, sink, before);
} else {
break;
@ -957,47 +970,47 @@ impl<'src> Classifier<'src> {
}
/// Concatenate colons and idents as one when possible.
fn get_full_ident_path(&mut self) -> Vec<(TokenKind, usize, usize)> {
let start = self.byte_pos as usize;
let mut pos = start;
fn get_full_ident_path(&mut self) -> Option<usize> {
let mut has_ident = false;
let mut nb_items = 0;
loop {
let ret = loop {
let mut nb = 0;
while let Some((TokenKind::Colon, _)) = self.tokens.peek() {
self.tokens.next();
while self.tokens.peek_next_if(|(token, _)| token == TokenKind::Colon).is_some() {
nb += 1;
nb_items += 1;
}
// Ident path can start with "::" but if we already have content in the ident path,
// the "::" is mandatory.
if has_ident && nb == 0 {
return vec![(TokenKind::Ident, start, pos)];
break Some(nb_items);
} else if nb != 0 && nb != 2 {
if has_ident {
return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)];
// Following `;` will be handled on its own.
break Some(nb_items - 1);
} else {
return vec![(TokenKind::Colon, start, pos + nb)];
break None;
}
}
if let Some((TokenKind::Ident, text)) = self.tokens.peek()
if let Some((TokenKind::Ident, text)) =
self.tokens.peek_next_if(|(token, _)| token == TokenKind::Ident)
&& let symbol = Symbol::intern(text)
&& (symbol.is_path_segment_keyword() || !is_keyword(symbol))
{
// We only "add" the colon if there is an ident behind.
pos += text.len() + nb;
has_ident = true;
self.tokens.next();
nb_items += 1;
} else if nb > 0 && has_ident {
return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)];
} else if nb > 0 {
return vec![(TokenKind::Colon, start, start + nb)];
// Following `;` will be handled on its own.
break Some(nb_items - 1);
} else if has_ident {
return vec![(TokenKind::Ident, start, pos)];
break Some(nb_items);
} else {
return Vec::new();
break None;
}
}
};
self.tokens.stop_peeking();
ret
}
/// Wraps the tokens iteration to ensure that the `byte_pos` is always correct.
@ -1243,7 +1256,6 @@ impl<'src> Classifier<'src> {
Class::MacroNonTerminal
}
TokenKind::Ident => {
let file_span = self.file_span;
let span = || new_span(before, text, file_span);
match text {

View file

@ -0,0 +1,26 @@
// This test ensures that the macro expansion is correctly handled in cases like:
// `field: !f!`, because the `:` was simply not considered because of how paths
// are handled.
//@ compile-flags: -Zunstable-options --generate-macro-expansion
#![crate_name = "foo"]
//@ has 'src/foo/field-followed-by-exclamation.rs.html'
struct Bar {
bla: bool,
}
macro_rules! f {
() => {{ false }}
}
const X: Bar = Bar {
//@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'f!'
//@ has - '//*[@class="expansion"]/*[@class="original"]' 'f!()'
//@ has - '//*[@class="expansion"]/*[@class="expanded"]' '{ false }'
// It includes both original and expanded code.
//@ has - '//*[@class="expansion"]' ' bla: !{ false }f!()'
bla: !f!(),
};

View file

@ -709,12 +709,6 @@ Tests on type inference.
Tests for diagnostics on infinitely recursive types without indirection.
## `tests/ui/inherent-impls-overlap-check/`
Checks that repeating the same function names across separate `impl` blocks triggers an informative error, but not if the `impl` are for different types, such as `Bar<u8>` and `Bar<u16>`.
NOTE: This should maybe be a subdirectory within another related to duplicate definitions, such as `tests/ui/duplicate/`.
## `tests/ui/inline-const/`
These tests revolve around the inline `const` block that forces the compiler to const-eval its content.

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/34074>
//@ edition: 2015
//@ check-pass
// Make sure several unnamed function parameters don't conflict with each other
@ -7,5 +8,4 @@ trait Tr {
fn f(u8, u8) {}
}
fn main() {
}
fn main() {}

View file

@ -0,0 +1,10 @@
//! regression test for <https://github.com/rust-lang/rust/issues/21306>
//@ run-pass
use std::sync::Arc;
fn main() {
let x = 5;
let command = Arc::new(Box::new(|| x * 2));
assert_eq!(command(), 10);
}

View file

@ -0,0 +1,5 @@
//! regression test for <https://github.com/rust-lang/rust/issues/27268>
//@ run-pass
fn main() {
const _C: &'static dyn Fn() = &|| {};
}

View file

@ -1,6 +1,6 @@
//! regression test for <https://github.com/rust-lang/rust/issues/19097>
//@ check-pass
#![allow(dead_code)]
// regression test for #19097
struct Foo<T>(T);

View file

@ -1,11 +1,12 @@
//! regression test for <https://github.com/rust-lang/rust/issues/24161>
//@ check-pass
#![allow(dead_code)]
#[derive(Copy,Clone)]
#[derive(Copy, Clone)]
struct Functions {
a: fn(u32) -> u32,
b: extern "C" fn(u32) -> u32,
c: unsafe fn(u32) -> u32,
d: unsafe extern "C" fn(u32) -> u32
d: unsafe extern "C" fn(u32) -> u32,
}
pub fn main() {}

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/23036>
//@ run-pass
use std::collections::HashMap;

View file

@ -0,0 +1,16 @@
//! regression test for <https://github.com/rust-lang/rust/issues/20454>
//@ check-pass
#![allow(unused_must_use)]
use std::thread;
fn _foo() {
thread::spawn(move || {
// no need for -> ()
loop {
println!("hello");
}
})
.join();
}
fn main() {}

View file

@ -3,7 +3,7 @@
#![feature(rustc_attrs)]
#[rustc_lint_query_instability]
//~^ ERROR attribute should be applied to a function
//~^ ERROR `#[rustc_lint_query_instability]` attribute cannot be used on structs
struct Foo;
impl Foo {

View file

@ -1,17 +1,20 @@
error: malformed `rustc_lint_query_instability` attribute input
--> $DIR/query_stability_incorrect.rs:10:5
|
LL | #[rustc_lint_query_instability(a)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]`
error: attribute should be applied to a function definition
error: `#[rustc_lint_query_instability]` attribute cannot be used on structs
--> $DIR/query_stability_incorrect.rs:5:1
|
LL | #[rustc_lint_query_instability]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | struct Foo;
| ----------- not a function definition
|
= help: `#[rustc_lint_query_instability]` can only be applied to functions
error[E0565]: malformed `rustc_lint_query_instability` attribute input
--> $DIR/query_stability_incorrect.rs:10:5
|
LL | #[rustc_lint_query_instability(a)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#[rustc_lint_query_instability]`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0565`.

View file

@ -1,13 +0,0 @@
//@ check-pass
#![allow(unused_must_use)]
use std::thread;
fn _foo() {
thread::spawn(move || { // no need for -> ()
loop {
println!("hello");
}
}).join();
}
fn main() {}

View file

@ -1,9 +0,0 @@
//@ run-pass
use std::sync::Arc;
fn main() {
let x = 5;
let command = Arc::new(Box::new(|| { x*2 }));
assert_eq!(command(), 10);
}

View file

@ -1,11 +0,0 @@
//@ build-pass
#![allow(dead_code)]
#![allow(non_upper_case_globals)]
static foo: [usize; 3] = [1, 2, 3];
static slice_1: &'static [usize] = &foo;
static slice_2: &'static [usize] = &foo;
fn main() {}

View file

@ -1,4 +0,0 @@
//@ run-pass
fn main() {
const _C: &'static dyn Fn() = &||{};
}

View file

@ -1,9 +0,0 @@
//@ check-pass
fn main() {
assert!({false});
assert!(r"\u{41}" == "A");
assert!(r"\u{".is_empty());
}

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/29540>
//@ build-pass
#[derive(Debug)]
pub struct Config {

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/26646>
//@ check-pass
#![deny(unused_attributes)]
@ -9,4 +10,4 @@ pub struct Foo;
#[repr(C)]
pub struct Bar;
fn main() { }
fn main() {}

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/37686>
//@ run-pass
fn main() {
match (0, 0) {

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/38987>
//@ run-pass
fn main() {
let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128;

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/18352>
//@ run-pass
const X: &'static str = "12345";
@ -5,7 +6,7 @@ const X: &'static str = "12345";
fn test(s: String) -> bool {
match &*s {
X => true,
_ => false
_ => false,
}
}

View file

@ -0,0 +1,10 @@
//! regression test for <https://github.com/rust-lang/rust/issues/21891>
//@ build-pass
#![allow(dead_code)]
static FOO: [usize; 3] = [1, 2, 3];
static SLICE_1: &'static [usize] = &FOO;
static SLICE_2: &'static [usize] = &FOO;
fn main() {}

View file

@ -0,0 +1,10 @@
//! regression test for <https://github.com/rust-lang/rust/issues/50471>
//@ check-pass
fn main() {
assert!({ false });
assert!(r"\u{41}" == "A");
assert!(r"\u{".is_empty());
}