1
Fork 0

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_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.infcx.dcx() self.infcx.dcx()
} }

View file

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

View file

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

View file

@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt {
pub(super) struct IncludingTupleField(pub(super) bool); 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 /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
/// is moved after being invoked. /// is moved after being invoked.
/// ///
@ -771,7 +771,7 @@ struct CapturedMessageOpt {
maybe_reinitialized_locations_is_empty: bool, 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. /// Finds the spans associated to a move or copy of move_place at location.
pub(super) fn move_spans( pub(super) fn move_spans(
&self, &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) { pub(crate) fn report_move_errors(&mut self) {
let grouped_errors = self.group_move_errors(); let grouped_errors = self.group_move_errors();
for error in grouped_errors { for error in grouped_errors {

View file

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

View file

@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> {
pub(super) span: Span, pub(super) span: Span,
} }
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that /// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound, /// 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 /// 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 { pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
self.body.source.def_id().expect_local() self.body.source.def_id().expect_local()
} }

View file

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

View file

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

View file

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

View file

@ -27,6 +27,7 @@ pub(crate) mod decodable;
pub(crate) mod default; pub(crate) mod default;
pub(crate) mod encodable; pub(crate) mod encodable;
pub(crate) mod hash; pub(crate) mod hash;
pub(crate) mod smart_ptr;
#[path = "cmp/eq.rs"] #[path = "cmp/eq.rs"]
pub(crate) mod eq; 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, PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable, RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable, RustcEncodable: encodable::expand_deriving_rustc_encodable,
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
} }
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); 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(","); 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( let result = llvm::LLVMRustOptimize(
module.module_llvm.llmod(), module.module_llvm.llmod(),
&*module.module_llvm.tm, &*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_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_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 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_loop: bool,
pub vectorize_slp: bool, pub vectorize_slp: bool,
pub merge_functions: bool, pub merge_functions: bool,
pub inline_threshold: Option<u32>,
pub emit_lifetime_markers: bool, pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>, 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(), emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]), 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 rustc_target::spec::{abi, SanitizerSet};
use crate::errors; use crate::errors;
use crate::target_features::from_target_feature; use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature};
use crate::{
errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol},
target_features::check_target_feature_trait_unsafe,
};
fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage { fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
use rustc_middle::mir::mono::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. // coverage on a smaller scope within an excluded larger scope.
} }
Some(_) | None => { 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; codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
} }
Some(_) => { Some(_) => {
tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span }); tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span });
} }
None => { None => {
// Unfortunately, unconditionally using `llvm.used` causes // Unfortunately, unconditionally using `llvm.used` causes

View file

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

View file

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

View file

@ -188,7 +188,7 @@ impl SipHasher128 {
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 { pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 {
let mut hasher = SipHasher128 { let mut hasher = SipHasher128 {
nbuf: 0, nbuf: 0,
buf: MaybeUninit::uninit_array(), buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY],
state: State { state: State {
v0: key0 ^ 0x736f6d6570736575, v0: key0 ^ 0x736f6d6570736575,
// The XOR with 0xee is only done on 128-bit algorithm version. // 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") { 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") { if cg_flags.iter().any(|x| *x == "passes=list") {

View file

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

View file

@ -436,6 +436,8 @@ declare_features! (
(unstable, deprecated_suggestion, "1.61.0", Some(94785)), (unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns. /// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)), (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. /// Controls errors in trait implementations.
(unstable, do_not_recommend, "1.67.0", Some(51992)), (unstable, do_not_recommend, "1.67.0", Some(51992)),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.

View file

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

View file

@ -4,8 +4,10 @@ use crate::{errors, parse_in};
use rustc_ast::token::Delimiter; use rustc_ast::token::Delimiter;
use rustc_ast::tokenstream::DelimSpan; use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::MetaItemKind; use rustc_ast::{
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety}; self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind,
NestedMetaItem, Safety,
};
use rustc_errors::{Applicability, FatalError, PResult}; use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::{ use rustc_feature::{
AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP, 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`. /// Checks that the given meta-item is compatible with this `AttributeTemplate`.
fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool { 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 { match meta {
MetaItemKind::Word => template.word, 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(lit) if lit.kind.is_str() => template.name_value_str.is_some(),
MetaItemKind::NameValue(..) => false, MetaItemKind::NameValue(..) => false,
} }
@ -230,6 +236,7 @@ fn emit_malformed_attribute(
if let Some(descr) = template.list { if let Some(descr) = template.list {
suggestions.push(format!("#{inner}[{name}({descr})]")); 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 { if let Some(descr) = template.name_value_str {
suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); suggestions.push(format!("#{inner}[{name} = \"{descr}\"]"));
} }

View file

@ -103,18 +103,9 @@ passes_continue_labeled_block =
.label = labeled blocks cannot be `continue`'d .label = labeled blocks cannot be `continue`'d
.block_label = labeled block the `continue` points to .block_label = labeled block the `continue` points to
passes_coverage_fn_defn = passes_coverage_not_fn_or_closure =
`#[coverage]` may only be applied to function definitions attribute should be applied to a function definition or closure
.label = not a function or closure
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_dead_codes = passes_dead_codes =
{ $multiple -> { $multiple ->

View file

@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) self.check_diagnostic_on_unimplemented(attr.span, hir_id, target)
} }
[sym::inline] => self.check_inline(hir_id, attr, span, 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::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target),
[sym::marker] => self.check_marker(hir_id, attr, span, target), [sym::marker] => self.check_marker(hir_id, attr, span, target),
[sym::target_feature] => { [sym::target_feature] => {
@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
} }
/// Checks if a `#[coverage]` is applied directly to a function /// Checks that `#[coverage(..)]` is applied to a function or closure.
fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool {
match target { match target {
// #[coverage] on function is fine // #[coverage(..)] on function is fine
Target::Fn Target::Fn
| Target::Closure | Target::Closure
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, | 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, attr_span: attr.span,
defn_span: span, defn_span: span,
}); });

View file

@ -1010,6 +1010,22 @@ impl<'tcx> DeadVisitor<'tcx> {
parent_item: Option<LocalDefId>, parent_item: Option<LocalDefId>,
report_on: ReportOn, 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 { let Some(&first_item) = dead_codes.first() else {
return; return;
}; };
@ -1053,6 +1069,9 @@ impl<'tcx> DeadVisitor<'tcx> {
}; };
let encl_def_id = parent_item.unwrap_or(first_item.def_id); 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 = let ignored_derived_impls =
if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
let trait_list = ign_traits let trait_list = ign_traits

View file

@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure {
pub defn_span: Span, 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)] #[derive(Diagnostic)]
#[diag(passes_coverage_not_coverable, code = E0788)] #[diag(passes_coverage_not_fn_or_closure, code = E0788)]
pub struct IgnoredCoverageNotCoverable { pub struct CoverageNotFnOrClosure {
#[primary_span] #[primary_span]
pub attr_span: Span, pub attr_span: Span,
#[label] #[label]

View file

@ -1499,7 +1499,8 @@ options! {
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED], incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
"enable incremental compilation"), "enable incremental compilation"),
inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED], 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")] #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED], instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage reports \ "instrument the generated code to support LLVM source-based code coverage reports \

View file

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

View file

@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
ObligationCauseCode::RepeatElementCopy { ObligationCauseCode::RepeatElementCopy {
is_constable, is_constable,
elt_type, elt_type: _,
elt_span, elt_span,
elt_stmt_span, elt_stmt_span: _,
} => { } => {
err.note( err.note(
"the `Copy` trait is required because this value will be copied for each element of the array", "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(); 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 Ok(snip) = sm.span_to_snippet(elt_span)
{ {
let help_msg = format!( err.span_suggestion(
"consider creating a new `const` item and initializing it with {value_kind} \ elt_span,
to be used in the repeat position" "create an inline `const` block",
); format!("const {{ {snip} }}"),
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()),
],
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} else { } else {
@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.help("consider using `core::array::from_fn` to initialize the array"); 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"); 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) => { ObligationCauseCode::VariableType(hir_id) => {
if let Some(typeck_results) = &self.typeck_results 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>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> 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 raw_arr_ptr = raw_arr.as_mut_ptr().cast();
let (head, tail) = self.inner.as_slices(); let (head, tail) = self.inner.as_slices();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -202,7 +202,7 @@ where
T: Copy, T: Copy,
{ {
fn spec_next_chunk(&mut self) -> Result<[T; N], array::IntoIter<T, N>> { 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(); let len = self.len();

View file

@ -64,7 +64,7 @@ where
fn next_chunk<const N: usize>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> 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> { struct Guard<'a, T> {
array: &'a mut [MaybeUninit<T>], array: &'a mut [MaybeUninit<T>],

View file

@ -68,7 +68,7 @@ where
fn next_chunk<const N: usize>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> 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> { struct Guard<'a, T> {
array: &'a mut [MaybeUninit<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> { impl<T, const N: usize> Buffer<T, N> {
fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> { fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> {
let first_half = crate::array::iter_next_chunk(iter).ok()?; 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 }) 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> { impl<T: Clone, const N: usize> Clone for Buffer<T, N> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let mut buffer = Buffer { let mut buffer = Buffer {
buffer: [MaybeUninit::uninit_array(), MaybeUninit::uninit_array()], buffer: [[const { MaybeUninit::uninit() }; N], [const { MaybeUninit::uninit() }; N]],
start: self.start, start: self.start,
}; };
buffer.as_uninit_array_mut().write(self.as_array_ref().clone()); buffer.as_uninit_array_mut().write(self.as_array_ref().clone());

View file

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

View file

@ -1018,3 +1018,12 @@ pub trait FnPtr: Copy + Clone {
#[lang = "fn_ptr_addr"] #[lang = "fn_ptr_addr"]
fn addr(self) -> *const (); 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 /// # Examples
/// ///
/// ``` /// ```
/// #![feature(maybe_uninit_uninit_array)]
/// #![feature(maybe_uninit_array_assume_init)] /// #![feature(maybe_uninit_array_assume_init)]
/// use std::mem::MaybeUninit; /// 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[0].write(0);
/// array[1].write(1); /// array[1].write(1);
/// array[2].write(2); /// array[2].write(2);

View file

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

View file

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

View file

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

View file

@ -104,7 +104,7 @@ struct AlignedStorage<T, const N: usize> {
impl<T, const N: usize> AlignedStorage<T, N> { impl<T, const N: usize> AlignedStorage<T, N> {
fn new() -> Self { 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>] { fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {

View file

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

View file

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

View file

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

View file

@ -301,7 +301,7 @@ fn read_buf() {
}); });
let mut s = t!(srv.accept()).0; 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()); let mut buf = BorrowedBuf::from(buf.as_mut_slice());
t!(s.read_buf(buf.unfilled())); t!(s.read_buf(buf.unfilled()));
assert_eq!(buf.filled(), &[1, 2, 3, 4]); 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 child = cmd.spawn().unwrap();
let mut stdout = child.stdout.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()); let mut buf = BorrowedBuf::from(buf.as_mut_slice());
stdout.read_buf(buf.unfilled()).unwrap(); stdout.read_buf(buf.unfilled()).unwrap();

View file

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

View file

@ -184,20 +184,9 @@ incremental files will be stored.
## inline-threshold ## inline-threshold
This option lets you set the default threshold for inlining a function. It This option is deprecated and does nothing.
takes an unsigned integer as a value. Inlining is based on a cost model, where
a higher threshold will allow more inlining.
The default depends on the [opt-level](#opt-level): Consider using `-Cllvm-args=--inline-threshold=...`.
| 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 |
## instrument-coverage ## instrument-coverage

View file

@ -374,11 +374,12 @@ impl<'test> TestCx<'test> {
// if a test does not crash, consider it an error // if a test does not crash, consider it an error
if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) { if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) {
self.fatal( self.fatal(&format!(
"test no longer crashes/triggers ICE! Please give it a mearningful name, \ "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 \ 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 //@ 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. // 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: 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 = 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)]` help: consider annotating `Bar` with `#[derive(Copy)]`
| |
LL + #[derive(Copy)] LL + #[derive(Copy)]
LL | struct Bar; 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 help: create an inline `const` block
|
LL ~ const ARRAY_REPEAT_VALUE: Option<Bar> = no_copy();
LL ~ let _: [Option<Bar>; 2] = [ARRAY_REPEAT_VALUE; 2];
| |
LL | let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
| ~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error 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 --> $DIR/trait-error.rs:5:6
| |
LL | [Foo(String::new()); 4]; 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` note: required for `Foo<String>` to implement `Copy`
--> $DIR/trait-error.rs:1:10 --> $DIR/trait-error.rs:1:10
@ -10,13 +13,7 @@ note: required for `Foo<String>` to implement `Copy`
LL | #[derive(Copy, Clone)] LL | #[derive(Copy, Clone)]
| ^^^^ unsatisfied trait bound introduced in this `derive` macro | ^^^^ 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 = 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) = 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 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 --> $DIR/const-fn-in-vec.rs:1:47
| |
LL | static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5]; 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: 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 = 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 error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:7:34 --> $DIR/const-fn-in-vec.rs:7:34
| |
LL | let _strings: [String; 5] = [String::new(); 5]; 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 = 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 error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:9:48 --> $DIR/const-fn-in-vec.rs:9:48
| |
LL | let _maybe_strings: [Option<String>; 5] = [None; 5]; 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: 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 = 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 error: aborting due to 3 previous errors

View file

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

View file

@ -1,18 +1,109 @@
error: malformed `coverage` attribute input 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] LL | #[coverage = true]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
help: the following are the possible correct uses 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 `,` error: expected identifier, found `,`
--> $DIR/bad-syntax.rs:52:12 --> $DIR/bad-syntax.rs:42:12
| |
LL | #[coverage(,off)] LL | #[coverage(,off)]
| ^ | ^
@ -20,59 +111,29 @@ LL | #[coverage(,off)]
| expected identifier | expected identifier
| help: remove this comma | help: remove this comma
error: expected `coverage(off)` or `coverage(on)` error: multiple `coverage` attributes
--> $DIR/bad-syntax.rs:18:1 --> $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)` error: multiple `coverage` attributes
--> $DIR/bad-syntax.rs:23:1 --> $DIR/bad-syntax.rs:11:1
| |
LL | #[coverage = true] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^ help: remove this attribute
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:30:1
| |
LL | #[coverage()] note: attribute also specified here
| ^^^^^^^^^^^^^ --> $DIR/bad-syntax.rs:12:1
error: expected `coverage(off)` or `coverage(on)`
--> $DIR/bad-syntax.rs:33:1
| |
LL | #[coverage(off, off)] LL | #[coverage(on)]
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
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)]
| ^^^^^^^^^^^^^^^^^
error: aborting due to 11 previous errors 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 // and in places that cannot have a coverage attribute, to demonstrate the
// interaction between multiple errors. // interaction between multiple errors.
// FIXME(#126658): The error messages for using this syntax are inconsistent #[coverage = "off"]
// with the error message in other cases. They also sometimes appear together //~^ ERROR malformed `coverage` attribute input
// with other errors, and they suggest using the incorrect `#[coverage]` syntax. //~| ERROR attribute should be applied to a function definition or closure
#[coverage = "off"] //~ ERROR malformed `coverage` attribute input
mod my_mod {} mod my_mod {}
mod my_mod_inner { 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"] #[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; 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 { impl MyStruct {
#[coverage = "off"] #[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; 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 { trait MyTrait {
#[coverage = "off"] #[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; const X: u32;
#[coverage = "off"] #[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; 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 { impl MyTrait for MyStruct {
#[coverage = "off"] #[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; const X: u32 = 8;
#[coverage = "off"] #[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 = (); type T = ();
} }
#[coverage = "off"] #[coverage = "off"]
//~^ ERROR expected `coverage(off)` or `coverage(on)` //~^ ERROR malformed `coverage` attribute input
//~| ERROR malformed `coverage` attribute input
fn main() {} fn main() {}

View file

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

View file

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

View file

@ -1,101 +1,116 @@
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:8:1 --> $DIR/no-coverage.rs:7:1
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| LL | / trait Trait {
note: the lint level is defined here LL | | #[coverage(off)]
--> $DIR/no-coverage.rs:4:9 LL | | const X: u32;
| ... |
LL | #![warn(unused_attributes)] 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 error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:20:1 --> $DIR/no-coverage.rs:18:1
| |
LL | #[coverage(off)] 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 error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:42:5 --> $DIR/no-coverage.rs:39:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | let _ = ();
| ----------- not a function or closure
warning: `#[coverage]` may only be applied to function definitions error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:47:9 --> $DIR/no-coverage.rs:43:9
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | () => (),
| -------- not a function or closure
warning: `#[coverage]` may only be applied to function definitions error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:52:5 --> $DIR/no-coverage.rs:47:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | return ();
| --------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:11:5 --> $DIR/no-coverage.rs:9:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | const X: u32; LL | const X: u32;
| ------------- not coverable code | ------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:14:5 --> $DIR/no-coverage.rs:12:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | type T; LL | type T;
| ------- not coverable code | ------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:25:5 --> $DIR/no-coverage.rs:22:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | type T = Self; LL | type T = Self;
| -------------- not coverable code | -------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:28:5 --> $DIR/no-coverage.rs:25:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | type U = impl Trait; LL | type U = impl Trait;
| -------------------- not coverable code | -------------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:33:5 --> $DIR/no-coverage.rs:30:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | static X: u32; LL | static X: u32;
| -------------- not coverable code | -------------- not a function or closure
error[E0788]: `#[coverage]` must be applied to coverable code error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/no-coverage.rs:36:5 --> $DIR/no-coverage.rs:33:5
| |
LL | #[coverage(off)] LL | #[coverage(off)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | type T; 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 --> $DIR/no-coverage.rs:5:1
| |
LL | #![coverage(off)] LL | #![coverage(off)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^ not a function or closure
error: unconstrained opaque type error: unconstrained opaque type
--> $DIR/no-coverage.rs:29:14 --> $DIR/no-coverage.rs:26:14
| |
LL | type U = impl Trait; LL | type U = impl Trait;
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
= note: `U` must be used in combination with a concrete type within the same impl = 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`. 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 // Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare
// words, not part of a more complicated substructure. // 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() {} fn yes_list() {}
#[coverage(no(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` #[coverage(no(milord))] //~ ERROR malformed `coverage` attribute input
fn no_list() {} fn no_list() {}
#[coverage(yes = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` #[coverage(yes = "milord")] //~ ERROR malformed `coverage` attribute input
fn yes_key() {} 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 no_key() {}
fn main() {} 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 --> $DIR/subword.rs:7:1
| |
LL | #[coverage(yes(milord))] 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 --> $DIR/subword.rs:10:1
| |
LL | #[coverage(no(milord))] 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 --> $DIR/subword.rs:13:1
| |
LL | #[coverage(yes = "milord")] 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 --> $DIR/subword.rs:16:1
| |
LL | #[coverage(no = "milord")] 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 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 // and in places that cannot have a coverage attribute, to demonstrate the
// interaction between multiple errors. // 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] #[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
mod my_mod {} mod my_mod {}
// FIXME(#126658): This is silently allowed, but should not be.
mod my_mod_inner { mod my_mod_inner {
#![coverage] #![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; struct MyStruct;
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage] #[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyStruct { 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; const X: u32 = 7;
} }
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage] #[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
trait MyTrait { 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; 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; type T;
} }
// FIXME(#126658): This is silently allowed, but should not be.
#[coverage] #[coverage]
//~^ ERROR malformed `coverage` attribute input
//~| ERROR attribute should be applied to a function definition or closure
impl MyTrait for MyStruct { 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; 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 = (); type T = ();
} }
#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` #[coverage]
//~^ ERROR malformed `coverage` attribute input
fn main() {} fn main() {}

View file

@ -1,57 +1,277 @@
error[E0788]: `#[coverage]` must be applied to coverable code error: malformed `coverage` attribute input
--> $DIR/word-only.rs:23:1 --> $DIR/word-only.rs:11:1
| |
LL | #[coverage] 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 error: malformed `coverage` attribute input
--> $DIR/word-only.rs:36:5 --> $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]
| ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: malformed `coverage` attribute input
--> $DIR/word-only.rs:31:5
| |
LL | #[coverage] 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 error: malformed `coverage` attribute input
--> $DIR/word-only.rs:39:5 --> $DIR/word-only.rs:27: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:41:5
| |
LL | #[coverage] LL | #[coverage]
| ^^^^^^^^^^^ | ^^^^^^^^^^^
LL | type T;
| ------- not coverable code
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:29:5
| |
LL | #[coverage] help: the following are the possible correct uses
| ^^^^^^^^^^^ |
LL | const X: u32 = 7; LL | #[coverage(off)]
| ----------------- not coverable code |
LL | #[coverage(on)]
|
error[E0788]: `#[coverage]` must be applied to coverable code error: malformed `coverage` attribute input
--> $DIR/word-only.rs:46:5 --> $DIR/word-only.rs:46:5
| |
LL | #[coverage] LL | #[coverage]
| ^^^^^^^^^^^ | ^^^^^^^^^^^
LL | const X: u32 = 8;
| ----------------- not coverable code
error[E0788]: `#[coverage]` must be applied to coverable code
--> $DIR/word-only.rs:49:5
| |
LL | #[coverage] help: the following are the possible correct uses
| ^^^^^^^^^^^ |
LL | type T = (); LL | #[coverage(off)]
| ------------ not coverable code |
LL | #[coverage(on)]
|
error: expected `coverage(off)` or `coverage(on)` error: malformed `coverage` attribute input
--> $DIR/word-only.rs:53:1 --> $DIR/word-only.rs:37:1
| |
LL | #[coverage] LL | #[coverage]
| ^^^^^^^^^^^ | ^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL | #[coverage(off)]
|
LL | #[coverage(on)]
|
error: aborting due to 7 previous errors 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 a function or closure
error[E0788]: attribute should be applied to a function definition or closure
--> $DIR/word-only.rs:61:5
|
LL | #[coverage]
| ^^^^^^^^^^^
...
LL | type T = ();
| ------------ not a function or closure
error: aborting due to 23 previous errors
For more information about this error, try `rustc --explain E0788`. 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, 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() { fn main() {
let e = Enum::Variant2; let e = Enum::Variant2;
e.clone(); 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)] 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"] [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." 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"] [mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
message = "Changes to the code generated for builtin derived traits." message = "Changes to the code generated for builtin derived traits."
cc = ["@nnethercote"] cc = ["@nnethercote"]
@ -949,6 +952,7 @@ bootstrap = [
"@albertlarsan68", "@albertlarsan68",
"@onur-ozkan", "@onur-ozkan",
"@clubby789", "@clubby789",
"@kobzol",
] ]
infra-ci = [ infra-ci = [
"@Mark-Simulacrum", "@Mark-Simulacrum",