From 03652157f9da55ea58debabe22bb7105ef8ebdf7 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Sun, 31 Jul 2016 00:58:30 +0900 Subject: [PATCH] Suppress unused type parameter error when type has error field --- src/librustc/ty/util.rs | 15 +++++++++++++++ src/librustc_typeck/check/wfcheck.rs | 5 +++++ src/test/compile-fail/issue-35075.rs | 19 +++++++++++++++++++ .../resolve-type-param-in-item-in-trait.rs | 11 ++++------- 4 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/test/compile-fail/issue-35075.rs diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 21c14e6fe4c3b..fadf36471555b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -182,6 +182,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pat_util::arm_contains_ref_binding(arm) } + pub fn has_error_field(self, ty: Ty<'tcx>) -> bool { + match ty.sty { + ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { + for field in def.all_fields() { + let field_ty = field.ty(self, substs); + if let TyError = field_ty.sty { + return true; + } + } + } + _ => () + } + false + } + /// Returns the type of element at index `i` in tuple or tuple-like type `t`. /// For an enum `t`, `variant` is None only if `t` is a univariant enum. pub fn positional_element_ty(self, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 907cb734c2ff9..34a91b22981e1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -454,6 +454,11 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { item: &hir::Item, ast_generics: &hir::Generics) { + let ty = self.tcx().node_id_to_type(item.id); + if self.tcx().has_error_field(ty) { + return; + } + let item_def_id = self.tcx().map.local_def_id(item.id); let ty_predicates = self.tcx().lookup_predicates(item_def_id); let variances = self.tcx().item_variances(item_def_id); diff --git a/src/test/compile-fail/issue-35075.rs b/src/test/compile-fail/issue-35075.rs new file mode 100644 index 0000000000000..a70452dcbd09a --- /dev/null +++ b/src/test/compile-fail/issue-35075.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Bar { + inner: Foo //~ ERROR type name `Foo` is undefined or not in scope +} + +enum Baz { + Foo(Foo) //~ ERROR type name `Foo` is undefined or not in scope +} + +fn main() {} diff --git a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs index 30ff1ed0e26f7..a1572b8566642 100644 --- a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs +++ b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs @@ -13,9 +13,8 @@ // scope (in this case, the enum). trait TraitA { - fn outer(self) { + fn outer(&self) { enum Foo { - //~^ ERROR parameter `B` is never used Variance(A) //~^ ERROR can't use type parameters from outer function } @@ -23,23 +22,21 @@ trait TraitA { } trait TraitB { - fn outer(self) { + fn outer(&self) { struct Foo(A); //~^ ERROR can't use type parameters from outer function - //~^^ ERROR parameter `B` is never used } } trait TraitC { - fn outer(self) { + fn outer(&self) { struct Foo { a: A } //~^ ERROR can't use type parameters from outer function - //~^^ ERROR parameter `B` is never used } } trait TraitD { - fn outer(self) { + fn outer(&self) { fn foo(a: A) { } //~^ ERROR can't use type parameters from outer function }