Auto merge of #126914 - compiler-errors:rollup-zx0hchm, r=compiler-errors

Rollup of 11 pull requests

Successful merges:

 - #124460 (Show notice about  "never used" of Debug for enum)
 - #124712 (Deprecate no-op codegen option `-Cinline-threshold=...`)
 - #125082 (Remove `MaybeUninit::uninit_array()` and replace it with inline const blocks.)
 - #125575 (SmartPointer derive-macro)
 - #126413 (compiletest: make the crash test error message abit more informative)
 - #126673 (Ensure we don't accidentally succeed when we want to report an error)
 - #126682 (coverage: Overhaul validation of the `#[coverage(..)]` attribute)
 - #126899 (Suggest inline const blocks for array initialization)
 - #126904 (Small fixme in core now that NonZero is generic)
 - #126909 (add `@kobzol` to bootstrap team for triagebot)
 - #126911 (Split the lifetimes of `MirBorrowckCtxt`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-06-24 21:33:02 +00:00
commit 6b0f4b5ec3
82 changed files with 1195 additions and 589 deletions

View File

@ -6,7 +6,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.infcx.dcx()
}

View File

@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> {
pub(crate) fn report_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion,
error_element: RegionElement,
cause: ObligationCause<'tcx>,
@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> {
fn nice_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> {
#[instrument(level = "debug", skip(self, mbcx))]
fn report_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion,
error_element: RegionElement,
cause: ObligationCause<'tcx>,
@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
fn nice_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
@ -270,7 +270,7 @@ where
fn nice_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
fn nice_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
@ -336,7 +336,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
fn nice_error(
&self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
_cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,

View File

@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> {
Destructor(Ty<'tcx>),
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub(crate) fn report_use_of_moved_or_uninitialized(
&mut self,
location: Location,
@ -4243,7 +4243,11 @@ enum AnnotatedBorrowFnSignature<'tcx> {
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
/// Annotate the provided diagnostic with information about borrow from the fn signature that
/// helps explain.
pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, 'tcx>, diag: &mut Diag<'_>) -> String {
pub(crate) fn emit(
&self,
cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>,
diag: &mut Diag<'_>,
) -> String {
match self {
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
diag.span_label(

View File

@ -389,7 +389,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
}
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
fn free_region_constraint_info(
&self,
borrow_region: RegionVid,

View File

@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt {
pub(super) struct IncludingTupleField(pub(super) bool);
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
/// is moved after being invoked.
///
@ -771,7 +771,7 @@ struct CapturedMessageOpt {
maybe_reinitialized_locations_is_empty: bool,
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Finds the spans associated to a move or copy of move_place at location.
pub(super) fn move_spans(
&self,

View File

@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> {
},
}
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub(crate) fn report_move_errors(&mut self) {
let grouped_errors = self.group_move_errors();
for error in grouped_errors {

View File

@ -30,7 +30,7 @@ pub(crate) enum AccessKind {
Mutate,
}
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub(crate) fn report_mutability_error(
&mut self,
access_place: Place<'tcx>,

View File

@ -75,7 +75,7 @@ impl OutlivesSuggestionBuilder {
/// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
fn region_vid_to_name(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
region: RegionVid,
) -> Option<RegionName> {
mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable)
@ -84,7 +84,7 @@ impl OutlivesSuggestionBuilder {
/// Compiles a list of all suggestions to be printed in the final big suggestion.
fn compile_all_suggestions(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
) -> SmallVec<[SuggestedConstraint; 2]> {
let mut suggested = SmallVec::new();
@ -160,7 +160,7 @@ impl OutlivesSuggestionBuilder {
/// Emit an intermediate note on the given `Diag` if the involved regions are suggestable.
pub(crate) fn intermediate_suggestion(
&mut self,
mbcx: &MirBorrowckCtxt<'_, '_>,
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
errci: &ErrorConstraintInfo<'_>,
diag: &mut Diag<'_>,
) {
@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder {
/// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
/// suggestion including all collected constraints.
pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) {
// No constraints to add? Done.
if self.constraints_to_add.is_empty() {
debug!("No constraints to suggest.");

View File

@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> {
pub(super) span: Span,
}
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is

View File

@ -198,7 +198,7 @@ impl rustc_errors::IntoDiagArg for RegionName {
}
}
impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
self.body.source.def_id().expect_local()
}

View File

@ -310,11 +310,11 @@ fn do_mir_borrowck<'tcx>(
promoted_mbcx.report_move_errors();
diags = promoted_mbcx.diags;
struct MoveVisitor<'a, 'cx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'cx, 'tcx>,
struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>,
}
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> {
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
if let Operand::Move(place) = operand {
self.ctxt.check_movable_place(location, *place);
@ -528,15 +528,15 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
}
}
struct MirBorrowckCtxt<'cx, 'tcx> {
struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
infcx: &'cx BorrowckInferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
body: &'cx Body<'tcx>,
move_data: &'cx MoveData<'tcx>,
body: &'mir Body<'tcx>,
move_data: &'a MoveData<'tcx>,
/// Map from MIR `Location` to `LocationIndex`; created
/// when MIR borrowck begins.
location_table: &'cx LocationTable,
location_table: &'a LocationTable,
movable_coroutine: bool,
/// This keeps track of whether local variables are free-ed when the function
@ -605,14 +605,16 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
// 2. loans made in overlapping scopes do not conflict
// 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way
impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorrowckCtxt<'cx, 'tcx> {
type FlowState = Flows<'cx, 'tcx>;
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'_, 'mir, '_, 'tcx>
{
type FlowState = Flows<'mir, 'tcx>;
fn visit_statement_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'cx, 'tcx>,
stmt: &'cx Statement<'tcx>,
flow_state: &Flows<'mir, 'tcx>,
stmt: &'mir Statement<'tcx>,
location: Location,
) {
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
@ -681,8 +683,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
fn visit_terminator_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'cx, 'tcx>,
term: &'cx Terminator<'tcx>,
flow_state: &Flows<'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
@ -792,8 +794,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
fn visit_terminator_after_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'cx, 'tcx>,
term: &'cx Terminator<'tcx>,
flow_state: &Flows<'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
let span = term.source_info.span;
@ -969,8 +971,8 @@ impl InitializationRequiringAction {
}
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn body(&self) -> &'cx Body<'tcx> {
impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn body(&self) -> &'mir Body<'tcx> {
self.body
}
@ -986,7 +988,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
let (sd, rw) = kind;
@ -1036,7 +1038,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_span: (Place<'tcx>, Span),
sd: AccessDepth,
rw: ReadOrWrite,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) -> bool {
let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set);
@ -1177,7 +1179,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
place_span: (Place<'tcx>, Span),
kind: AccessDepth,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
// Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
@ -1194,8 +1196,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn consume_rvalue(
&mut self,
location: Location,
(rvalue, span): (&'cx Rvalue<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
) {
match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
@ -1452,8 +1454,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn consume_operand(
&mut self,
location: Location,
(operand, span): (&'cx Operand<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
(operand, span): (&'mir Operand<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
) {
match *operand {
Operand::Copy(place) => {
@ -1573,7 +1575,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'cx, 'tcx>) {
fn check_activations(
&mut self,
location: Location,
span: Span,
flow_state: &Flows<'mir, 'tcx>,
) {
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
// another borrow.
@ -1736,7 +1743,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;
@ -1841,7 +1848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;
@ -1940,7 +1947,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&mut self,
location: Location,
(place, span): (Place<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
debug!("check_if_assigned_path_is_moved place: {:?}", place);
@ -2001,12 +2008,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
fn check_parent_of_field<'cx, 'tcx>(
this: &mut MirBorrowckCtxt<'cx, 'tcx>,
fn check_parent_of_field<'mir, 'tcx>(
this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>,
location: Location,
base: PlaceRef<'tcx>,
span: Span,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) {
// rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we
@ -2097,7 +2104,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(place, span): (Place<'tcx>, Span),
kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
location: Location,
) -> bool {
debug!(
@ -2213,7 +2220,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn is_local_ever_initialized(
&self,
local: Local,
flow_state: &Flows<'cx, 'tcx>,
flow_state: &Flows<'mir, 'tcx>,
) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?;
let ii = &self.move_data.init_path_map[mpi];
@ -2221,7 +2228,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
/// Adds the place into the used mutable variables set
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'cx, 'tcx>) {
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) {
match root_place {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being
@ -2476,7 +2483,7 @@ mod diags {
}
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn buffer_error(&mut self, diag: Diag<'tcx>) {
self.diags.buffer_error(diag);
}

View File

@ -34,7 +34,7 @@ pub(super) enum PrefixSet {
Shallow,
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Returns an iterator over the prefixes of `place`
/// (inclusive) from longest to smallest, potentially
/// terminating the iteration early based on `kind`.

View File

@ -6,7 +6,7 @@ use rustc_middle::mir::{
use crate::MirBorrowckCtxt;
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
/// of the `unused_mut` lint.
///
@ -45,13 +45,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// MIR visitor for collecting used mutable variables.
/// The 'visit lifetime represents the duration of the MIR walk.
struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> {
temporary_used_locals: FxIndexSet<Local>,
never_initialized_mut_locals: &'visit mut FxIndexSet<Local>,
mbcx: &'visit mut MirBorrowckCtxt<'cx, 'tcx>,
mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>,
}
impl GatherUsedMutsVisitor<'_, '_, '_> {
impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {
fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
// Remove any locals that we found were initialized from the
// `never_initialized_mut_locals` set. At the end, the only remaining locals will
@ -63,7 +63,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> {
}
}
impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> {
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
debug!("visit_terminator: terminator={:?}", terminator);
match &terminator.kind {

View File

@ -27,6 +27,7 @@ pub(crate) mod decodable;
pub(crate) mod default;
pub(crate) mod encodable;
pub(crate) mod hash;
pub(crate) mod smart_ptr;
#[path = "cmp/eq.rs"]
pub(crate) mod eq;

View File

@ -0,0 +1,140 @@
use std::mem::swap;
use ast::HasAttrs;
use rustc_ast::{
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
TraitBoundModifiers,
};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use smallvec::{smallvec, SmallVec};
use thin_vec::{thin_vec, ThinVec};
macro_rules! path {
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
}
pub fn expand_deriving_smart_ptr(
cx: &ExtCtxt<'_>,
span: Span,
_mitem: &MetaItem,
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
_is_const: bool,
) {
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
&& let ItemKind::Struct(_, g) = &aitem.kind
{
(aitem.ident, g)
} else {
cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit();
return;
};
// Convert generic parameters (from the struct) into generic args.
let mut pointee_param = None;
let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
let self_params = generics
.params
.iter()
.enumerate()
.map(|(idx, p)| match p.kind {
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
GenericParamKind::Type { .. } => {
if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
if pointee_param.is_some() {
multiple_pointee_diag.push(cx.dcx().struct_span_err(
p.span(),
"`SmartPointer` can only admit one type as pointee",
));
} else {
pointee_param = Some(idx);
}
}
GenericArg::Type(cx.ty_ident(p.span(), p.ident))
}
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
})
.collect::<Vec<_>>();
let Some(pointee_param_idx) = pointee_param else {
cx.dcx().struct_span_err(
span,
"At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
).emit();
return;
};
if !multiple_pointee_diag.is_empty() {
for diag in multiple_pointee_diag {
diag.emit();
}
return;
}
// Create the type of `self`.
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
let self_type = cx.ty_path(path);
// Declare helper function that adds implementation blocks.
// FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
let mut add_impl_block = |generics, trait_symbol, trait_args| {
let mut parts = path!(span, core::ops);
parts.push(Ident::new(trait_symbol, span));
let trait_path = cx.path_all(span, true, parts, trait_args);
let trait_ref = cx.trait_ref(trait_path);
let item = cx.item(
span,
Ident::empty(),
attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
constness: ast::Const::No,
generics,
of_trait: Some(trait_ref),
self_ty: self_type.clone(),
items: ThinVec::new(),
})),
);
push(Annotatable::Item(item));
};
// Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For
// example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`.
let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span));
let mut alt_self_params = self_params;
alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone());
let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params));
// Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
let mut impl_generics = generics.clone();
{
let p = &mut impl_generics.params[pointee_param_idx];
let arg = GenericArg::Type(s_ty.clone());
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
p.bounds.push(cx.trait_bound(unsize, false));
let mut attrs = thin_vec![];
swap(&mut p.attrs, &mut attrs);
p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
}
// Add the `__S: ?Sized` extra parameter to the impl block.
let sized = cx.path_global(span, path!(span, core::marker::Sized));
let bound = GenericBound::Trait(
cx.poly_trait_ref(span, sized),
TraitBoundModifiers {
polarity: ast::BoundPolarity::Maybe(span),
constness: ast::BoundConstness::Never,
asyncness: ast::BoundAsyncness::Normal,
},
);
let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None);
impl_generics.params.push(extra_param);
// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone());
}

View File

@ -127,6 +127,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable,
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
}
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);

View File

@ -564,9 +564,6 @@ pub(crate) unsafe fn llvm_optimize(
let llvm_plugins = config.llvm_plugins.join(",");
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
// We would have to add upstream support for this first, before we can support
// config.inline_threshold and our more aggressive default thresholds.
let result = llvm::LLVMRustOptimize(
module.module_llvm.llmod(),
&*module.module_llvm.tm,

View File

@ -27,8 +27,6 @@ codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified

View File

@ -120,7 +120,6 @@ pub struct ModuleConfig {
pub vectorize_loop: bool,
pub vectorize_slp: bool,
pub merge_functions: bool,
pub inline_threshold: Option<u32>,
pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>,
}
@ -280,7 +279,6 @@ impl ModuleConfig {
}
},
inline_threshold: sess.opts.cg.inline_threshold,
emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
}

View File

@ -15,11 +15,7 @@ use rustc_span::{sym, Span};
use rustc_target::spec::{abi, SanitizerSet};
use crate::errors;
use crate::target_features::from_target_feature;
use crate::{
errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol},
target_features::check_target_feature_trait_unsafe,
};
use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature};
fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
use rustc_middle::mir::mono::Linkage::*;
@ -139,7 +135,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// coverage on a smaller scope within an excluded larger scope.
}
Some(_) | None => {
tcx.dcx().emit_err(ExpectedCoverageSymbol { span: attr.span });
tcx.dcx()
.span_delayed_bug(attr.span, "unexpected value of coverage attribute");
}
}
}
@ -174,7 +171,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
}
Some(_) => {
tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span });
tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span });
}
None => {
// Unfortunately, unconditionally using `llvm.used` causes

View File

@ -564,13 +564,6 @@ pub struct UnknownArchiveKind<'a> {
pub kind: &'a str,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_expected_coverage_symbol)]
pub struct ExpectedCoverageSymbol {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_expected_used_symbol)]
pub struct ExpectedUsedSymbol {

View File

@ -27,7 +27,6 @@
#![feature(lint_reasons)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
#![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]

View File

@ -188,7 +188,7 @@ impl SipHasher128 {
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 {
let mut hasher = SipHasher128 {
nbuf: 0,
buf: MaybeUninit::uninit_array(),
buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY],
state: State {
v0: key0 ^ 0x736f6d6570736575,
// The XOR with 0xee is only done on 128-bit algorithm version.

View File

@ -1133,7 +1133,11 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
}
if cg_flags.iter().any(|x| *x == "no-stack-check") {
early_dcx.early_warn("the --no-stack-check flag is deprecated and does nothing");
early_dcx.early_warn("the `-Cno-stack-check` flag is deprecated and does nothing");
}
if cg_flags.iter().any(|x| x.starts_with("inline-threshold")) {
early_dcx.early_warn("the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)");
}
if cg_flags.iter().any(|x| *x == "passes=list") {

View File

@ -105,6 +105,9 @@ pub struct AttributeTemplate {
pub word: bool,
/// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`.
pub list: Option<&'static str>,
/// If non-empty, the attribute is allowed to take a list containing exactly
/// one of the listed words, like `#[coverage(off)]`.
pub one_of: &'static [Symbol],
/// If `Some`, the attribute is allowed to be a name/value pair where the
/// value is a string, like `#[must_use = "reason"]`.
pub name_value_str: Option<&'static str>,
@ -165,19 +168,20 @@ pub enum AttributeDuplicates {
/// E.g., `template!(Word, List: "description")` means that the attribute
/// supports forms `#[attr]` and `#[attr(description)]`.
macro_rules! template {
(Word) => { template!(@ true, None, None) };
(List: $descr: expr) => { template!(@ false, Some($descr), None) };
(NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
(Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
(Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
(Word) => { template!(@ true, None, &[], None) };
(List: $descr: expr) => { template!(@ false, Some($descr), &[], None) };
(OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) };
(NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) };
(Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) };
(Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) };
(List: $descr1: expr, NameValueStr: $descr2: expr) => {
template!(@ false, Some($descr1), Some($descr2))
template!(@ false, Some($descr1), &[], Some($descr2))
};
(Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
template!(@ true, Some($descr1), Some($descr2))
template!(@ true, Some($descr1), &[], Some($descr2))
};
(@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
word: $word, list: $list, name_value_str: $name_value_str
(@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate {
word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str
} };
}
@ -478,8 +482,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, experimental!(no_sanitize)
),
gated!(
coverage, Normal, template!(Word, List: "on|off"),
WarnFollowing, EncodeCrossCrate::No,
coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
ErrorPreceding, EncodeCrossCrate::No,
coverage_attribute, experimental!(coverage)
),
@ -575,6 +579,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
),
// `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
gated!(
pointee, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
),
// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
// ==========================================================================

View File

@ -436,6 +436,8 @@ declare_features! (
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)),
/// Allows deriving `SmartPointer` traits
(unstable, derive_smart_pointer, "1.79.0", Some(123430)),
/// Controls errors in trait implementations.
(unstable, do_not_recommend, "1.67.0", Some(51992)),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.

View File

@ -1245,11 +1245,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr,
);
return self
return Err(self
.commit_if_ok(|_| {
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
self.at(cause, self.param_env).lub(DefineOpaqueTypes::Yes, prev_ty, new_ty)
})
.map(|ok| self.register_infer_ok_obligations(ok));
.unwrap_err());
}
}
@ -1259,10 +1259,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(e) = first_error {
Err(e)
} else {
self.commit_if_ok(|_| {
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
Err(self
.commit_if_ok(|_| {
self.at(cause, self.param_env).lub(
DefineOpaqueTypes::Yes,
prev_ty,
new_ty,
)
})
.map(|ok| self.register_infer_ok_obligations(ok))
.unwrap_err())
}
}
Ok(ok) => {

View File

@ -4,8 +4,10 @@ use crate::{errors, parse_in};
use rustc_ast::token::Delimiter;
use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::MetaItemKind;
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety};
use rustc_ast::{
self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind,
NestedMetaItem, Safety,
};
use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::{
AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
@ -184,9 +186,13 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim
/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool {
let is_one_allowed_subword = |items: &[NestedMetaItem]| match items {
[item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)),
_ => false,
};
match meta {
MetaItemKind::Word => template.word,
MetaItemKind::List(..) => template.list.is_some(),
MetaItemKind::List(items) => template.list.is_some() || is_one_allowed_subword(items),
MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(),
MetaItemKind::NameValue(..) => false,
}
@ -230,6 +236,7 @@ fn emit_malformed_attribute(
if let Some(descr) = template.list {
suggestions.push(format!("#{inner}[{name}({descr})]"));
}
suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]")));
if let Some(descr) = template.name_value_str {
suggestions.push(format!("#{inner}[{name} = \"{descr}\"]"));
}

View File

@ -103,18 +103,9 @@ passes_continue_labeled_block =
.label = labeled blocks cannot be `continue`'d
.block_label = labeled block the `continue` points to
passes_coverage_fn_defn =
`#[coverage]` may only be applied to function definitions
passes_coverage_ignored_function_prototype =
`#[coverage]` is ignored on function prototypes
passes_coverage_not_coverable =
`#[coverage]` must be applied to coverable code
.label = not coverable code
passes_coverage_propagate =
`#[coverage]` does not propagate into items and must be applied to the contained functions directly
passes_coverage_not_fn_or_closure =
attribute should be applied to a function definition or closure
.label = not a function or closure
passes_dead_codes =
{ $multiple ->

View File

@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_diagnostic_on_unimplemented(attr.span, hir_id, target)
}
[sym::inline] => self.check_inline(hir_id, attr, span, target),
[sym::coverage] => self.check_coverage(hir_id, attr, span, target),
[sym::coverage] => self.check_coverage(attr, span, target),
[sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target),
[sym::marker] => self.check_marker(hir_id, attr, span, target),
[sym::target_feature] => {
@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
/// Checks if a `#[coverage]` is applied directly to a function
fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
/// Checks that `#[coverage(..)]` is applied to a function or closure.
fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool {
match target {
// #[coverage] on function is fine
// #[coverage(..)] on function is fine
Target::Fn
| Target::Closure
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
// function prototypes can't be covered
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::IgnoredCoverageFnProto,
);
true
}
Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => {
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::IgnoredCoveragePropagate,
);
true
}
Target::Expression | Target::Statement | Target::Arm => {
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::IgnoredCoverageFnDefn,
);
true
}
_ => {
self.dcx().emit_err(errors::IgnoredCoverageNotCoverable {
self.dcx().emit_err(errors::CoverageNotFnOrClosure {
attr_span: attr.span,
defn_span: span,
});

View File

@ -1010,6 +1010,22 @@ impl<'tcx> DeadVisitor<'tcx> {
parent_item: Option<LocalDefId>,
report_on: ReportOn,
) {
fn get_parent_if_enum_variant<'tcx>(
tcx: TyCtxt<'tcx>,
may_variant: LocalDefId,
) -> LocalDefId {
if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant)
&& let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
&& let Some(enum_local_id) = enum_did.as_local()
&& let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
&& let ItemKind::Enum(_, _) = item.kind
{
enum_local_id
} else {
may_variant
}
}
let Some(&first_item) = dead_codes.first() else {
return;
};
@ -1053,6 +1069,9 @@ impl<'tcx> DeadVisitor<'tcx> {
};
let encl_def_id = parent_item.unwrap_or(first_item.def_id);
// If parent of encl_def_id is an enum, use the parent ID intead.
let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id);
let ignored_derived_impls =
if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
let trait_list = ign_traits

View File

@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure {
pub defn_span: Span,
}
#[derive(LintDiagnostic)]
#[diag(passes_coverage_ignored_function_prototype)]
pub struct IgnoredCoverageFnProto;
#[derive(LintDiagnostic)]
#[diag(passes_coverage_propagate)]
pub struct IgnoredCoveragePropagate;
#[derive(LintDiagnostic)]
#[diag(passes_coverage_fn_defn)]
pub struct IgnoredCoverageFnDefn;
#[derive(Diagnostic)]
#[diag(passes_coverage_not_coverable, code = E0788)]
pub struct IgnoredCoverageNotCoverable {
#[diag(passes_coverage_not_fn_or_closure, code = E0788)]
pub struct CoverageNotFnOrClosure {
#[primary_span]
pub attr_span: Span,
#[label]

View File

@ -1499,7 +1499,8 @@ options! {
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
"enable incremental compilation"),
inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
"set the threshold for inlining a function"),
"this option is deprecated and does nothing \
(consider using `-Cllvm-args=--inline-threshold=...`)"),
#[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage reports \

View File

@ -174,6 +174,7 @@ symbols! {
Center,
Cleanup,
Clone,
CoerceUnsized,
Command,
ConstParamTy,
Context,
@ -189,6 +190,7 @@ symbols! {
DiagMessage,
Diagnostic,
DirBuilder,
DispatchFromDyn,
Display,
DoubleEndedIterator,
Duration,
@ -299,8 +301,10 @@ symbols! {
Saturating,
Send,
SeqCst,
Sized,
SliceIndex,
SliceIter,
SmartPointer,
Some,
SpanCtxt,
String,
@ -323,6 +327,7 @@ symbols! {
TyCtxt,
TyKind,
Unknown,
Unsize,
Upvars,
Vec,
VecDeque,
@ -707,6 +712,7 @@ symbols! {
derive,
derive_const,
derive_default_enum,
derive_smart_pointer,
destruct,
destructuring_assignment,
diagnostic,
@ -1315,6 +1321,7 @@ symbols! {
on,
on_unimplemented,
opaque,
ops,
opt_out_copy,
optimize,
optimize_attribute,
@ -1389,6 +1396,7 @@ symbols! {
plugin,
plugin_registrar,
plugins,
pointee,
pointee_trait,
pointer,
pointer_like,

View File

@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
ObligationCauseCode::RepeatElementCopy {
is_constable,
elt_type,
elt_type: _,
elt_span,
elt_stmt_span,
elt_stmt_span: _,
} => {
err.note(
"the `Copy` trait is required because this value will be copied for each element of the array",
);
let value_kind = match is_constable {
IsConstable::Fn => Some("the result of the function call"),
IsConstable::Ctor => Some("the result of the constructor"),
_ => None,
};
let sm = tcx.sess.source_map();
if let Some(value_kind) = value_kind
if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
&& let Ok(snip) = sm.span_to_snippet(elt_span)
{
let help_msg = format!(
"consider creating a new `const` item and initializing it with {value_kind} \
to be used in the repeat position"
);
let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default();
err.multipart_suggestion(
help_msg,
vec![
(
elt_stmt_span.shrink_to_lo(),
format!(
"const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}"
),
),
(elt_span, "ARRAY_REPEAT_VALUE".to_string()),
],
err.span_suggestion(
elt_span,
"create an inline `const` block",
format!("const {{ {snip} }}"),
Applicability::MachineApplicable,
);
} else {
@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.help("consider using `core::array::from_fn` to initialize the array");
err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information");
}
if tcx.sess.is_nightly_build()
&& matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
{
err.help(
"create an inline `const` block, see RFC #2920 \
<https://github.com/rust-lang/rfcs/pull/2920> for more information",
);
}
}
ObligationCauseCode::VariableType(hir_id) => {
if let Some(typeck_results) = &self.typeck_results

View File

@ -132,7 +132,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut raw_arr = MaybeUninit::uninit_array();
let mut raw_arr = [const { MaybeUninit::uninit() }; N];
let raw_arr_ptr = raw_arr.as_mut_ptr().cast();
let (head, tail) = self.inner.as_slices();

View File

@ -135,7 +135,6 @@
#![feature(layout_for_ptr)]
#![feature(local_waker)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(panic_internals)]
#![feature(pattern)]

View File

@ -254,7 +254,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
#[inline]
fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
let mut raw_ary = MaybeUninit::uninit_array();
let mut raw_ary = [const { MaybeUninit::uninit() }; N];
let len = self.len();

View File

@ -101,7 +101,6 @@ impl<T, const N: usize> IntoIter<T, N> {
/// ```
/// #![feature(array_into_iter_constructors)]
/// #![feature(maybe_uninit_uninit_array_transpose)]
/// #![feature(maybe_uninit_uninit_array)]
/// use std::array::IntoIter;
/// use std::mem::MaybeUninit;
///
@ -111,7 +110,7 @@ impl<T, const N: usize> IntoIter<T, N> {
/// fn next_chunk<T: Copy, const N: usize>(
/// it: &mut impl Iterator<Item = T>,
/// ) -> Result<[T; N], IntoIter<T, N>> {
/// let mut buffer = MaybeUninit::uninit_array();
/// let mut buffer = [const { MaybeUninit::uninit() }; N];
/// let mut i = 0;
/// while i < N {
/// match it.next() {
@ -203,7 +202,7 @@ impl<T, const N: usize> IntoIter<T, N> {
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const fn empty() -> Self {
let buffer = MaybeUninit::uninit_array();
let buffer = [const { MaybeUninit::uninit() }; N];
let initialized = 0..0;
// SAFETY: We're telling it that none of the elements are initialized,
@ -405,7 +404,8 @@ impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
fn clone(&self) -> Self {
// Note, we don't really need to match the exact same alive range, so
// we can just clone into offset 0 regardless of where `self` is.
let mut new = Self { data: MaybeUninit::uninit_array(), alive: IndexRange::zero_to(0) };
let mut new =
Self { data: [const { MaybeUninit::uninit() }; N], alive: IndexRange::zero_to(0) };
// Clone all alive elements.
for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {

View File

@ -127,7 +127,7 @@ where
R: Try,
R::Residual: Residual<[R::Output; N]>,
{
let mut array = MaybeUninit::uninit_array::<N>();
let mut array = [const { MaybeUninit::uninit() }; N];
match try_from_fn_erased(&mut array, cb) {
ControlFlow::Break(r) => FromResidual::from_residual(r),
ControlFlow::Continue(()) => {
@ -918,7 +918,7 @@ impl<T> Drop for Guard<'_, T> {
pub(crate) fn iter_next_chunk<T, const N: usize>(
iter: &mut impl Iterator<Item = T>,
) -> Result<[T; N], IntoIter<T, N>> {
let mut array = MaybeUninit::uninit_array::<N>();
let mut array = [const { MaybeUninit::uninit() }; N];
let r = iter_next_chunk_erased(&mut array, iter);
match r {
Ok(()) => {

View File

@ -35,8 +35,8 @@ fn float_to_decimal_common_exact<T>(
where
T: flt2dec::DecodableFloat,
{
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = [MaybeUninit::uninit(); 4];
let formatted = flt2dec::to_exact_fixed_str(
flt2dec::strategy::grisu::format_exact,
*num,
@ -62,8 +62,9 @@ where
T: flt2dec::DecodableFloat,
{
// enough for f32 and f64
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] =
[MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS];
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = [MaybeUninit::uninit(); 4];
let formatted = flt2dec::to_shortest_str(
flt2dec::strategy::grisu::format_shortest,
*num,
@ -107,8 +108,8 @@ fn float_to_exponential_common_exact<T>(
where
T: flt2dec::DecodableFloat,
{
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = [MaybeUninit::uninit(); 6];
let formatted = flt2dec::to_exact_exp_str(
flt2dec::strategy::grisu::format_exact,
*num,
@ -135,8 +136,9 @@ where
T: flt2dec::DecodableFloat,
{
// enough for f32 and f64
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] =
[MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS];
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = [MaybeUninit::uninit(); 6];
let formatted = flt2dec::to_shortest_exp_str(
flt2dec::strategy::grisu::format_shortest,
*num,

View File

@ -202,7 +202,7 @@ where
T: Copy,
{
fn spec_next_chunk(&mut self) -> Result<[T; N], array::IntoIter<T, N>> {
let mut raw_array = MaybeUninit::uninit_array();
let mut raw_array = [const { MaybeUninit::uninit() }; N];
let len = self.len();

View File

@ -64,7 +64,7 @@ where
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut array: [MaybeUninit<Self::Item>; N] = MaybeUninit::uninit_array();
let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
struct Guard<'a, T> {
array: &'a mut [MaybeUninit<T>],

View File

@ -68,7 +68,7 @@ where
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut array: [MaybeUninit<Self::Item>; N] = MaybeUninit::uninit_array();
let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
struct Guard<'a, T> {
array: &'a mut [MaybeUninit<T>],

View File

@ -110,7 +110,8 @@ impl<I: Iterator, const N: usize> MapWindowsInner<I, N> {
impl<T, const N: usize> Buffer<T, N> {
fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> {
let first_half = crate::array::iter_next_chunk(iter).ok()?;
let buffer = [MaybeUninit::new(first_half).transpose(), MaybeUninit::uninit_array()];
let buffer =
[MaybeUninit::new(first_half).transpose(), [const { MaybeUninit::uninit() }; N]];
Some(Self { buffer, start: 0 })
}
@ -204,7 +205,7 @@ impl<T, const N: usize> Buffer<T, N> {
impl<T: Clone, const N: usize> Clone for Buffer<T, N> {
fn clone(&self) -> Self {
let mut buffer = Buffer {
buffer: [MaybeUninit::uninit_array(), MaybeUninit::uninit_array()],
buffer: [[const { MaybeUninit::uninit() }; N], [const { MaybeUninit::uninit() }; N]],
start: self.start,
};
buffer.as_uninit_array_mut().write(self.as_array_ref().clone());

View File

@ -140,7 +140,6 @@
#![feature(const_likely)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_maybe_uninit_uninit_array)]
#![feature(const_nonnull_new)]
#![feature(const_num_midpoint)]
#![feature(const_option)]
@ -177,7 +176,6 @@
#![feature(is_ascii_octdigit)]
#![feature(isqrt)]
#![feature(link_cfg)]
#![feature(maybe_uninit_uninit_array)]
#![feature(offset_of_enum)]
#![feature(offset_of_nested)]
#![feature(panic_internals)]

View File

@ -1018,3 +1018,12 @@ pub trait FnPtr: Copy + Clone {
#[lang = "fn_ptr_addr"]
fn addr(self) -> *const ();
}
/// Derive macro generating impls of traits related to smart pointers.
#[cfg(not(bootstrap))]
#[rustc_builtin_macro]
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)]
#[unstable(feature = "derive_smart_pointer", issue = "123430")]
pub macro SmartPointer($item:item) {
/* compiler built-in */
}

View File

@ -917,11 +917,10 @@ impl<T> MaybeUninit<T> {
/// # Examples
///
/// ```
/// #![feature(maybe_uninit_uninit_array)]
/// #![feature(maybe_uninit_array_assume_init)]
/// use std::mem::MaybeUninit;
///
/// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
/// let mut array: [MaybeUninit<i32>; 3] = [MaybeUninit::uninit(); 3];
/// array[0].write(0);
/// array[1].write(1);
/// array[2].write(2);

View File

@ -11,7 +11,7 @@ pub struct DisplayBuffer<const SIZE: usize> {
impl<const SIZE: usize> DisplayBuffer<SIZE> {
#[inline]
pub const fn new() -> Self {
Self { buf: MaybeUninit::uninit_array(), len: 0 }
Self { buf: [MaybeUninit::uninit(); SIZE], len: 0 }
}
#[inline]

View File

@ -483,7 +483,6 @@ impl u8 {
Self = u8,
ActualT = u8,
SignedT = i8,
NonZeroT = NonZero<u8>,
BITS = 8,
MAX = 255,
rot = 2,
@ -1098,7 +1097,6 @@ impl u16 {
Self = u16,
ActualT = u16,
SignedT = i16,
NonZeroT = NonZero<u16>,
BITS = 16,
MAX = 65535,
rot = 4,
@ -1147,7 +1145,6 @@ impl u32 {
Self = u32,
ActualT = u32,
SignedT = i32,
NonZeroT = NonZero<u32>,
BITS = 32,
MAX = 4294967295,
rot = 8,
@ -1171,7 +1168,6 @@ impl u64 {
Self = u64,
ActualT = u64,
SignedT = i64,
NonZeroT = NonZero<u64>,
BITS = 64,
MAX = 18446744073709551615,
rot = 12,
@ -1195,7 +1191,6 @@ impl u128 {
Self = u128,
ActualT = u128,
SignedT = i128,
NonZeroT = NonZero<u128>,
BITS = 128,
MAX = 340282366920938463463374607431768211455,
rot = 16,
@ -1221,7 +1216,6 @@ impl usize {
Self = usize,
ActualT = u16,
SignedT = isize,
NonZeroT = NonZero<usize>,
BITS = 16,
MAX = 65535,
rot = 4,
@ -1246,7 +1240,6 @@ impl usize {
Self = usize,
ActualT = u32,
SignedT = isize,
NonZeroT = NonZero<usize>,
BITS = 32,
MAX = 4294967295,
rot = 8,
@ -1271,7 +1264,6 @@ impl usize {
Self = usize,
ActualT = u64,
SignedT = isize,
NonZeroT = NonZero<usize>,
BITS = 64,
MAX = 18446744073709551615,
rot = 12,

View File

@ -3,7 +3,6 @@ macro_rules! uint_impl {
Self = $SelfT:ty,
ActualT = $ActualT:ident,
SignedT = $SignedT:ident,
NonZeroT = $NonZeroT:ty,
// There are all for use *only* in doc comments.
// As such, they're all passed as literals -- passing them as a string
@ -1216,8 +1215,7 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline]
pub const fn checked_ilog2(self) -> Option<u32> {
// FIXME: Simply use `NonZero::new` once it is actually generic.
if let Some(x) = <$NonZeroT>::new(self) {
if let Some(x) = NonZero::new(self) {
Some(x.ilog2())
} else {
None
@ -1239,8 +1237,7 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline]
pub const fn checked_ilog10(self) -> Option<u32> {
// FIXME: Simply use `NonZero::new` once it is actually generic.
if let Some(x) = <$NonZeroT>::new(self) {
if let Some(x) = NonZero::new(self) {
Some(x.ilog10())
} else {
None

View File

@ -104,7 +104,7 @@ struct AlignedStorage<T, const N: usize> {
impl<T, const N: usize> AlignedStorage<T, N> {
fn new() -> Self {
Self { _align: [], storage: MaybeUninit::uninit_array() }
Self { _align: [], storage: [const { MaybeUninit::uninit() }; N] }
}
fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {

View File

@ -54,8 +54,6 @@
#![feature(slice_split_once)]
#![feature(split_as_slice)]
#![feature(maybe_uninit_fill)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(min_specialization)]

View File

@ -406,7 +406,7 @@ fn file_test_read_buf() {
let filename = &tmpdir.join("test");
check!(fs::write(filename, &[1, 2, 3, 4]));
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
let mut file = check!(File::open(filename));
check!(file.read_buf(buf.unfilled()));

View File

@ -337,7 +337,6 @@
#![feature(hint_assert_unchecked)]
#![feature(ip)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)]
#![feature(panic_can_unwind)]
#![feature(panic_info_message)]
@ -407,7 +406,6 @@
#![feature(const_ip)]
#![feature(const_ipv4)]
#![feature(const_ipv6)]
#![feature(const_maybe_uninit_uninit_array)]
#![feature(const_waker)]
#![feature(thread_local_internals)]
// tidy-alphabetical-end

View File

@ -301,7 +301,7 @@ fn read_buf() {
});
let mut s = t!(srv.accept()).0;
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
t!(s.read_buf(buf.unfilled()));
assert_eq!(buf.filled(), &[1, 2, 3, 4]);

View File

@ -137,7 +137,7 @@ fn child_stdout_read_buf() {
let child = cmd.spawn().unwrap();
let mut stdout = child.stdout.unwrap();
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
stdout.read_buf(buf.unfilled()).unwrap();

View File

@ -225,7 +225,7 @@ where
// This initial size also works around `GetFullPathNameW` returning
// incorrect size hints for some short paths:
// https://github.com/dylni/normpath/issues/5
let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array();
let mut stack_buf: [MaybeUninit<u16>; 512] = [MaybeUninit::uninit(); 512];
let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new();
unsafe {
let mut n = stack_buf.len();

View File

@ -184,20 +184,9 @@ incremental files will be stored.
## inline-threshold
This option lets you set the default threshold for inlining a function. It
takes an unsigned integer as a value. Inlining is based on a cost model, where
a higher threshold will allow more inlining.
This option is deprecated and does nothing.
The default depends on the [opt-level](#opt-level):
| opt-level | Threshold |
|-----------|-----------|
| 0 | N/A, only inlines always-inline functions |
| 1 | N/A, only inlines always-inline functions and LLVM lifetime intrinsics |
| 2 | 225 |
| 3 | 275 |
| s | 75 |
| z | 25 |
Consider using `-Cllvm-args=--inline-threshold=...`.
## instrument-coverage

View File

@ -374,11 +374,12 @@ impl<'test> TestCx<'test> {
// if a test does not crash, consider it an error
if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) {
self.fatal(
"test no longer crashes/triggers ICE! Please give it a mearningful name, \
self.fatal(&format!(
"crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name, \
add a doc-comment to the start of the test explaining why it exists and \
move it to tests/ui or wherever you see fit.",
);
move it to tests/ui or wherever you see fit. Adding 'Fixes #<issueNr>' to your PR description \
ensures that the corresponding ticket is auto-closed upon merge."
));
}
}

View File

@ -1,5 +1,5 @@
//@ run-pass
//@ compile-flags: -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2
//@ compile-flags: -Ccodegen-units=1 -Cllvm-args=--inline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2
// Make sure LLVM does not miscompile this.

View File

@ -6,17 +6,15 @@ LL | let _: [Option<Bar>; 2] = [no_copy(); 2];
|
= note: required for `Option<Bar>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
help: consider annotating `Bar` with `#[derive(Copy)]`
|
LL + #[derive(Copy)]
LL | struct Bar;
|
help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position
|
LL ~ const ARRAY_REPEAT_VALUE: Option<Bar> = no_copy();
LL ~ let _: [Option<Bar>; 2] = [ARRAY_REPEAT_VALUE; 2];
help: create an inline `const` block
|
LL | let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
| ~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error

View File

@ -2,7 +2,10 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/trait-error.rs:5:6
|
LL | [Foo(String::new()); 4];
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`, which is required by `Foo<String>: Copy`
| ^^^^^^^^^^^^^^^^^^
| |
| the trait `Copy` is not implemented for `String`, which is required by `Foo<String>: Copy`
| help: create an inline `const` block: `const { Foo(String::new()) }`
|
note: required for `Foo<String>` to implement `Copy`
--> $DIR/trait-error.rs:1:10
@ -10,13 +13,7 @@ note: required for `Foo<String>` to implement `Copy`
LL | #[derive(Copy, Clone)]
| ^^^^ unsatisfied trait bound introduced in this `derive` macro
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position
|
LL ~ const ARRAY_REPEAT_VALUE: Foo<String> = Foo(String::new());
LL ~ [ARRAY_REPEAT_VALUE; 4];
|
error: aborting due to 1 previous error

View File

@ -2,45 +2,36 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:1:47
|
LL | static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
| ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option<String>: Copy`
| ^^^^
| |
| the trait `Copy` is not implemented for `String`, which is required by `Option<String>: Copy`
| help: create an inline `const` block: `const { None }`
|
= note: required for `Option<String>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position
|
LL + const ARRAY_REPEAT_VALUE: Option<String> = None;
LL ~ static _MAYBE_STRINGS: [Option<String>; 5] = [ARRAY_REPEAT_VALUE; 5];
|
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:7:34
|
LL | let _strings: [String; 5] = [String::new(); 5];
| ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
| ^^^^^^^^^^^^^
| |
| the trait `Copy` is not implemented for `String`
| help: create an inline `const` block: `const { String::new() }`
|
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position
|
LL ~ const ARRAY_REPEAT_VALUE: String = String::new();
LL ~ let _strings: [String; 5] = [ARRAY_REPEAT_VALUE; 5];
|
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:9:48
|
LL | let _maybe_strings: [Option<String>; 5] = [None; 5];
| ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option<String>: Copy`
| ^^^^
| |
| the trait `Copy` is not implemented for `String`, which is required by `Option<String>: Copy`
| help: create an inline `const` block: `const { None }`
|
= note: required for `Option<String>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position
|
LL ~ const ARRAY_REPEAT_VALUE: Option<String> = None;
LL ~ let _maybe_strings: [Option<String>; 5] = [ARRAY_REPEAT_VALUE; 5];
|
error: aborting due to 3 previous errors

View File

@ -1,58 +1,45 @@
#![feature(coverage_attribute)]
//@ edition: 2021
// Tests the error messages produced (or not produced) by various unusual
// uses of the `#[coverage(..)]` attribute.
// FIXME(#126658): Multiple coverage attributes with the same value are useless,
// and should probably produce a diagnostic.
#[coverage(off)]
#[coverage(off)] //~ ERROR multiple `coverage` attributes
#[coverage(off)]
fn multiple_consistent() {}
// FIXME(#126658): When there are multiple inconsistent coverage attributes,
// it's unclear which one will prevail.
#[coverage(off)]
#[coverage(off)] //~ ERROR multiple `coverage` attributes
#[coverage(on)]
fn multiple_inconsistent() {}
#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage] //~ ERROR malformed `coverage` attribute input
fn bare_word() {}
// FIXME(#126658): This shows as multiple different errors, one of which suggests
// writing bare `#[coverage]`, which is not allowed.
#[coverage = true]
//~^ ERROR expected `coverage(off)` or `coverage(on)`
//~| ERROR malformed `coverage` attribute input
//~| HELP the following are the possible correct uses
//~| SUGGESTION #[coverage(on|off)]
#[coverage = true] //~ ERROR malformed `coverage` attribute input
fn key_value() {}
#[coverage()] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage()] //~ ERROR malformed `coverage` attribute input
fn list_empty() {}
#[coverage(off, off)] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(off, off)] //~ ERROR malformed `coverage` attribute input
fn list_consistent() {}
#[coverage(off, on)] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(off, on)] //~ ERROR malformed `coverage` attribute input
fn list_inconsistent() {}
#[coverage(bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(bogus)] //~ ERROR malformed `coverage` attribute input
fn bogus_word() {}
#[coverage(bogus, off)] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(bogus, off)] //~ ERROR malformed `coverage` attribute input
fn bogus_word_before() {}
#[coverage(off, bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(off, bogus)] //~ ERROR malformed `coverage` attribute input
fn bogus_word_after() {}
#[coverage(off,)]
#[coverage(off,)] // (OK!)
fn comma_after() {}
// FIXME(#126658): This shows as multiple different errors.
#[coverage(,off)]
//~^ ERROR expected identifier, found `,`
//~| HELP remove this comma
//~| ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(,off)] //~ ERROR expected identifier, found `,`
fn comma_before() {}
fn main() {}

View File

@ -1,18 +1,109 @@
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:23:1
--> $DIR/bad-syntax.rs:15:1
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:18:1
|
LL | #[coverage = true]
| ^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:21:1
|
LL | #[coverage]
LL | #[coverage()]
| ^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:24:1
|
LL | #[coverage(off, off)]
| ^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:27:1
|
LL | #[coverage(off, on)]
| ^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:30:1
|
LL | #[coverage(bogus)]
| ^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:33:1
|
LL | #[coverage(bogus, off)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: malformed `coverage` attribute input
--> $DIR/bad-syntax.rs:36:1
|
LL | #[coverage(off, bogus)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: expected identifier, found `,`
--> $DIR/bad-syntax.rs:52:12
--> $DIR/bad-syntax.rs:42:12
|
LL | #[coverage(,off)]
| ^
@ -20,59 +111,29 @@ LL | #[coverage(,off)]
| expected identifier
| help: remove this comma
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:18:1
error: multiple `coverage` attributes
--> $DIR/bad-syntax.rs:7:1
|
LL | #[coverage]
| ^^^^^^^^^^^
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/bad-syntax.rs:8:1
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:23:1
error: multiple `coverage` attributes
--> $DIR/bad-syntax.rs:11:1
|
LL | #[coverage = true]
| ^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:30:1
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ help: remove this attribute
|
LL | #[coverage()]
| ^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:33:1
note: attribute also specified here
--> $DIR/bad-syntax.rs:12:1
|
LL | #[coverage(off, off)]
| ^^^^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:36:1
|
LL | #[coverage(off, on)]
| ^^^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:39:1
|
LL | #[coverage(bogus)]
| ^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:42:1
|
LL | #[coverage(bogus, off)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:45:1
|
LL | #[coverage(off, bogus)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:52:1
|
LL | #[coverage(,off)]
| ^^^^^^^^^^^^^^^^^
LL | #[coverage(on)]
| ^^^^^^^^^^^^^^^
error: aborting due to 11 previous errors

View File

@ -8,57 +8,62 @@
// and in places that cannot have a coverage attribute, to demonstrate the
// interaction between multiple errors.
// FIXME(#126658): The error messages for using this syntax are inconsistent
// with the error message in other cases. They also sometimes appear together
// with other errors, and they suggest using the incorrect `#[coverage]` syntax.
#[coverage = "off"] //~ ERROR malformed `coverage` attribute input
#[coverage = "off"]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
mod my_mod {}
mod my_mod_inner {
#![coverage = "off"] //~ ERROR malformed `coverage` attribute input
#![coverage = "off"]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
}
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
struct MyStruct;
#[coverage = "off"] //~ ERROR malformed `coverage` attribute input
#[coverage = "off"]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyStruct {
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32 = 7;
}
#[coverage = "off"] //~ ERROR malformed `coverage` attribute input
#[coverage = "off"]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
trait MyTrait {
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32;
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
type T;
}
#[coverage = "off"] //~ ERROR malformed `coverage` attribute input
#[coverage = "off"]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyTrait for MyStruct {
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32 = 8;
#[coverage = "off"]
//~^ ERROR `#[coverage]` must be applied to coverable code
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
type T = ();
}
#[coverage = "off"]
//~^ ERROR expected `coverage(off)` or `coverage(on)`
//~| ERROR malformed `coverage` attribute input
//~^ ERROR malformed `coverage` attribute input
fn main() {}

View File

@ -1,28 +1,28 @@
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:15:1
--> $DIR/name-value.rs:11:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
| ~~~~~~~~~~~~~~~~~~~
LL | #[coverage]
| ~~~~~~~~~~~
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:19:5
--> $DIR/name-value.rs:17:5
|
LL | #![coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #![coverage(on|off)]
| ~~~~~~~~~~~~~~~~~~~~
LL | #![coverage]
| ~~~~~~~~~~~~
LL | #![coverage(off)]
|
LL | #![coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:22:1
@ -32,22 +32,22 @@ LL | #[coverage = "off"]
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:29:5
--> $DIR/name-value.rs:31:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
@ -58,162 +58,220 @@ LL | #[coverage = "off"]
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
| ~~~~~~~~~~~~~~~~~~~
LL | #[coverage]
| ~~~~~~~~~~~
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:37:5
--> $DIR/name-value.rs:41:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:42:5
--> $DIR/name-value.rs:46:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:35:1
--> $DIR/name-value.rs:37:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
| ~~~~~~~~~~~~~~~~~~~
LL | #[coverage]
| ~~~~~~~~~~~
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:50:5
--> $DIR/name-value.rs:56:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:55:5
--> $DIR/name-value.rs:61:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:48:1
--> $DIR/name-value.rs:52:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
| ~~~~~~~~~~~~~~~~~~~
LL | #[coverage]
| ~~~~~~~~~~~
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/name-value.rs:61:1
--> $DIR/name-value.rs:67:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(on|off)]
LL | #[coverage(off)]
|
LL | #[coverage]
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:11:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | mod my_mod {}
| ------------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:17:5
|
LL | / mod my_mod_inner {
LL | | #![coverage = "off"]
| | ^^^^^^^^^^^^^^^^^^^^
LL | |
LL | |
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:22:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | struct MyStruct;
| ---------------- not coverable code
| ---------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/name-value.rs:37:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:27:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | / impl MyStruct {
LL | | #[coverage = "off"]
LL | |
LL | |
LL | | const X: u32 = 7;
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:37:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | / trait MyTrait {
LL | | #[coverage = "off"]
LL | |
LL | |
... |
LL | | type T;
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:52:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | / impl MyTrait for MyStruct {
LL | | #[coverage = "off"]
LL | |
LL | |
... |
LL | | type T = ();
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:41:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | const X: u32;
| ------------- not coverable code
| ------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/name-value.rs:42:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:46:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | type T;
| ------- not coverable code
| ------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/name-value.rs:29:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:31:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | const X: u32 = 7;
| ----------------- not coverable code
| ----------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/name-value.rs:50:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:56:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | const X: u32 = 8;
| ----------------- not coverable code
| ----------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/name-value.rs:55:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/name-value.rs:61:5
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
...
LL | type T = ();
| ------------ not coverable code
| ------------ not a function or closure
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/name-value.rs:61:1
|
LL | #[coverage = "off"]
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 19 previous errors
error: aborting due to 23 previous errors
For more information about this error, try `rustc --explain E0788`.

View File

@ -2,54 +2,48 @@
#![feature(coverage_attribute)]
#![feature(impl_trait_in_assoc_type)]
#![warn(unused_attributes)]
#![coverage(off)]
//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
#![coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
#[coverage(off)]
//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
trait Trait {
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
const X: u32;
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
type T;
type U;
}
#[coverage(off)]
//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
impl Trait for () {
const X: u32 = 0;
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
type T = Self;
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
type U = impl Trait; //~ ERROR unconstrained opaque type
}
extern "C" {
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
static X: u32;
#[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
type T;
}
#[coverage(off)]
fn main() {
#[coverage(off)]
//~^ WARN `#[coverage]` may only be applied to function definitions
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
let _ = ();
match () {
#[coverage(off)]
//~^ WARN `#[coverage]` may only be applied to function definitions
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
() => (),
}
#[coverage(off)]
//~^ WARN `#[coverage]` may only be applied to function definitions
#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
return ();
}

View File

@ -1,101 +1,116 @@
warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
--> $DIR/no-coverage.rs:8:1
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:7:1
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/no-coverage.rs:4:9
|
LL | #![warn(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
LL | / trait Trait {
LL | | #[coverage(off)]
LL | | const X: u32;
... |
LL | | type U;
LL | | }
| |_- not a function or closure
warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
--> $DIR/no-coverage.rs:20:1
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:18:1
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | / impl Trait for () {
LL | | const X: u32 = 0;
LL | |
LL | | #[coverage(off)]
... |
LL | | type U = impl Trait;
LL | | }
| |_- not a function or closure
warning: `#[coverage]` may only be applied to function definitions
--> $DIR/no-coverage.rs:42:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:39:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | let _ = ();
| ----------- not a function or closure
warning: `#[coverage]` may only be applied to function definitions
--> $DIR/no-coverage.rs:47:9
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:43:9
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | () => (),
| -------- not a function or closure
warning: `#[coverage]` may only be applied to function definitions
--> $DIR/no-coverage.rs:52:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:47:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | return ();
| --------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:11:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:9:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | const X: u32;
| ------------- not coverable code
| ------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:14:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:12:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | type T;
| ------- not coverable code
| ------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:25:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:22:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | type T = Self;
| -------------- not coverable code
| -------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:28:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:25:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | type U = impl Trait;
| -------------------- not coverable code
| -------------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:33:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:30:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | static X: u32;
| -------------- not coverable code
| -------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/no-coverage.rs:36:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:33:5
|
LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^
LL | type T;
| ------- not coverable code
| ------- not a function or closure
warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:5:1
|
LL | #![coverage(off)]
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ not a function or closure
error: unconstrained opaque type
--> $DIR/no-coverage.rs:29:14
--> $DIR/no-coverage.rs:26:14
|
LL | type U = impl Trait;
| ^^^^^^^^^^
|
= note: `U` must be used in combination with a concrete type within the same impl
error: aborting due to 7 previous errors; 6 warnings emitted
error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0788`.

View File

@ -4,16 +4,16 @@
// Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare
// words, not part of a more complicated substructure.
#[coverage(yes(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(yes(milord))] //~ ERROR malformed `coverage` attribute input
fn yes_list() {}
#[coverage(no(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(no(milord))] //~ ERROR malformed `coverage` attribute input
fn no_list() {}
#[coverage(yes = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(yes = "milord")] //~ ERROR malformed `coverage` attribute input
fn yes_key() {}
#[coverage(no = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage(no = "milord")] //~ ERROR malformed `coverage` attribute input
fn no_key() {}
fn main() {}

View File

@ -1,26 +1,54 @@
error: expected `coverage(off)` or `coverage(on)`
error: malformed `coverage` attribute input
--> $DIR/subword.rs:7:1
|
LL | #[coverage(yes(milord))]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: expected `coverage(off)` or `coverage(on)`
error: malformed `coverage` attribute input
--> $DIR/subword.rs:10:1
|
LL | #[coverage(no(milord))]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: expected `coverage(off)` or `coverage(on)`
error: malformed `coverage` attribute input
--> $DIR/subword.rs:13:1
|
LL | #[coverage(yes = "milord")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: expected `coverage(off)` or `coverage(on)`
error: malformed `coverage` attribute input
--> $DIR/subword.rs:16:1
|
LL | #[coverage(no = "milord")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
| ~~~~~~~~~~~~~~~~
LL | #[coverage(on)]
| ~~~~~~~~~~~~~~~
error: aborting due to 4 previous errors

View File

@ -8,47 +8,62 @@
// and in places that cannot have a coverage attribute, to demonstrate the
// interaction between multiple errors.
// FIXME(#126658): The error messages for using this syntax give the impression
// that it is legal, even though it should never be legal.
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
mod my_mod {}
// FIXME(#126658): This is silently allowed, but should not be.
mod my_mod_inner {
#![coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
}
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
struct MyStruct;
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyStruct {
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32 = 7;
}
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
trait MyTrait {
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32;
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
type T;
}
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyTrait for MyStruct {
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
const X: u32 = 8;
#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code
#[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
type T = ();
}
#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)`
#[coverage]
//~^ ERROR malformed `coverage` attribute input
fn main() {}

View File

@ -1,57 +1,277 @@
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:23:1
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:11:1
|
LL | #[coverage]
| ^^^^^^^^^^^
LL | struct MyStruct;
| ---------------- not coverable code
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:36:5
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:17:5
|
LL | #![coverage]
| ^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #![coverage(off)]
|
LL | #![coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:22:1
|
LL | #[coverage]
| ^^^^^^^^^^^
LL | const X: u32;
| ------------- not coverable code
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:39:5
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:31:5
|
LL | #[coverage]
| ^^^^^^^^^^^
LL | type T;
| ------- not coverable code
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:29:5
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:27:1
|
LL | #[coverage]
| ^^^^^^^^^^^
LL | const X: u32 = 7;
| ----------------- not coverable code
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:41:5
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:46:5
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:37:1
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:56:5
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:61:5
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:52:1
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:67:1
|
LL | #[coverage]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:11:1
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | mod my_mod {}
| ------------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:17:5
|
LL | / mod my_mod_inner {
LL | | #![coverage]
| | ^^^^^^^^^^^^
LL | |
LL | |
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:22:1
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | struct MyStruct;
| ---------------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:27:1
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | / impl MyStruct {
LL | | #[coverage]
LL | |
LL | |
LL | | const X: u32 = 7;
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:37:1
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | / trait MyTrait {
LL | | #[coverage]
LL | |
LL | |
... |
LL | | type T;
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:52:1
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | / impl MyTrait for MyStruct {
LL | | #[coverage]
LL | |
LL | |
... |
LL | | type T = ();
LL | | }
| |_- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:41:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | const X: u32;
| ------------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:46:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | type T;
| ------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:31:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | const X: u32 = 7;
| ----------------- not a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:56:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | const X: u32 = 8;
| ----------------- not coverable code
| ----------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:49:5
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:61:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | type T = ();
| ------------ not coverable code
| ------------ not a function or closure
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/word-only.rs:53:1
|
LL | #[coverage]
| ^^^^^^^^^^^
error: aborting due to 7 previous errors
error: aborting due to 23 previous errors
For more information about this error, try `rustc --explain E0788`.

View File

@ -0,0 +1,4 @@
//@ check-pass
//@ compile-flags: -Cinline-threshold=666
fn main() {}

View File

@ -0,0 +1,2 @@
warning: the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)

View File

@ -0,0 +1,55 @@
//@ run-pass
#![feature(derive_smart_pointer, arbitrary_self_types)]
use std::marker::SmartPointer;
#[derive(SmartPointer)]
struct MyPointer<'a, #[pointee] T: ?Sized> {
ptr: &'a T,
}
impl<T: ?Sized> Copy for MyPointer<'_, T> {}
impl<T: ?Sized> Clone for MyPointer<'_, T> {
fn clone(&self) -> Self {
Self { ptr: self.ptr }
}
}
impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> {
type Target = T;
fn deref(&self) -> &'a T {
self.ptr
}
}
struct MyValue(u32);
impl MyValue {
fn through_pointer(self: MyPointer<'_, Self>) -> u32 {
self.ptr.0
}
}
trait MyTrait {
fn through_trait(&self) -> u32;
fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32;
}
impl MyTrait for MyValue {
fn through_trait(&self) -> u32 {
self.0
}
fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32 {
self.ptr.0
}
}
pub fn main() {
let v = MyValue(10);
let ptr = MyPointer { ptr: &v };
assert_eq!(v.0, ptr.through_pointer());
assert_eq!(v.0, ptr.through_pointer());
let dptr = ptr as MyPointer<dyn MyTrait>;
assert_eq!(v.0, dptr.through_trait());
assert_eq!(v.0, dptr.through_trait_and_pointer());
}

View File

@ -0,0 +1,9 @@
use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive_smart_pointer'
#[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
struct MyPointer<'a, #[pointee] T: ?Sized> {
//~^ ERROR the `#[pointee]` attribute is an experimental feature
ptr: &'a T,
}
fn main() {}

View File

@ -0,0 +1,33 @@
error[E0658]: use of unstable library feature 'derive_smart_pointer'
--> $DIR/feature-gate-derive-smart-pointer.rs:3:10
|
LL | #[derive(SmartPointer)]
| ^^^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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 `#[pointee]` attribute is an experimental feature
--> $DIR/feature-gate-derive-smart-pointer.rs:4:22
|
LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
| ^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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]: use of unstable library feature 'derive_smart_pointer'
--> $DIR/feature-gate-derive-smart-pointer.rs:1:5
|
LL | use std::marker::SmartPointer;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -6,7 +6,22 @@ enum Enum {
Variant2,
}
#[derive(Debug)]
enum TupleVariant {
Variant1(i32), //~ ERROR: variant `Variant1` is never constructed
Variant2,
}
#[derive(Debug)]
enum StructVariant {
Variant1 { id: i32 }, //~ ERROR: variant `Variant1` is never constructed
Variant2,
}
fn main() {
let e = Enum::Variant2;
e.clone();
let _ = TupleVariant::Variant2;
let _ = StructVariant::Variant2;
}

View File

@ -13,5 +13,25 @@ note: the lint level is defined here
LL | #![deny(dead_code)]
| ^^^^^^^^^
error: aborting due to 1 previous error
error: variant `Variant1` is never constructed
--> $DIR/unused-variant.rs:11:5
|
LL | enum TupleVariant {
| ------------ variant in this enum
LL | Variant1(i32),
| ^^^^^^^^
|
= note: `TupleVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
error: variant `Variant1` is never constructed
--> $DIR/unused-variant.rs:17:5
|
LL | enum StructVariant {
| ------------- variant in this enum
LL | Variant1 { id: i32 },
| ^^^^^^^^
|
= note: `StructVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
error: aborting due to 3 previous errors

View File

@ -811,6 +811,9 @@ If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/util
[mentions."src/bootstrap/src/core/build_steps/llvm.rs"]
message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp."
[mentions."test/crashes"]
message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the correspondig `ui` subdir and add 'Fixes #<issueNr>' to the pr description to autoclose the issue upon merge."
[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
message = "Changes to the code generated for builtin derived traits."
cc = ["@nnethercote"]
@ -949,6 +952,7 @@ bootstrap = [
"@albertlarsan68",
"@onur-ozkan",
"@clubby789",
"@kobzol",
]
infra-ci = [
"@Mark-Simulacrum",