diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 57469d94ce8..595a2295674 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -465,29 +465,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { } } -// Check that trait with default impls (`impl Trait for ..`) contain no methods -struct DefaultedTraitVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } - -impl<'a, 'tcx> Visitor<'tcx> for DefaultedTraitVisitor<'a, 'tcx> { - fn visit_item(&mut self, item: &ast::Item) { - let tcx = self.ccx.tcx; - - match item.node { - ast::ItemTrait(_, _, _, ref trait_methods) => { - if ty::trait_has_default_impl(tcx, local_def(item.id)) && - !trait_methods.is_empty() - { - tcx.sess.span_err( - item.span, - "traits with default impls (`e.g. impl Trait for ..`) must have no \ - methods") - } - }, - _ => {}, - } - } -} - pub fn check_item_types(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); @@ -501,11 +478,6 @@ pub fn check_item_types(ccx: &CrateCtxt) { visit::walk_crate(&mut visit, krate); ccx.tcx.sess.abort_if_errors(); - - let mut visit = DefaultedTraitVisitor { ccx: ccx }; - visit::walk_crate(&mut visit, krate); - - ccx.tcx.sess.abort_if_errors(); } fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index aa7e2b6dcce..8185f48cb8c 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -118,7 +118,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(_, ref ast_generics, _, _) => { + ast::ItemTrait(_, ref ast_generics, _, ref items) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( @@ -127,6 +127,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &trait_predicates); self.check_variances(item, ast_generics, &trait_predicates, self.tcx().lang_items.phantom_fn()); + if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { + if !items.is_empty() { + ccx.tcx.sess.span_err( + item.span, + "traits with default impls (`e.g. unsafe impl Trait for ..`) must \ + have no methods or associated items") + } + } } _ => {} } diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs new file mode 100644 index 00000000000..ff5ac9de8d9 --- /dev/null +++ b/src/test/compile-fail/issue-23080-2.rs @@ -0,0 +1,29 @@ +// Copyright 2015 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. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +use std::marker::MarkerTrait; + +unsafe trait Trait: MarkerTrait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + type Output; +} + +unsafe impl Trait for .. {} + +fn call_method(x: T) {} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs index 61b9a1a14e0..99373a69697 100644 --- a/src/test/compile-fail/issue-23080.rs +++ b/src/test/compile-fail/issue-23080.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength + #![feature(optin_builtin_traits)] unsafe trait Trait { -//~^ error: traits with default impls (`e.g. impl Trait for ..`) must have no methods +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items fn method(&self) { println!("Hello"); }