diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-07-02 13:26:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-02 13:26:14 +0000 |
commit | 2b1d687d6a8eb959664e5299af229089341d14be (patch) | |
tree | 0a47a64c3df8feba4f52686bcc72a139f598a446 | |
parent | 458f7a5459a8907fa55a84248ba137281ac675c4 (diff) | |
parent | d882a0c97f82e9919d6ffe76183b78ed86db1793 (diff) | |
download | gcc-2b1d687d6a8eb959664e5299af229089341d14be.zip gcc-2b1d687d6a8eb959664e5299af229089341d14be.tar.gz gcc-2b1d687d6a8eb959664e5299af229089341d14be.tar.bz2 |
Merge #534
534: Unused struct fields r=philberty a=thomasyonug
1. make struct field carry the location info. Fixed #533
2. detect unused struct field.
Co-authored-by: Thomas Young <wenzhang5800@gmail.com>
29 files changed, 222 insertions, 76 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 7865a44..37d087c 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -1841,10 +1841,10 @@ private: Identifier field_name; std::unique_ptr<Type> field_type; - // should this store location info? - NodeId node_id; + Location locus; + public: // Returns whether struct field has any outer attributes. bool has_outer_attributes () const { return !outer_attrs.empty (); } @@ -1853,17 +1853,18 @@ public: bool has_visibility () const { return !visibility.is_error (); } StructField (Identifier field_name, std::unique_ptr<Type> field_type, - Visibility vis, + Visibility vis, Location locus, std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), field_name (std::move (field_name)), field_type (std::move (field_type)), - node_id (Analysis::Mappings::get ()->get_next_node_id ()) + node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus) {} // Copy constructor StructField (StructField const &other) : outer_attrs (other.outer_attrs), visibility (other.visibility), - field_name (other.field_name), node_id (other.node_id) + field_name (other.field_name), node_id (other.node_id), + locus (other.locus) { // guard to prevent null dereference if (other.field_type != nullptr) @@ -1903,7 +1904,8 @@ public: // Creates an error state struct field. static StructField create_error () { - return StructField (std::string (""), nullptr, Visibility::create_error ()); + return StructField (std::string (""), nullptr, Visibility::create_error (), + Location ()); } std::string as_string () const; @@ -1914,6 +1916,8 @@ public: Identifier get_field_name () const { return field_name; } + Location get_locus () const { return locus; } + // TODO: is this better? Or is a "vis_block" better? std::unique_ptr<Type> &get_field_type () { diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index b2a4d5f..7985faa 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -165,12 +165,10 @@ public: mappings->get_next_localdef_id ( crate_num)); - // FIXME - // AST::StructField is missing Location info - Location field_locus; HIR::StructField translated_field (mapping, field.get_field_name (), std::unique_ptr<HIR::Type> (type), vis, - field_locus, field.get_outer_attrs ()); + field.get_locus (), + field.get_outer_attrs ()); fields.push_back (std::move (translated_field)); return true; }); diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index a5069b7..10b1f61 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -1448,8 +1448,6 @@ public: Location locus; - // should this store location info? - // Returns whether struct field has any outer attributes. bool has_outer_attributes () const { return !outer_attrs.empty (); } diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc index 5cdb5d4..af871a5 100644 --- a/gcc/rust/lint/rust-lint-marklive.cc +++ b/gcc/rust/lint/rust-lint-marklive.cc @@ -92,89 +92,156 @@ void MarkLive::visit (HIR::PathInExpression &expr) { expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool { - NodeId ast_node_id = seg.get_mappings ().get_nodeid (); - NodeId ref_node_id = UNKNOWN_NODEID; - HirId ref; - if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - Resolver::Definition def; - if (!resolver->lookup_definition (ref_node_id, &def)) - { - rust_error_at (seg.get_locus (), - "unknown reference for resolved name"); - return false; - } - ref_node_id = def.parent; - } - else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) - { - return false; - } - - if (!mappings->lookup_node_to_hir (seg.get_mappings ().get_crate_num (), - ref_node_id, &ref)) - { - rust_error_at (seg.get_locus (), "reverse lookup failure"); - return false; - } - if (scannedSymbols.find (ref) == scannedSymbols.end ()) - { - worklist.push_back (ref); - } - liveSymbols.emplace (ref); - return true; + return visit_path_segment (seg); }); } void -MarkLive::visit (HIR::IdentifierExpr &expr) +MarkLive::visit (HIR::MethodCallExpr &expr) { + expr.get_receiver ()->accept_vis (*this); + visit_path_segment (expr.get_method_name ()); + expr.iterate_params ([&] (HIR::Expr *param) -> bool { + param->accept_vis (*this); + return true; + }); + NodeId ast_node_id = expr.get_mappings ().get_nodeid (); + NodeId ref_node_id = UNKNOWN_NODEID; + find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (), + expr.as_string ()); - // then lookup the reference_node_id + // node back to HIR + HirId ref; + node_id_to_hir_id (expr.get_mappings ().get_crate_num (), ref_node_id, ref, + expr.get_locus ()); + mark_hir_id (ref); +} + +bool +MarkLive::visit_path_segment (HIR::PathExprSegment seg) +{ + NodeId ast_node_id = seg.get_mappings ().get_nodeid (); NodeId ref_node_id = UNKNOWN_NODEID; if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) { - // these ref_node_ids will resolve to a pattern declaration but we are - // interested in the definition that this refers to get the parent id Resolver::Definition def; if (!resolver->lookup_definition (ref_node_id, &def)) { - rust_error_at (expr.get_locus (), + rust_error_at (seg.get_locus (), "unknown reference for resolved name"); - return; + return false; } ref_node_id = def.parent; } else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) { - rust_error_at (expr.get_locus (), - "Failed to lookup type reference for node: %s", - expr.as_string ().c_str ()); - return; + return false; } + HirId ref; + node_id_to_hir_id (seg.get_mappings ().get_crate_num (), ref_node_id, ref, + seg.get_locus ()); + mark_hir_id (ref); + return true; +} - if (ref_node_id == UNKNOWN_NODEID) +void +MarkLive::visit (HIR::FieldAccessExpr &expr) +{ + // visit receiver at first + expr.get_receiver_expr ()->accept_vis (*this); + + // resolve the receiver back to ADT type + TyTy::BaseType *receiver = nullptr; + if (!tyctx->lookup_type ( + expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver)) + { + rust_error_at (expr.get_receiver_expr ()->get_locus_slow (), + "unresolved type for receiver"); + } + rust_assert (receiver->get_kind () == TyTy::TypeKind::ADT); + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver); + + // get the field index + size_t index = 0; + adt->get_field (expr.get_field_name (), &index); + if (index >= adt->num_fields ()) { - rust_error_at (expr.get_locus (), "unresolved node: %s", - expr.as_string ().c_str ()); + rust_error_at (expr.get_receiver_expr ()->get_locus_slow (), + "cannot access struct %s by index: %ld", + adt->get_name ().c_str (), index); return; } + // get the field hir id + HirId field_id = adt->get_field (index)->get_ref (); + mark_hir_id (field_id); +} + +void +MarkLive::visit (HIR::TupleIndexExpr &expr) +{ + // TODO: unused tuple field detection + expr.get_tuple_expr ()->accept_vis (*this); +} + +void +MarkLive::visit (HIR::IdentifierExpr &expr) +{ + NodeId ast_node_id = expr.get_mappings ().get_nodeid (); + NodeId ref_node_id = UNKNOWN_NODEID; + find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (), + expr.as_string ()); // node back to HIR HirId ref; - if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - ref_node_id, &ref)) + node_id_to_hir_id (expr.get_mappings ().get_crate_num (), ref_node_id, ref, + expr.get_locus ()); + mark_hir_id (ref); +} + +void +MarkLive::mark_hir_id (HirId id) +{ + if (scannedSymbols.find (id) == scannedSymbols.end ()) + { + worklist.push_back (id); + } + liveSymbols.emplace (id); +} + +void +MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id, + Location locus, const std::string &node_name) +{ + if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) { - rust_error_at (expr.get_locus (), "reverse lookup failure"); + // these ref_node_ids will resolve to a pattern declaration but we are + // interested in the definition that this refers to get the parent id + Resolver::Definition def; + if (!resolver->lookup_definition (ref_node_id, &def)) + { + rust_error_at (locus, "unknown reference for resolved name"); + return; + } + ref_node_id = def.parent; + } + else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) + { + rust_error_at (locus, "Failed to lookup type reference for node: %s", + node_name.c_str ()); return; } +} - if (scannedSymbols.find (ref) == scannedSymbols.end ()) +void +MarkLive::node_id_to_hir_id (CrateNum crateNum, NodeId ref_node_id, HirId &ref, + Location locus) +{ + if (!mappings->lookup_node_to_hir (crateNum, ref_node_id, &ref)) { - worklist.push_back (ref); + rust_error_at (locus, "reverse lookup failure"); + return; } - liveSymbols.emplace (ref); } } // namespace Analysis diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h index 2db5294..72274d0 100644 --- a/gcc/rust/lint/rust-lint-marklive.h +++ b/gcc/rust/lint/rust-lint-marklive.h @@ -38,6 +38,9 @@ public: void visit (HIR::PathInExpression &expr) override; void visit (HIR::IdentifierExpr &expr) override; + void visit (HIR::FieldAccessExpr &expr) override; + void visit (HIR::TupleIndexExpr &expr) override; + void visit (HIR::MethodCallExpr &expr) override; void visit (HIR::BorrowExpr &expr) override { @@ -156,6 +159,10 @@ public: void visit (HIR::CallExpr &expr) override { expr.get_fnexpr ()->accept_vis (*this); + expr.iterate_params ([&] (HIR::Expr *expr) -> bool { + expr->accept_vis (*this); + return true; + }); } void visit (HIR::ArithmeticOrLogicalExpr &expr) override @@ -226,9 +233,17 @@ private: std::set<HirId> scannedSymbols; Analysis::Mappings *mappings; Resolver::Resolver *resolver; + Resolver::TypeCheckContext *tyctx; MarkLive (std::vector<HirId> worklist) : worklist (worklist), mappings (Analysis::Mappings::get ()), - resolver (Resolver::Resolver::get ()){}; + resolver (Resolver::Resolver::get ()), + tyctx (Resolver::TypeCheckContext::get ()){}; + + void mark_hir_id (HirId); + bool visit_path_segment (HIR::PathExprSegment); + void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id, + Location locus, const std::string &node_name); + void node_id_to_hir_id (CrateNum, NodeId, HirId &, Location); }; } // namespace Analysis diff --git a/gcc/rust/lint/rust-lint-scan-deadcode.h b/gcc/rust/lint/rust-lint-scan-deadcode.h index 1dee18a..ad48a47 100644 --- a/gcc/rust/lint/rust-lint-scan-deadcode.h +++ b/gcc/rust/lint/rust-lint-scan-deadcode.h @@ -46,15 +46,37 @@ public: void visit (HIR::Function &function) override { HirId hirId = function.get_mappings ().get_hirid (); - warning (hirId, function.get_locus (), "function", - function.get_function_name (), "used"); + if (should_warn (hirId)) + { + rust_warning_at (function.get_locus (), 0, "%s is never %s: %<%s%>", + "function", "used", + function.get_function_name ().c_str ()); + } } void visit (HIR::StructStruct &stct) override { HirId hirId = stct.get_mappings ().get_hirid (); - warning (hirId, stct.get_locus (), "struct", stct.get_identifier (), - "constructed"); + if (should_warn (hirId)) + { + rust_warning_at (stct.get_locus (), 0, "%s is never %s: %<%s%>", + "struct", "constructed", + stct.get_identifier ().c_str ()); + } + else + { + // only warn the unused fields when in unwarned struct. + stct.iterate ([&] (HIR::StructField &field) -> bool { + HirId field_hir_id = field.get_mappings ().get_hirid (); + if (should_warn (field_hir_id)) + { + rust_warning_at (field.get_locus (), 0, "%s is never %s: %<%s%>", + "field", "read", + field.get_field_name ().c_str ()); + } + return true; + }); + } } private: @@ -64,15 +86,11 @@ private: ScanDeadcode (std::set<HirId> &live_symbols) : live_symbols (live_symbols), resolver (Resolver::Resolver::get ()){}; - void warning (HirId hirId, Location loc, const std::string &span, - const std::string &name, const std::string &participle) const + bool should_warn (HirId hirId) { - if (live_symbols.find (hirId) == live_symbols.end ()) - { - rust_warning_at (loc, 0, "%s is never %s: %<%s%>", span.c_str (), - participle.c_str (), name.c_str ()); - return; - } + // TODO: There are more condition to check if should warn, i.e visibility, + // attributes. + return live_symbols.find (hirId) == live_symbols.end (); } }; diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 23e6234..9f8282b 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -4150,6 +4150,8 @@ Parser<ManagedTokenSource>::parse_struct_field () // parse visibility, if it exists AST::Visibility vis = parse_visibility (); + Location locus = lexer.peek_token ()->get_locus (); + // parse field name const_TokenPtr field_name_tok = lexer.peek_token (); if (field_name_tok->get_id () != IDENTIFIER) @@ -4180,7 +4182,7 @@ Parser<ManagedTokenSource>::parse_struct_field () } return AST::StructField (std::move (field_name), std::move (field_type), - std::move (vis), std::move (outer_attrs)); + std::move (vis), locus, std::move (outer_attrs)); } // Parses tuple fields in tuple/tuple struct declarations. diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_3.rs b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs index 0028ca5..9256df5 100644 --- a/gcc/testsuite/rust/compile/torture/forward_decl_3.rs +++ b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs @@ -5,5 +5,7 @@ fn main() { struct Foo { one: i32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } two: i32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/compile/torture/generics10.rs b/gcc/testsuite/rust/compile/torture/generics10.rs index 9526149..8473d49 100644 --- a/gcc/testsuite/rust/compile/torture/generics10.rs +++ b/gcc/testsuite/rust/compile/torture/generics10.rs @@ -3,6 +3,7 @@ struct Foo<T>(T); struct Bar<T> { a: Foo<T>, b: bool, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn test<T>(a: Bar<T>) -> Foo<T> { diff --git a/gcc/testsuite/rust/compile/torture/generics13.rs b/gcc/testsuite/rust/compile/torture/generics13.rs index 5c8795d..e924ab4 100644 --- a/gcc/testsuite/rust/compile/torture/generics13.rs +++ b/gcc/testsuite/rust/compile/torture/generics13.rs @@ -1,5 +1,6 @@ struct Foo<A> { a: A, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } struct GenericStruct<T> { diff --git a/gcc/testsuite/rust/compile/torture/generics14.rs b/gcc/testsuite/rust/compile/torture/generics14.rs index aa8fbf2..0d2e390 100644 --- a/gcc/testsuite/rust/compile/torture/generics14.rs +++ b/gcc/testsuite/rust/compile/torture/generics14.rs @@ -1,5 +1,6 @@ struct Foo<A> { a: A, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Foo<isize> { diff --git a/gcc/testsuite/rust/compile/torture/generics4.rs b/gcc/testsuite/rust/compile/torture/generics4.rs index 3ae3861..915cc49 100644 --- a/gcc/testsuite/rust/compile/torture/generics4.rs +++ b/gcc/testsuite/rust/compile/torture/generics4.rs @@ -1,6 +1,8 @@ struct Foo<T> { a: T, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: bool, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn test<T>(a: T) -> Foo<T> { diff --git a/gcc/testsuite/rust/compile/torture/generics6.rs b/gcc/testsuite/rust/compile/torture/generics6.rs index 283a118..5456b6d 100644 --- a/gcc/testsuite/rust/compile/torture/generics6.rs +++ b/gcc/testsuite/rust/compile/torture/generics6.rs @@ -3,6 +3,7 @@ struct Foo<T>(T); struct Bar<T> { a: Foo<T>, b: bool, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/generics7.rs b/gcc/testsuite/rust/compile/torture/generics7.rs index 2e89ce1..e8e5ca6 100644 --- a/gcc/testsuite/rust/compile/torture/generics7.rs +++ b/gcc/testsuite/rust/compile/torture/generics7.rs @@ -3,6 +3,7 @@ struct Foo<T>(T); struct Bar { a: Foo<i32>, b: bool, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/impl_block3.rs b/gcc/testsuite/rust/compile/torture/impl_block3.rs index 78ec459..22ce19f 100644 --- a/gcc/testsuite/rust/compile/torture/impl_block3.rs +++ b/gcc/testsuite/rust/compile/torture/impl_block3.rs @@ -1,6 +1,8 @@ struct Point { x: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } y: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Point { @@ -15,7 +17,9 @@ impl Point { struct Rectangle { p1: Point, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } p2: Point, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Rectangle { diff --git a/gcc/testsuite/rust/compile/torture/methods1.rs b/gcc/testsuite/rust/compile/torture/methods1.rs index df3663f..a8e384d 100644 --- a/gcc/testsuite/rust/compile/torture/methods1.rs +++ b/gcc/testsuite/rust/compile/torture/methods1.rs @@ -1,6 +1,7 @@ struct Point { x: f64, y: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Point { diff --git a/gcc/testsuite/rust/compile/torture/methods2.rs b/gcc/testsuite/rust/compile/torture/methods2.rs index 72ba29c..d63211b 100644 --- a/gcc/testsuite/rust/compile/torture/methods2.rs +++ b/gcc/testsuite/rust/compile/torture/methods2.rs @@ -1,6 +1,7 @@ struct Point { x: f64, y: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Point { diff --git a/gcc/testsuite/rust/compile/torture/methods3.rs b/gcc/testsuite/rust/compile/torture/methods3.rs index b0cb78f..55426f4 100644 --- a/gcc/testsuite/rust/compile/torture/methods3.rs +++ b/gcc/testsuite/rust/compile/torture/methods3.rs @@ -1,6 +1,7 @@ struct Point { x: f64, y: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } impl Point { diff --git a/gcc/testsuite/rust/compile/torture/nested_struct1.rs b/gcc/testsuite/rust/compile/torture/nested_struct1.rs index 56ce053..2bd5ead 100644 --- a/gcc/testsuite/rust/compile/torture/nested_struct1.rs +++ b/gcc/testsuite/rust/compile/torture/nested_struct1.rs @@ -1,11 +1,13 @@ struct Point { x: f64, y: f64, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } struct Rectangle { p1: Point, p2: Point, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs index 3c0b24a..39dc61a 100644 --- a/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs +++ b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn foo() -> Foo { diff --git a/gcc/testsuite/rust/compile/torture/struct_init.rs b/gcc/testsuite/rust/compile/torture/struct_init.rs index be0b963..1926f73 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init.rs @@ -1,6 +1,8 @@ struct Foo { one: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } two: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_init_3.rs b/gcc/testsuite/rust/compile/torture/struct_init_3.rs index 5e52d09..1398f8e 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init_3.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init_3.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_init_4.rs b/gcc/testsuite/rust/compile/torture/struct_init_4.rs index 57b6bd4..d4b2de8 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init_4.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init_4.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_init_5.rs b/gcc/testsuite/rust/compile/torture/struct_init_5.rs index 891f645..e7f9d16 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init_5.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init_5.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_init_6.rs b/gcc/testsuite/rust/compile/torture/struct_init_6.rs index e7f8a12..9a6241a 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init_6.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init_6.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/struct_init_7.rs b/gcc/testsuite/rust/compile/torture/struct_init_7.rs index a8c8050..a73d642 100644 --- a/gcc/testsuite/rust/compile/torture/struct_init_7.rs +++ b/gcc/testsuite/rust/compile/torture/struct_init_7.rs @@ -1,6 +1,8 @@ struct Foo { a: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } b: f32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/type_infer1.rs b/gcc/testsuite/rust/compile/torture/type_infer1.rs index b6502b5..3fee728 100644 --- a/gcc/testsuite/rust/compile/torture/type_infer1.rs +++ b/gcc/testsuite/rust/compile/torture/type_infer1.rs @@ -1,6 +1,8 @@ struct Foo { one: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } two: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn test(x: i32) -> i32 { diff --git a/gcc/testsuite/rust/compile/torture/type_infer5.rs b/gcc/testsuite/rust/compile/torture/type_infer5.rs index 1bccb4c..2c2602a 100644 --- a/gcc/testsuite/rust/compile/torture/type_infer5.rs +++ b/gcc/testsuite/rust/compile/torture/type_infer5.rs @@ -1,6 +1,7 @@ struct Foo { a: i32, b: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } } fn main() { diff --git a/gcc/testsuite/rust/compile/torture/unused_struct_field.rs b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs new file mode 100644 index 0000000..429b303 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs @@ -0,0 +1,9 @@ +struct Foo { + one: i32, +// { dg-warning "field is never read" "" { target *-*-* } .-1 } + two: i32 +} +fn main() { + let _a = Foo {one: 1, two: 2}; + let _b = _a.two; +}
\ No newline at end of file |