mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Warn about dead tuple struct fields
This commit is contained in:
parent
e141246cbb
commit
e3c7e04a44
@ -30,7 +30,7 @@ pub type DoubleDouble = DoubleFloat<ieee::Double>;
|
|||||||
// FIXME: Implement all operations in DoubleDouble, and delete these
|
// FIXME: Implement all operations in DoubleDouble, and delete these
|
||||||
// semantics.
|
// semantics.
|
||||||
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
|
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
|
||||||
pub struct FallbackS<F>(F);
|
pub struct FallbackS<F>(#[allow(unused)] F);
|
||||||
type Fallback<F> = ieee::IeeeFloat<FallbackS<F>>;
|
type Fallback<F> = ieee::IeeeFloat<FallbackS<F>>;
|
||||||
impl<F: Float> ieee::Semantics for FallbackS<F> {
|
impl<F: Float> ieee::Semantics for FallbackS<F> {
|
||||||
// Forbid any conversion to/from bits.
|
// Forbid any conversion to/from bits.
|
||||||
@ -45,7 +45,7 @@ impl<F: Float> ieee::Semantics for FallbackS<F> {
|
|||||||
// truncate the mantissa. The result of that second conversion
|
// truncate the mantissa. The result of that second conversion
|
||||||
// may be inexact, but should never underflow.
|
// may be inexact, but should never underflow.
|
||||||
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
|
// FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
|
||||||
pub struct FallbackExtendedS<F>(F);
|
pub struct FallbackExtendedS<F>(#[allow(unused)] F);
|
||||||
type FallbackExtended<F> = ieee::IeeeFloat<FallbackExtendedS<F>>;
|
type FallbackExtended<F> = ieee::IeeeFloat<FallbackExtendedS<F>>;
|
||||||
impl<F: Float> ieee::Semantics for FallbackExtendedS<F> {
|
impl<F: Float> ieee::Semantics for FallbackExtendedS<F> {
|
||||||
// Forbid any conversion to/from bits.
|
// Forbid any conversion to/from bits.
|
||||||
|
@ -630,6 +630,32 @@ declare_lint! {
|
|||||||
"detects attributes that were not used by the compiler"
|
"detects attributes that were not used by the compiler"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `unused_tuple_struct_fields` lint detects fields of tuple structs
|
||||||
|
/// that are never read.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #[warn(unused_tuple_struct_fields)]
|
||||||
|
/// struct S(i32, i32, i32);
|
||||||
|
/// let s = S(1, 2, 3);
|
||||||
|
/// let _ = (s.0, s.2);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Tuple struct fields that are never read anywhere may indicate a
|
||||||
|
/// mistake or unfinished code. To silence this warning, consider
|
||||||
|
/// removing the unused field(s) or, to preserve the numbering of the
|
||||||
|
/// remaining fields, change the unused field(s) to have unit type.
|
||||||
|
pub UNUSED_TUPLE_STRUCT_FIELDS,
|
||||||
|
Allow,
|
||||||
|
"detects tuple struct fields that are never read"
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `unreachable_code` lint detects unreachable code paths.
|
/// The `unreachable_code` lint detects unreachable code paths.
|
||||||
///
|
///
|
||||||
@ -3281,6 +3307,7 @@ declare_lint_pass! {
|
|||||||
UNSUPPORTED_CALLING_CONVENTIONS,
|
UNSUPPORTED_CALLING_CONVENTIONS,
|
||||||
BREAK_WITH_LABEL_AND_LOOP,
|
BREAK_WITH_LABEL_AND_LOOP,
|
||||||
UNUSED_ATTRIBUTES,
|
UNUSED_ATTRIBUTES,
|
||||||
|
UNUSED_TUPLE_STRUCT_FIELDS,
|
||||||
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
||||||
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
||||||
DEREF_INTO_DYN_SUPERTRAIT,
|
DEREF_INTO_DYN_SUPERTRAIT,
|
||||||
|
@ -53,7 +53,7 @@ pub(crate) fn target_from_impl_item<'tcx>(
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum ItemLike<'tcx> {
|
enum ItemLike<'tcx> {
|
||||||
Item(&'tcx Item<'tcx>),
|
Item(&'tcx Item<'tcx>),
|
||||||
ForeignItem(&'tcx ForeignItem<'tcx>),
|
ForeignItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CheckAttrVisitor<'tcx> {
|
struct CheckAttrVisitor<'tcx> {
|
||||||
@ -1995,12 +1995,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
|||||||
|
|
||||||
fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) {
|
fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) {
|
||||||
let target = Target::from_foreign_item(f_item);
|
let target = Target::from_foreign_item(f_item);
|
||||||
self.check_attributes(
|
self.check_attributes(f_item.hir_id(), f_item.span, target, Some(ItemLike::ForeignItem));
|
||||||
f_item.hir_id(),
|
|
||||||
f_item.span,
|
|
||||||
target,
|
|
||||||
Some(ItemLike::ForeignItem(f_item)),
|
|
||||||
);
|
|
||||||
intravisit::walk_foreign_item(self, f_item)
|
intravisit::walk_foreign_item(self, f_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_errors::{pluralize, MultiSpan};
|
use rustc_errors::{pluralize, Applicability, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
@ -42,6 +42,7 @@ struct MarkSymbolVisitor<'tcx> {
|
|||||||
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
|
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
|
||||||
live_symbols: FxHashSet<LocalDefId>,
|
live_symbols: FxHashSet<LocalDefId>,
|
||||||
repr_has_repr_c: bool,
|
repr_has_repr_c: bool,
|
||||||
|
repr_has_repr_simd: bool,
|
||||||
in_pat: bool,
|
in_pat: bool,
|
||||||
ignore_variant_stack: Vec<DefId>,
|
ignore_variant_stack: Vec<DefId>,
|
||||||
// maps from tuple struct constructors to tuple struct items
|
// maps from tuple struct constructors to tuple struct items
|
||||||
@ -220,6 +221,32 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_tuple_field_pattern_match(
|
||||||
|
&mut self,
|
||||||
|
lhs: &hir::Pat<'_>,
|
||||||
|
res: Res,
|
||||||
|
pats: &[hir::Pat<'_>],
|
||||||
|
dotdot: Option<usize>,
|
||||||
|
) {
|
||||||
|
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
|
||||||
|
ty::Adt(adt, _) => adt.variant_of_res(res),
|
||||||
|
_ => span_bug!(lhs.span, "non-ADT in tuple struct pattern"),
|
||||||
|
};
|
||||||
|
let first_n = pats.iter().enumerate().take(dotdot.unwrap_or(pats.len()));
|
||||||
|
let missing = variant.fields.len() - pats.len();
|
||||||
|
let last_n = pats
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.skip(dotdot.unwrap_or(pats.len()))
|
||||||
|
.map(|(idx, pat)| (idx + missing, pat));
|
||||||
|
for (idx, pat) in first_n.chain(last_n) {
|
||||||
|
if let PatKind::Wild = pat.kind {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.insert_def_id(variant.fields[idx].did);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn mark_live_symbols(&mut self) {
|
fn mark_live_symbols(&mut self) {
|
||||||
let mut scanned = FxHashSet::default();
|
let mut scanned = FxHashSet::default();
|
||||||
while let Some(id) = self.worklist.pop() {
|
while let Some(id) = self.worklist.pop() {
|
||||||
@ -274,12 +301,15 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let had_repr_c = self.repr_has_repr_c;
|
let had_repr_c = self.repr_has_repr_c;
|
||||||
|
let had_repr_simd = self.repr_has_repr_simd;
|
||||||
self.repr_has_repr_c = false;
|
self.repr_has_repr_c = false;
|
||||||
|
self.repr_has_repr_simd = false;
|
||||||
match node {
|
match node {
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
|
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
|
||||||
let def = self.tcx.adt_def(item.def_id);
|
let def = self.tcx.adt_def(item.def_id);
|
||||||
self.repr_has_repr_c = def.repr().c();
|
self.repr_has_repr_c = def.repr().c();
|
||||||
|
self.repr_has_repr_simd = def.repr().simd();
|
||||||
|
|
||||||
intravisit::walk_item(self, &item)
|
intravisit::walk_item(self, &item)
|
||||||
}
|
}
|
||||||
@ -315,6 +345,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
self.repr_has_repr_simd = had_repr_simd;
|
||||||
self.repr_has_repr_c = had_repr_c;
|
self.repr_has_repr_c = had_repr_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,9 +378,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
|||||||
) {
|
) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let has_repr_c = self.repr_has_repr_c;
|
let has_repr_c = self.repr_has_repr_c;
|
||||||
|
let has_repr_simd = self.repr_has_repr_simd;
|
||||||
let live_fields = def.fields().iter().filter_map(|f| {
|
let live_fields = def.fields().iter().filter_map(|f| {
|
||||||
let def_id = tcx.hir().local_def_id(f.hir_id);
|
let def_id = tcx.hir().local_def_id(f.hir_id);
|
||||||
if has_repr_c {
|
if has_repr_c || (f.is_positional() && has_repr_simd) {
|
||||||
return Some(def_id);
|
return Some(def_id);
|
||||||
}
|
}
|
||||||
if !tcx.visibility(f.hir_id.owner).is_public() {
|
if !tcx.visibility(f.hir_id.owner).is_public() {
|
||||||
@ -408,6 +440,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
|||||||
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
|
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
|
||||||
self.handle_res(res);
|
self.handle_res(res);
|
||||||
}
|
}
|
||||||
|
PatKind::TupleStruct(ref qpath, ref fields, dotdot) => {
|
||||||
|
let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
|
||||||
|
self.handle_tuple_field_pattern_match(pat, res, fields, dotdot);
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +476,11 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
|
fn has_allow_dead_code_or_lang_attr_helper(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
id: hir::HirId,
|
||||||
|
lint: &'static lint::Lint,
|
||||||
|
) -> bool {
|
||||||
let attrs = tcx.hir().attrs(id);
|
let attrs = tcx.hir().attrs(id);
|
||||||
if tcx.sess.contains_name(attrs, sym::lang) {
|
if tcx.sess.contains_name(attrs, sym::lang) {
|
||||||
return true;
|
return true;
|
||||||
@ -470,7 +510,11 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
|
tcx.lint_level_at_node(lint, id).0 == lint::Allow
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
|
||||||
|
has_allow_dead_code_or_lang_attr_helper(tcx, id, lint::builtin::DEAD_CODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These check_* functions seeds items that
|
// These check_* functions seeds items that
|
||||||
@ -623,6 +667,7 @@ fn live_symbols_and_ignored_derived_traits<'tcx>(
|
|||||||
maybe_typeck_results: None,
|
maybe_typeck_results: None,
|
||||||
live_symbols: Default::default(),
|
live_symbols: Default::default(),
|
||||||
repr_has_repr_c: false,
|
repr_has_repr_c: false,
|
||||||
|
repr_has_repr_simd: false,
|
||||||
in_pat: false,
|
in_pat: false,
|
||||||
ignore_variant_stack: vec![],
|
ignore_variant_stack: vec![],
|
||||||
struct_constructors,
|
struct_constructors,
|
||||||
@ -644,17 +689,30 @@ struct DeadVisitor<'tcx> {
|
|||||||
ignored_derived_traits: &'tcx FxHashMap<LocalDefId, Vec<(DefId, DefId)>>,
|
ignored_derived_traits: &'tcx FxHashMap<LocalDefId, Vec<(DefId, DefId)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ShouldWarnAboutField {
|
||||||
|
Yes(bool), // positional?
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> DeadVisitor<'tcx> {
|
impl<'tcx> DeadVisitor<'tcx> {
|
||||||
fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> bool {
|
fn should_warn_about_field(&mut self, field: &ty::FieldDef) -> ShouldWarnAboutField {
|
||||||
if self.live_symbols.contains(&field.did.expect_local()) {
|
if self.live_symbols.contains(&field.did.expect_local()) {
|
||||||
return false;
|
return ShouldWarnAboutField::No;
|
||||||
}
|
|
||||||
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
|
|
||||||
if is_positional {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
let field_type = self.tcx.type_of(field.did);
|
let field_type = self.tcx.type_of(field.did);
|
||||||
!field_type.is_phantom_data()
|
if field_type.is_phantom_data() {
|
||||||
|
return ShouldWarnAboutField::No;
|
||||||
|
}
|
||||||
|
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
|
||||||
|
if is_positional
|
||||||
|
&& self
|
||||||
|
.tcx
|
||||||
|
.layout_of(self.tcx.param_env(field.did).and(field_type))
|
||||||
|
.map_or(true, |layout| layout.is_zst())
|
||||||
|
{
|
||||||
|
return ShouldWarnAboutField::No;
|
||||||
|
}
|
||||||
|
ShouldWarnAboutField::Yes(is_positional)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn warn_multiple_dead_codes(
|
fn warn_multiple_dead_codes(
|
||||||
@ -662,6 +720,7 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
dead_codes: &[LocalDefId],
|
dead_codes: &[LocalDefId],
|
||||||
participle: &str,
|
participle: &str,
|
||||||
parent_item: Option<LocalDefId>,
|
parent_item: Option<LocalDefId>,
|
||||||
|
is_positional: bool,
|
||||||
) {
|
) {
|
||||||
if let Some(&first_id) = dead_codes.first() {
|
if let Some(&first_id) = dead_codes.first() {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
@ -669,7 +728,7 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|&def_id| tcx.item_name(def_id.to_def_id()).to_string())
|
.map(|&def_id| tcx.item_name(def_id.to_def_id()).to_string())
|
||||||
.collect();
|
.collect();
|
||||||
let spans = dead_codes
|
let spans: Vec<_> = dead_codes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&def_id| match tcx.def_ident_span(def_id) {
|
.map(|&def_id| match tcx.def_ident_span(def_id) {
|
||||||
Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()),
|
Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()),
|
||||||
@ -678,9 +737,13 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
tcx.struct_span_lint_hir(
|
tcx.struct_span_lint_hir(
|
||||||
lint::builtin::DEAD_CODE,
|
if is_positional {
|
||||||
|
lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
|
||||||
|
} else {
|
||||||
|
lint::builtin::DEAD_CODE
|
||||||
|
},
|
||||||
tcx.hir().local_def_id_to_hir_id(first_id),
|
tcx.hir().local_def_id_to_hir_id(first_id),
|
||||||
MultiSpan::from_spans(spans),
|
MultiSpan::from_spans(spans.clone()),
|
||||||
|lint| {
|
|lint| {
|
||||||
let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
|
let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
|
||||||
let span_len = dead_codes.len();
|
let span_len = dead_codes.len();
|
||||||
@ -702,6 +765,21 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
are = pluralize!("is", span_len),
|
are = pluralize!("is", span_len),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if is_positional {
|
||||||
|
err.multipart_suggestion(
|
||||||
|
&format!(
|
||||||
|
"consider changing the field{s} to be of unit type to \
|
||||||
|
suppress this warning while preserving the field \
|
||||||
|
numbering, or remove the field{s}",
|
||||||
|
s = pluralize!(span_len)
|
||||||
|
),
|
||||||
|
spans.iter().map(|sp| (*sp, "()".to_string())).collect(),
|
||||||
|
// "HasPlaceholders" because applying this fix by itself isn't
|
||||||
|
// enough: All constructor calls have to be adjusted as well
|
||||||
|
Applicability::HasPlaceholders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(parent_item) = parent_item {
|
if let Some(parent_item) = parent_item {
|
||||||
let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id());
|
let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id());
|
||||||
err.span_label(
|
err.span_label(
|
||||||
@ -743,6 +821,7 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
participle: &str,
|
participle: &str,
|
||||||
dead_codes: Vec<DeadVariant>,
|
dead_codes: Vec<DeadVariant>,
|
||||||
|
is_positional: bool,
|
||||||
) {
|
) {
|
||||||
let mut dead_codes = dead_codes
|
let mut dead_codes = dead_codes
|
||||||
.iter()
|
.iter()
|
||||||
@ -758,12 +837,13 @@ impl<'tcx> DeadVisitor<'tcx> {
|
|||||||
&group.map(|v| v.def_id).collect::<Vec<_>>(),
|
&group.map(|v| v.def_id).collect::<Vec<_>>(),
|
||||||
participle,
|
participle,
|
||||||
Some(def_id),
|
Some(def_id),
|
||||||
|
is_positional,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) {
|
fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) {
|
||||||
self.warn_multiple_dead_codes(&[id], participle, None);
|
self.warn_multiple_dead_codes(&[id], participle, None, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_definition(&mut self, def_id: LocalDefId) {
|
fn check_definition(&mut self, def_id: LocalDefId) {
|
||||||
@ -829,24 +909,37 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut is_positional = false;
|
||||||
let dead_fields = variant
|
let dead_fields = variant
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|field| {
|
.filter_map(|field| {
|
||||||
let def_id = field.did.expect_local();
|
let def_id = field.did.expect_local();
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
if visitor.should_warn_about_field(&field) {
|
if let ShouldWarnAboutField::Yes(is_pos) =
|
||||||
let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
|
visitor.should_warn_about_field(&field)
|
||||||
|
{
|
||||||
|
let level = tcx
|
||||||
|
.lint_level_at_node(
|
||||||
|
if is_pos {
|
||||||
|
is_positional = true;
|
||||||
|
lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
|
||||||
|
} else {
|
||||||
|
lint::builtin::DEAD_CODE
|
||||||
|
},
|
||||||
|
hir_id,
|
||||||
|
)
|
||||||
|
.0;
|
||||||
Some(DeadVariant { def_id, name: field.name, level })
|
Some(DeadVariant { def_id, name: field.name, level })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields)
|
visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields, is_positional)
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor.warn_dead_fields_and_variants(item.def_id, "constructed", dead_variants);
|
visitor.warn_dead_fields_and_variants(item.def_id, "constructed", dead_variants, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ enum EnumNoDrop<T1, T2> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct NonGenericNoDrop(i32);
|
struct NonGenericNoDrop(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
|
|
||||||
struct NonGenericWithDrop(i32);
|
struct NonGenericWithDrop(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
|
//~ MONO_ITEM fn std::ptr::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
|
||||||
|
|
||||||
impl Drop for NonGenericWithDrop {
|
impl Drop for NonGenericWithDrop {
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#![feature(start)]
|
#![feature(start)]
|
||||||
|
|
||||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
|
//~ MONO_ITEM fn std::ptr::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||||
struct Root(Intermediate);
|
struct Root(#[allow(unused_tuple_struct_fields)] Intermediate);
|
||||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
|
//~ MONO_ITEM fn std::ptr::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||||
struct Intermediate(Leaf);
|
struct Intermediate(#[allow(unused_tuple_struct_fields)] Leaf);
|
||||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
|
//~ MONO_ITEM fn std::ptr::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||||
struct Leaf;
|
struct Leaf;
|
||||||
|
|
||||||
@ -17,9 +17,9 @@ impl Drop for Leaf {
|
|||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RootGen<T>(IntermediateGen<T>);
|
struct RootGen<T>(#[allow(unused_tuple_struct_fields)] IntermediateGen<T>);
|
||||||
struct IntermediateGen<T>(LeafGen<T>);
|
struct IntermediateGen<T>(#[allow(unused_tuple_struct_fields)] LeafGen<T>);
|
||||||
struct LeafGen<T>(T);
|
struct LeafGen<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T> Drop for LeafGen<T> {
|
impl<T> Drop for LeafGen<T> {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
|
@ -40,7 +40,7 @@ impl Trait for u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Wrapper<T: ?Sized>(*const T);
|
struct Wrapper<T: ?Sized>(#[allow(unused_tuple_struct_fields)] *const T);
|
||||||
|
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
pub struct V<S>(S);
|
pub struct V<S>(#[allow(unused_tuple_struct_fields)] S);
|
||||||
pub trait An {
|
pub trait An {
|
||||||
type U;
|
type U;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#![feature(repr_align)]
|
#![feature(repr_align)]
|
||||||
|
|
||||||
#[repr(align(16))]
|
#[repr(align(16))]
|
||||||
pub struct A(i64);
|
pub struct A(#[allow(unused_tuple_struct_fields)] i64);
|
||||||
|
|
||||||
#[allow(improper_ctypes_definitions)]
|
#[allow(improper_ctypes_definitions)]
|
||||||
pub extern "C" fn foo(x: A) {}
|
pub extern "C" fn foo(x: A) {}
|
||||||
|
@ -92,7 +92,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
|
|||||||
extern fn rust_eh_personality() {}
|
extern fn rust_eh_personality() {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Page([[u64; 32]; 16]);
|
struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
|
@ -79,7 +79,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
|
|||||||
extern fn rust_eh_personality() {}
|
extern fn rust_eh_personality() {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Page([[u64; 32]; 16]);
|
struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Foo(Box<[u8]>);
|
struct Foo(#[allow(unused_tuple_struct_fields)] Box<[u8]>);
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
println!("{:?}", Foo(Box::new([0, 1, 2])));
|
println!("{:?}", Foo(Box::new([0, 1, 2])));
|
||||||
|
@ -17,7 +17,7 @@ impl Foo for Def {
|
|||||||
const X: i32 = 97;
|
const X: i32 = 97;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Proxy<T>(T);
|
struct Proxy<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T: Foo> Foo for Proxy<T> {
|
impl<T: Foo> Foo for Proxy<T> {
|
||||||
const X: i32 = T::X;
|
const X: i32 = T::X;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
trait Tr1 { type As1; }
|
trait Tr1 { type As1; }
|
||||||
trait Tr2 { type As2; }
|
trait Tr2 { type As2; }
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
trait Device {
|
trait Device {
|
||||||
type Resources;
|
type Resources;
|
||||||
}
|
}
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Foo<D, R>(D, R);
|
struct Foo<D, R>(D, R);
|
||||||
|
|
||||||
trait Tr {
|
trait Tr {
|
||||||
|
@ -9,7 +9,7 @@ pub trait UnifyKey {
|
|||||||
fn dummy(&self) { }
|
fn dummy(&self) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Node<K:UnifyKey>(K, K::Value);
|
pub struct Node<K:UnifyKey>(#[allow(unused_tuple_struct_fields)] K, K::Value);
|
||||||
|
|
||||||
fn foo<K : UnifyKey<Value=Option<V>>,V : Clone>(node: &Node<K>) -> Option<V> {
|
fn foo<K : UnifyKey<Value=Option<V>>,V : Clone>(node: &Node<K>) -> Option<V> {
|
||||||
node.1.clone()
|
node.1.clone()
|
||||||
|
@ -17,7 +17,7 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
const BIG_FUT_SIZE: usize = 1024;
|
const BIG_FUT_SIZE: usize = 1024;
|
||||||
struct BigFut([u8; BIG_FUT_SIZE]);
|
struct BigFut(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
|
||||||
|
|
||||||
impl BigFut {
|
impl BigFut {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
@ -16,7 +16,7 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
const BIG_FUT_SIZE: usize = 1024;
|
const BIG_FUT_SIZE: usize = 1024;
|
||||||
struct Big([u8; BIG_FUT_SIZE]);
|
struct Big(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
|
||||||
|
|
||||||
impl Big {
|
impl Big {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
@ -9,7 +9,7 @@ unsafe auto trait AutoUnsafe {}
|
|||||||
impl !Auto for bool {}
|
impl !Auto for bool {}
|
||||||
impl !AutoUnsafe for bool {}
|
impl !AutoUnsafe for bool {}
|
||||||
|
|
||||||
struct AutoBool(bool);
|
struct AutoBool(#[allow(unused_tuple_struct_fields)] bool);
|
||||||
|
|
||||||
impl Auto for AutoBool {}
|
impl Auto for AutoBool {}
|
||||||
unsafe impl AutoUnsafe for AutoBool {}
|
unsafe impl AutoUnsafe for AutoBool {}
|
||||||
|
@ -15,7 +15,7 @@ trait Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Token<T>(T::Item) where T: Iterator;
|
struct Token<T>(#[allow(unused_tuple_struct_fields)] T::Item) where T: Iterator;
|
||||||
|
|
||||||
impl<T> Parser for Token<T> where T: Iterator {
|
impl<T> Parser for Token<T> where T: Iterator {
|
||||||
type Input = T;
|
type Input = T;
|
||||||
@ -25,7 +25,7 @@ impl<T> Parser for Token<T> where T: Iterator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Chain<L, R>(L, R);
|
struct Chain<L, R>(#[allow(unused_tuple_struct_fields)] L, #[allow(unused_tuple_struct_fields)] R);
|
||||||
|
|
||||||
impl<L, R> Parser for Chain<L, R> where L: Parser, R: Parser<Input = L::Input> {
|
impl<L, R> Parser for Chain<L, R> where L: Parser, R: Parser<Input = L::Input> {
|
||||||
type Input = L::Input;
|
type Input = L::Input;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
enum color {
|
enum color {
|
||||||
rgb(isize, isize, isize),
|
rgb(isize, isize, isize),
|
||||||
rgba(isize, isize, isize, isize),
|
rgba(isize, isize, isize, isize),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
enum blah { a(isize, isize, usize), b(isize, isize), c, }
|
enum blah { a(isize, isize, #[allow(unused_tuple_struct_fields)] usize), b(isize, isize), c, }
|
||||||
|
|
||||||
fn or_alt(q: blah) -> isize {
|
fn or_alt(q: blah) -> isize {
|
||||||
match q { blah::a(x, y, _) | blah::b(x, y) => { return x + y; } blah::c => { return 0; } }
|
match q { blah::a(x, y, _) | blah::b(x, y) => { return x + y; } blah::c => { return 0; } }
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
enum clam<T> { a(T), }
|
enum clam<T> { a(#[allow(unused_tuple_struct_fields)] T), }
|
||||||
|
|
||||||
pub fn main() { let c = clam::a(2); match c { clam::a::<isize>(_) => { } } }
|
pub fn main() { let c = clam::a(2); match c { clam::a::<isize>(_) => { } } }
|
||||||
|
@ -12,7 +12,7 @@ use trait_superkinds_in_metadata::RequiresCopy;
|
|||||||
use std::marker;
|
use std::marker;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct X<T>(T);
|
struct X<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T:Sync> RequiresShare for X<T> { }
|
impl<T:Sync> RequiresShare for X<T> { }
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Test that `Clone` is correctly implemented for builtin types.
|
// Test that `Clone` is correctly implemented for builtin types.
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct S(i32);
|
struct S(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
|
|
||||||
fn test_clone<T: Clone>(arg: T) {
|
fn test_clone<T: Clone>(arg: T) {
|
||||||
let _ = arg.clone();
|
let _ = arg.clone();
|
||||||
|
@ -18,10 +18,10 @@ impl Foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S(Foo);
|
struct S(#[allow(unused_tuple_struct_fields)] Foo);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct T(i32);
|
struct T(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
|
|
||||||
struct U(S, T);
|
struct U(S, T);
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ impl Foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S(Foo);
|
struct S(#[allow(unused_tuple_struct_fields)] Foo);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct T(i32);
|
struct T(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
|
|
||||||
struct U(S, T);
|
struct U(S, T);
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ impl Drop for Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ConstainsDropField(Foo, Foo);
|
struct ConstainsDropField(Foo, #[allow(unused_tuple_struct_fields)] Foo);
|
||||||
|
|
||||||
// `t` needs Drop because one of its elements needs drop,
|
// `t` needs Drop because one of its elements needs drop,
|
||||||
// therefore precise capture might affect drop ordering
|
// therefore precise capture might affect drop ordering
|
||||||
|
@ -13,7 +13,7 @@ impl Drop for Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ConstainsDropField(Foo, Foo);
|
struct ConstainsDropField(Foo, #[allow(unused_tuple_struct_fields)] Foo);
|
||||||
|
|
||||||
// `t` needs Drop because one of its elements needs drop,
|
// `t` needs Drop because one of its elements needs drop,
|
||||||
// therefore precise capture might affect drop ordering
|
// therefore precise capture might affect drop ordering
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
#![allow(unused_assignments)]
|
#![allow(unused_assignments)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
enum Foo {
|
enum Foo {
|
||||||
Bar(u32, u32),
|
Bar(u32, u32),
|
||||||
Baz(&'static u32, &'static u32)
|
Baz(&'static u32, &'static u32)
|
||||||
|
@ -20,5 +20,5 @@ impl<T> Test<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait Foo { fn dummy(&self) { }}
|
trait Foo { fn dummy(&self) { }}
|
||||||
struct Output(isize);
|
struct Output(#[allow(unused_tuple_struct_fields)] isize);
|
||||||
impl Foo for Output {}
|
impl Foo for Output {}
|
||||||
|
@ -9,6 +9,7 @@ trait Foo {
|
|||||||
const ASSOC: usize = 1;
|
const ASSOC: usize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Iced<T: Foo>(T, [(); T::ASSOC])
|
struct Iced<T: Foo>(T, [(); T::ASSOC])
|
||||||
where
|
where
|
||||||
[(); T::ASSOC]: ;
|
[(); T::ASSOC]: ;
|
||||||
|
@ -9,6 +9,7 @@ trait Foo {
|
|||||||
const ASSOC: usize = 1;
|
const ASSOC: usize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Iced<T: Foo>(T, [(); T::ASSOC])
|
struct Iced<T: Foo>(T, [(); T::ASSOC])
|
||||||
where
|
where
|
||||||
[(); T::ASSOC]: ;
|
[(); T::ASSOC]: ;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
extern crate const_generic_lib;
|
extern crate const_generic_lib;
|
||||||
|
|
||||||
struct Container(const_generic_lib::Alias);
|
struct Container(#[allow(unused_tuple_struct_fields)] const_generic_lib::Alias);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8]));
|
let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8]));
|
||||||
|
@ -16,7 +16,7 @@ impl BlockCipher for BarCipher {
|
|||||||
const BLOCK_SIZE: usize = 32;
|
const BLOCK_SIZE: usize = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Block<C>(C);
|
pub struct Block<C>(#[allow(unused_tuple_struct_fields)] C);
|
||||||
|
|
||||||
pub fn test<C: BlockCipher, const M: usize>()
|
pub fn test<C: BlockCipher, const M: usize>()
|
||||||
where
|
where
|
||||||
|
@ -6,7 +6,7 @@ trait Nat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Zero;
|
struct Zero;
|
||||||
struct Succ<N>(N);
|
struct Succ<N>(#[allow(unused_tuple_struct_fields)] N);
|
||||||
|
|
||||||
impl Nat for Zero {
|
impl Nat for Zero {
|
||||||
const VALUE: usize = 0;
|
const VALUE: usize = 0;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Trivial(u8, f32);
|
struct Trivial(u8, f32);
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct NonTrivial(u8, String);
|
struct NonTrivial(u8, String);
|
||||||
|
|
||||||
const CONST_U8: bool = mem::needs_drop::<u8>();
|
const CONST_U8: bool = mem::needs_drop::<u8>();
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
struct Foo(u32);
|
struct Foo(#[allow(unused_tuple_struct_fields)] u32);
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Bar {
|
struct Bar {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#![warn(indirect_structural_match)]
|
#![warn(indirect_structural_match)]
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct NoDerive(u32);
|
struct NoDerive(#[allow(unused_tuple_struct_fields)] u32);
|
||||||
|
|
||||||
// This impl makes `NoDerive` irreflexive.
|
// This impl makes `NoDerive` irreflexive.
|
||||||
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
const HASH_LEN: usize = 20;
|
const HASH_LEN: usize = 20;
|
||||||
struct Hash([u8; HASH_LEN]);
|
struct Hash(#[allow(unused_tuple_struct_fields)] [u8; HASH_LEN]);
|
||||||
fn init_hash(_: &mut [u8; HASH_LEN]) {}
|
fn init_hash(_: &mut [u8; HASH_LEN]) {}
|
||||||
|
|
||||||
fn foo<'a>() -> &'a () {
|
fn foo<'a>() -> &'a () {
|
||||||
|
@ -4,7 +4,7 @@ use std::cell::Cell;
|
|||||||
|
|
||||||
const NONE_CELL_STRING: Option<Cell<String>> = None;
|
const NONE_CELL_STRING: Option<Cell<String>> = None;
|
||||||
|
|
||||||
struct Foo<T>(T);
|
struct Foo<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
impl<T> Foo<T> {
|
impl<T> Foo<T> {
|
||||||
const FOO: Option<Box<T>> = None;
|
const FOO: Option<Box<T>> = None;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct Foo(u32);
|
struct Foo(#[allow(unused_tuple_struct_fields)] u32);
|
||||||
|
|
||||||
const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
|
const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct S<T>(T, ());
|
struct S<T>(T, ());
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
@ -23,7 +23,7 @@ impl Clone for Liar {
|
|||||||
|
|
||||||
/// This struct is actually Copy... at least, it thinks it is!
|
/// This struct is actually Copy... at least, it thinks it is!
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct Innocent(Liar);
|
struct Innocent(#[allow(unused_tuple_struct_fields)] Liar);
|
||||||
|
|
||||||
impl Innocent {
|
impl Innocent {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
@ -3,6 +3,7 @@ fn main() {}
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Little;
|
pub struct Little;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
pub struct Big(
|
pub struct Big(
|
||||||
Little,
|
Little,
|
||||||
Little,
|
Little,
|
||||||
|
@ -12,10 +12,10 @@ trait Foo { fn foo(&self, _: &str); }
|
|||||||
|
|
||||||
struct Dt<A: Foo>(&'static str, A);
|
struct Dt<A: Foo>(&'static str, A);
|
||||||
struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
|
struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
|
||||||
struct Pt<A: Foo, B: Foo>(&'static str, A, B);
|
struct Pt<A: Foo, B: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A, B);
|
||||||
struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B);
|
struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B, &'b B);
|
||||||
struct St<A: Foo>(&'static str, A);
|
struct St<A: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A);
|
||||||
struct Sr<'a, B:'a+Foo>(&'static str, &'a B);
|
struct Sr<'a, B:'a+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B);
|
||||||
|
|
||||||
impl<A: Foo> Drop for Dt<A> {
|
impl<A: Foo> Drop for Dt<A> {
|
||||||
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
|
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
|
||||||
|
@ -35,10 +35,10 @@ trait Foo { fn foo(&self, _: &str); }
|
|||||||
|
|
||||||
struct Dt<A: Foo>(&'static str, A);
|
struct Dt<A: Foo>(&'static str, A);
|
||||||
struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
|
struct Dr<'a, B:'a+Foo>(&'static str, &'a B);
|
||||||
struct Pt<A,B: Foo>(&'static str, A, B);
|
struct Pt<A,B: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A, B);
|
||||||
struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B);
|
struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B, &'b B);
|
||||||
struct St<A: Foo>(&'static str, A);
|
struct St<A: Foo>(&'static str, #[allow(unused_tuple_struct_fields)] A);
|
||||||
struct Sr<'a, B:'a+Foo>(&'static str, &'a B);
|
struct Sr<'a, B:'a+Foo>(&'static str, #[allow(unused_tuple_struct_fields)] &'a B);
|
||||||
|
|
||||||
impl<A: Foo> Drop for Dt<A> {
|
impl<A: Foo> Drop for Dt<A> {
|
||||||
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
|
fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); }
|
||||||
|
@ -103,7 +103,7 @@ fn dynamic_drop(a: &Allocator, c: bool) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
|
struct TwoPtrs<'a>(Ptr<'a>, #[allow(unused_tuple_struct_fields)] Ptr<'a>);
|
||||||
fn struct_dynamic_drop(a: &Allocator, c0: bool, c1: bool, c: bool) {
|
fn struct_dynamic_drop(a: &Allocator, c0: bool, c1: bool, c: bool) {
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
let x;
|
let x;
|
||||||
|
@ -21,7 +21,7 @@ impl Drop for ScribbleOnDrop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Foo<T>(u32, T, Box<for <'r> fn(&'r T) -> String>);
|
struct Foo<T>(u32, T, #[allow(unused_tuple_struct_fields)] Box<for <'r> fn(&'r T) -> String>);
|
||||||
|
|
||||||
unsafe impl<#[may_dangle] T> Drop for Foo<T> {
|
unsafe impl<#[may_dangle] T> Drop for Foo<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
enum ADT {
|
enum ADT {
|
||||||
First(u32, u32),
|
First(u32, u32),
|
||||||
Second(u64)
|
Second(u64)
|
||||||
|
@ -27,13 +27,14 @@ enum CLike3 {
|
|||||||
D
|
D
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
enum ADT {
|
enum ADT {
|
||||||
First(u32, u32),
|
First(u32, u32),
|
||||||
Second(u64)
|
Second(u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NullablePointer {
|
enum NullablePointer {
|
||||||
Something(&'static u32),
|
Something(#[allow(unused_tuple_struct_fields)] &'static u32),
|
||||||
Nothing
|
Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
use std::ops::Generator;
|
use std::ops::Generator;
|
||||||
|
|
||||||
const FOO_SIZE: usize = 1024;
|
const FOO_SIZE: usize = 1024;
|
||||||
struct Foo([u8; FOO_SIZE]);
|
struct Foo(#[allow(unused_tuple_struct_fields)] [u8; FOO_SIZE]);
|
||||||
|
|
||||||
impl Drop for Foo {
|
impl Drop for Foo {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
extern crate default_type_params_xc;
|
extern crate default_type_params_xc;
|
||||||
|
|
||||||
struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
|
struct Vec<T, A = default_type_params_xc::Heap>(#[allow(unused_tuple_struct_fields)] Option<(T,A)>);
|
||||||
|
|
||||||
struct Foo;
|
struct Foo;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
enum wrapper<T> { wrapped(T), }
|
enum wrapper<T> { wrapped(#[allow(unused_tuple_struct_fields)] T), }
|
||||||
|
|
||||||
pub fn main() { let _w = wrapper::wrapped(vec![1, 2, 3, 4, 5]); }
|
pub fn main() { let _w = wrapper::wrapped(vec![1, 2, 3, 4, 5]); }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
struct S<T>(T);
|
struct S<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let _s = S(2);
|
let _s = S(2);
|
||||||
|
@ -76,7 +76,7 @@ impl<T> Trait2<T> for Foo {
|
|||||||
fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
|
fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Bar<T>(T);
|
pub struct Bar<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T> Bar<T> {
|
impl<T> Bar<T> {
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ impl<T> Trait3 for Bar<T> {
|
|||||||
fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
|
fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Baz<'a>(&'a i32);
|
pub struct Baz<'a>(#[allow(unused_tuple_struct_fields)] &'a i32);
|
||||||
|
|
||||||
impl<'a> Baz<'a> {
|
impl<'a> Baz<'a> {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -76,7 +76,7 @@ impl<T> Trait2<T> for Foo {
|
|||||||
fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
|
fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Bar<T>(T);
|
pub struct Bar<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T> Bar<T> {
|
impl<T> Bar<T> {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -111,7 +111,7 @@ impl<T> Trait3 for Bar<T> {
|
|||||||
fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
|
fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Baz<'a>(&'a i32);
|
pub struct Baz<'a>(#[allow(unused_tuple_struct_fields)] &'a i32);
|
||||||
|
|
||||||
impl<'a> Baz<'a> {
|
impl<'a> Baz<'a> {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
enum list<T> { cons(Box<T>, Box<list<T>>), nil, }
|
enum list<T> { #[allow(unused_tuple_struct_fields)] cons(Box<T>, Box<list<T>>), nil, }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let _a: list<isize> =
|
let _a: list<isize> =
|
||||||
|
@ -5,6 +5,6 @@
|
|||||||
// This used to cause memory corruption in stage 0.
|
// This used to cause memory corruption in stage 0.
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
enum thing<K> { some(K), }
|
enum thing<K> { some(#[allow(unused_tuple_struct_fields)] K), }
|
||||||
|
|
||||||
pub fn main() { let _x = thing::some("hi".to_string()); }
|
pub fn main() { let _x = thing::some("hi".to_string()); }
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
enum clam<T> { a(T), }
|
enum clam<T> { a(#[allow(unused_tuple_struct_fields)] T), }
|
||||||
|
|
||||||
pub fn main() { let _c = clam::a(3); }
|
pub fn main() { let _c = clam::a(3); }
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
enum option<T> { some(Box<T>), none, }
|
enum option<T> { some(#[allow(unused_tuple_struct_fields)] Box<T>), none, }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut a: option<isize> = option::some::<isize>(Box::new(10));
|
let mut a: option<isize> = option::some::<isize>(Box::new(10));
|
||||||
|
@ -15,7 +15,7 @@ pub fn future_from_generator<
|
|||||||
GenFuture(x)
|
GenFuture(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GenFuture<T: FakeGenerator<Yield = ()>>(T);
|
struct GenFuture<T: FakeGenerator<Yield = ()>>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<T: FakeGenerator<Yield = ()>> FakeFuture for GenFuture<T> {
|
impl<T: FakeGenerator<Yield = ()>> FakeFuture for GenFuture<T> {
|
||||||
type Output = T::Return;
|
type Output = T::Return;
|
||||||
|
@ -164,7 +164,7 @@ fn range_shadow_multi_pats() {
|
|||||||
|
|
||||||
fn misc() {
|
fn misc() {
|
||||||
enum Foo {
|
enum Foo {
|
||||||
Bar(usize, bool)
|
Bar(#[allow(unused_tuple_struct_fields)] usize, bool)
|
||||||
}
|
}
|
||||||
// This test basically mimics how trace_macros! macro is implemented,
|
// This test basically mimics how trace_macros! macro is implemented,
|
||||||
// which is a rare combination of vector patterns, multiple wild-card
|
// which is a rare combination of vector patterns, multiple wild-card
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Matrix4<S>(S);
|
struct Matrix4<S>(#[allow(unused_tuple_struct_fields)] S);
|
||||||
trait POrd<S> {}
|
trait POrd<S> {}
|
||||||
|
|
||||||
fn translate<S: POrd<S>>(s: S) -> Matrix4<S> { Matrix4(s) }
|
fn translate<S: POrd<S>>(s: S) -> Matrix4<S> { Matrix4(s) }
|
||||||
|
@ -12,7 +12,7 @@ impl Bar for BarImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Foo<B: Bar>(B);
|
struct Foo<B: Bar>(#[allow(unused_tuple_struct_fields)] B);
|
||||||
|
|
||||||
impl<B: Bar> Drop for Foo<B> {
|
impl<B: Bar> Drop for Foo<B> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Pair<T, V> (T, V);
|
struct Pair<T, V> (T, V);
|
||||||
|
|
||||||
impl Pair<
|
impl Pair<
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// cause compiler to loop. Note that no instances
|
// cause compiler to loop. Note that no instances
|
||||||
// of such a type could ever be constructed.
|
// of such a type could ever be constructed.
|
||||||
|
|
||||||
struct T(Box<T>);
|
struct T(#[allow(unused_tuple_struct_fields)] Box<T>);
|
||||||
|
|
||||||
trait ToStr2 {
|
trait ToStr2 {
|
||||||
fn my_to_string(&self) -> String;
|
fn my_to_string(&self) -> String;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
struct Node<T: ?Sized>(T);
|
struct Node<T: ?Sized>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: Box<Node<[isize]>> = box Node([]);
|
let x: Box<Node<[isize]>> = box Node([]);
|
||||||
|
@ -4,7 +4,7 @@ pub trait Foo {
|
|||||||
fn method2();
|
fn method2();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Slice<'a, T: 'a>(&'a [T]);
|
struct Slice<'a, T: 'a>(#[allow(unused_tuple_struct_fields)] &'a [T]);
|
||||||
|
|
||||||
impl<'a, T: 'a> Foo for Slice<'a, T> {
|
impl<'a, T: 'a> Foo for Slice<'a, T> {
|
||||||
fn method2() {
|
fn method2() {
|
||||||
|
@ -19,7 +19,7 @@ impl<'a, T> UserDefined for &'a T { }
|
|||||||
// ```
|
// ```
|
||||||
macro_rules! impl_drop {
|
macro_rules! impl_drop {
|
||||||
($Bound:ident, $Id:ident) => {
|
($Bound:ident, $Id:ident) => {
|
||||||
struct $Id<T: $Bound>(T);
|
struct $Id<T: $Bound>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
unsafe impl <#[may_dangle] T: $Bound> Drop for $Id<T> {
|
unsafe impl <#[may_dangle] T: $Bound> Drop for $Id<T> {
|
||||||
fn drop(&mut self) { }
|
fn drop(&mut self) { }
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
struct Foo(i32);
|
struct Foo(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
|
|
||||||
impl Drop for Foo {
|
impl Drop for Foo {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
trait Device {
|
trait Device {
|
||||||
type Resources;
|
type Resources;
|
||||||
}
|
}
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Foo<D, R>(D, R);
|
struct Foo<D, R>(D, R);
|
||||||
|
|
||||||
impl<D: Device> Foo<D, D::Resources> {
|
impl<D: Device> Foo<D, D::Resources> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
struct S<T: 'static>(Option<&'static T>);
|
struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
|
||||||
|
|
||||||
trait Tr { type Out; }
|
trait Tr { type Out; }
|
||||||
impl<T> Tr for T { type Out = T; }
|
impl<T> Tr for T { type Out = T; }
|
||||||
|
@ -3,8 +3,9 @@ pub trait Parser {
|
|||||||
type Input;
|
type Input;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Iter<P: Parser>(P, P::Input);
|
pub struct Iter<P: Parser>(#[allow(unused_tuple_struct_fields)] P, P::Input);
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
pub struct Map<P, F>(P, F);
|
pub struct Map<P, F>(P, F);
|
||||||
impl<P, F> Parser for Map<P, F> where F: FnMut(P) {
|
impl<P, F> Parser for Map<P, F> where F: FnMut(P) {
|
||||||
type Input = u8;
|
type Input = u8;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
struct S<T: 'static>(Option<&'static T>);
|
struct S<T: 'static>(#[allow(unused_tuple_struct_fields)] Option<&'static T>);
|
||||||
|
|
||||||
trait Tr { type Out; }
|
trait Tr { type Out; }
|
||||||
impl<T> Tr for T { type Out = T; }
|
impl<T> Tr for T { type Out = T; }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
trait Tr { type T; }
|
trait Tr { type T; }
|
||||||
impl Tr for u8 { type T=(); }
|
impl Tr for u8 { type T=(); }
|
||||||
struct S<I: Tr>(I::T);
|
struct S<I: Tr>(#[allow(unused_tuple_struct_fields)] I::T);
|
||||||
|
|
||||||
fn foo<I: Tr>(i: I::T) {
|
fn foo<I: Tr>(i: I::T) {
|
||||||
S::<I>(i);
|
S::<I>(i);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
struct Parser<'a>(Box<dyn FnMut(Parser) + 'a>);
|
struct Parser<'a>(#[allow(unused_tuple_struct_fields)] Box<dyn FnMut(Parser) + 'a>);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _x = Parser(Box::new(|_|{}));
|
let _x = Parser(Box::new(|_|{}));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
struct Wrapper<'a, T: ?Sized>(&'a mut i32, T);
|
struct Wrapper<'a, T: ?Sized>(&'a mut i32, #[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
impl<'a, T: ?Sized> Drop for Wrapper<'a, T> {
|
impl<'a, T: ?Sized> Drop for Wrapper<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
#![allow(unused_assignments)]
|
#![allow(unused_assignments)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
struct NoisyDrop<T: fmt::Debug>(T);
|
struct NoisyDrop<T: fmt::Debug>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
impl<T: fmt::Debug> Drop for NoisyDrop<T> {
|
impl<T: fmt::Debug> Drop for NoisyDrop<T> {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Bar<T: fmt::Debug>([*const NoisyDrop<T>; 2]);
|
struct Bar<T: fmt::Debug>(#[allow(unused_tuple_struct_fields)] [*const NoisyDrop<T>; 2]);
|
||||||
|
|
||||||
fn fine() {
|
fn fine() {
|
||||||
let (u,b);
|
let (u,b);
|
||||||
@ -15,6 +15,7 @@ fn fine() {
|
|||||||
b = Bar([&NoisyDrop(&u), &NoisyDrop(&u)]);
|
b = Bar([&NoisyDrop(&u), &NoisyDrop(&u)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct Bar2<T: fmt::Debug>(*const NoisyDrop<T>, *const NoisyDrop<T>);
|
struct Bar2<T: fmt::Debug>(*const NoisyDrop<T>, *const NoisyDrop<T>);
|
||||||
|
|
||||||
fn lolwut() {
|
fn lolwut() {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
|
struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
|
struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
|
||||||
|
|
||||||
struct Foo<T> { data: Vec<T> }
|
struct Foo<T> { data: Vec<T> }
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#![feature(dropck_eyepatch)]
|
#![feature(dropck_eyepatch)]
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
|
struct Concrete<'a>(#[allow(unused_tuple_struct_fields)] u32, Cell<Option<&'a Concrete<'a>>>);
|
||||||
|
|
||||||
struct Foo<T> { data: Vec<T> }
|
struct Foo<T> { data: Vec<T> }
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#![recursion_limit="1024"]
|
#![recursion_limit="1024"]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![recursion_limit="1024"]
|
#![recursion_limit="1024"]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
pub struct S0<T>(T,T);
|
pub struct S0<T>(T,T);
|
||||||
pub struct S1<T>(Option<Box<S0<S0<T>>>>,Option<Box<S0<S0<T>>>>);
|
pub struct S1<T>(Option<Box<S0<S0<T>>>>,Option<Box<S0<S0<T>>>>);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
error[E0283]: type annotations needed
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/issue-29147.rs:21:13
|
--> $DIR/issue-29147.rs:22:13
|
||||||
|
|
|
|
||||||
LL | let _ = <S5<_>>::xxx;
|
LL | let _ = <S5<_>>::xxx;
|
||||||
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
|
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
|
||||||
|
|
|
|
||||||
note: multiple `impl`s satisfying `S5<_>: Foo` found
|
note: multiple `impl`s satisfying `S5<_>: Foo` found
|
||||||
--> $DIR/issue-29147.rs:17:1
|
--> $DIR/issue-29147.rs:18:1
|
||||||
|
|
|
|
||||||
LL | impl Foo for S5<u32> { fn xxx(&self) {} }
|
LL | impl Foo for S5<u32> { fn xxx(&self) {} }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -6,7 +6,7 @@ struct Bar;
|
|||||||
const BAZ: Bar = Bar;
|
const BAZ: Bar = Bar;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Foo([Bar; 1]);
|
struct Foo(#[allow(unused_tuple_struct_fields)] [Bar; 1]);
|
||||||
|
|
||||||
struct Biz;
|
struct Biz;
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ impl<T> Front for Vec<T> {
|
|||||||
type Back = Vec<T>;
|
type Back = Vec<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PtrBack<T: Front>(Vec<T::Back>);
|
struct PtrBack<T: Front>(#[allow(unused_tuple_struct_fields)] Vec<T::Back>);
|
||||||
|
|
||||||
struct M(PtrBack<Vec<M>>);
|
struct M(#[allow(unused_tuple_struct_fields)] PtrBack<Vec<M>>);
|
||||||
|
|
||||||
#[allow(unused_must_use)]
|
#[allow(unused_must_use)]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum Foo {
|
enum Foo {
|
||||||
Foo(u8),
|
Foo(#[allow(unused_tuple_struct_fields)] u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
|
|
||||||
struct Thing<'a>(&'a str);
|
struct Thing<'a>(#[allow(unused_tuple_struct_fields)] &'a str);
|
||||||
impl<'a> Iterator for Thing<'a> {
|
impl<'a> Iterator for Thing<'a> {
|
||||||
type Item = &'a str;
|
type Item = &'a str;
|
||||||
fn next(&mut self) -> Option<&'a str> {
|
fn next(&mut self) -> Option<&'a str> {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
const SZ: usize = 100;
|
const SZ: usize = 100;
|
||||||
|
#[allow(unused_tuple_struct_fields)]
|
||||||
struct P<T: ?Sized>([u8; SZ], T);
|
struct P<T: ?Sized>([u8; SZ], T);
|
||||||
|
|
||||||
type Ack<T> = P<P<T>>;
|
type Ack<T> = P<P<T>>;
|
||||||
|
@ -153,7 +153,7 @@ mod stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Slot<T> {
|
enum Slot<T> {
|
||||||
Next(usize),
|
Next(#[allow(unused_tuple_struct_fields)] usize),
|
||||||
_Data { _a: T },
|
_Data { _a: T },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ trait X {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Y(isize);
|
struct Y(#[allow(unused_tuple_struct_fields)] isize);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Z<T: X+std::fmt::Debug> {
|
struct Z<T: X+std::fmt::Debug> {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use std::iter::{Fuse, Cloned};
|
use std::iter::{Fuse, Cloned};
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
|
||||||
struct Foo<'a, T: 'a>(&'a T);
|
struct Foo<'a, T: 'a>(#[allow(unused_tuple_struct_fields)] &'a T);
|
||||||
impl<'a, T: 'a> Copy for Foo<'a, T> {}
|
impl<'a, T: 'a> Copy for Foo<'a, T> {}
|
||||||
impl<'a, T: 'a> Clone for Foo<'a, T> {
|
impl<'a, T: 'a> Clone for Foo<'a, T> {
|
||||||
fn clone(&self) -> Self { *self }
|
fn clone(&self) -> Self { *self }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
struct A(bool);
|
struct A(#[allow(unused_tuple_struct_fields)] bool);
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let f = A;
|
let f = A;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use std::any::type_name;
|
use std::any::type_name;
|
||||||
|
|
||||||
struct Bar<M>(M);
|
struct Bar<M>(#[allow(unused_tuple_struct_fields)] M);
|
||||||
|
|
||||||
impl<M> Bar<M> {
|
impl<M> Bar<M> {
|
||||||
fn foo(&self) -> &'static str {
|
fn foo(&self) -> &'static str {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
trait FooBar {
|
trait FooBar {
|
||||||
fn dummy(&self) { }
|
fn dummy(&self) { }
|
||||||
}
|
}
|
||||||
struct Bar(i32);
|
struct Bar(#[allow(unused_tuple_struct_fields)] i32);
|
||||||
struct Foo { bar: Bar }
|
struct Foo { bar: Bar }
|
||||||
|
|
||||||
impl FooBar for Bar {}
|
impl FooBar for Bar {}
|
||||||
|
@ -14,10 +14,10 @@ use std::mem::size_of;
|
|||||||
use std::num::NonZeroU32 as N32;
|
use std::num::NonZeroU32 as N32;
|
||||||
use std::sync::{Mutex, RwLock};
|
use std::sync::{Mutex, RwLock};
|
||||||
|
|
||||||
struct Wrapper<T>(T);
|
struct Wrapper<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct Transparent<T>(T);
|
struct Transparent<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
struct NoNiche<T>(UnsafeCell<T>);
|
struct NoNiche<T>(UnsafeCell<T>);
|
||||||
|
|
||||||
|
@ -1,12 +1,37 @@
|
|||||||
// check-pass
|
#![deny(unused_tuple_struct_fields)]
|
||||||
|
//~^ NOTE: the lint level is defined here
|
||||||
|
|
||||||
#![deny(dead_code)]
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
const LEN: usize = 4;
|
const LEN: usize = 4;
|
||||||
|
|
||||||
#[derive(Debug)]
|
struct SingleUnused(i32, [u8; LEN], String);
|
||||||
struct Wrapper([u8; LEN]);
|
//~^ ERROR: field `1` is never read
|
||||||
|
//~| NOTE: field in this struct
|
||||||
|
//~| HELP: consider changing the field to be of unit type
|
||||||
|
|
||||||
|
struct MultipleUnused(i32, f32, String, u8);
|
||||||
|
//~^ ERROR: fields `0`, `1`, `2` and `3` are never read
|
||||||
|
//~| NOTE: fields in this struct
|
||||||
|
//~| HELP: consider changing the fields to be of unit type
|
||||||
|
|
||||||
|
struct GoodUnit(());
|
||||||
|
|
||||||
|
struct GoodPhantom(PhantomData<i32>);
|
||||||
|
|
||||||
|
struct Void;
|
||||||
|
struct GoodVoid(Void);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{:?}", Wrapper([0, 1, 2, 3]));
|
let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string());
|
||||||
|
let _ = w.0;
|
||||||
|
let _ = w.2;
|
||||||
|
|
||||||
|
let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8);
|
||||||
|
|
||||||
|
let gu = GoodUnit(());
|
||||||
|
let gp = GoodPhantom(PhantomData);
|
||||||
|
let gv = GoodVoid(Void);
|
||||||
|
|
||||||
|
let _ = (gu, gp, gv, m);
|
||||||
}
|
}
|
||||||
|
33
src/test/ui/lint/dead-code/tuple-struct-field.stderr
Normal file
33
src/test/ui/lint/dead-code/tuple-struct-field.stderr
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
error: field `1` is never read
|
||||||
|
--> $DIR/tuple-struct-field.rs:8:26
|
||||||
|
|
|
||||||
|
LL | struct SingleUnused(i32, [u8; LEN], String);
|
||||||
|
| ------------ ^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| field in this struct
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/tuple-struct-field.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(unused_tuple_struct_fields)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
|
||||||
|
|
|
||||||
|
LL | struct SingleUnused(i32, (), String);
|
||||||
|
| ~~
|
||||||
|
|
||||||
|
error: fields `0`, `1`, `2` and `3` are never read
|
||||||
|
--> $DIR/tuple-struct-field.rs:13:23
|
||||||
|
|
|
||||||
|
LL | struct MultipleUnused(i32, f32, String, u8);
|
||||||
|
| -------------- ^^^ ^^^ ^^^^^^ ^^
|
||||||
|
| |
|
||||||
|
| fields in this struct
|
||||||
|
|
|
||||||
|
help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
|
||||||
|
|
|
||||||
|
LL | struct MultipleUnused((), (), (), ());
|
||||||
|
| ~~ ~~ ~~ ~~
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![deny(dead_code)]
|
#![deny(dead_code)]
|
||||||
|
|
||||||
pub struct GenericFoo<T>(T);
|
pub struct GenericFoo<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||||
|
|
||||||
type Foo = GenericFoo<u32>;
|
type Foo = GenericFoo<u32>;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user