Skip to content

Un-regress conflicting destructors #28681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 28, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/librustc/middle/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ use std::rc::Rc;
use syntax::ast;
use syntax::codemap;
use syntax::codemap::{Span, DUMMY_SP};
use util::nodemap::{FnvHashMap, NodeMap};
use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};

use self::combine::CombineFields;
use self::region_inference::{RegionVarBindings, RegionSnapshot};
@@ -92,6 +92,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {

pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,

// the set of predicates on which errors have been reported, to
// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,

// This is a temporary field used for toggling on normalization in the inference context,
// as we move towards the approach described here:
// https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
@@ -374,6 +378,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
region_vars: RegionVarBindings::new(tcx),
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
reported_trait_errors: RefCell::new(FnvHashSet()),
normalize: false,
err_count_on_creation: tcx.sess.err_count()
}
14 changes: 9 additions & 5 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
@@ -348,13 +348,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// this properly would result in the necessity of computing *type*
// reachability, which might result in a compile time loss.
fn mark_destructors_reachable(&mut self) {
for adt in self.tcx.adt_defs() {
if let Some(destructor_def_id) = adt.destructor() {
if destructor_def_id.is_local() {
self.reachable_symbols.insert(destructor_def_id.node);
let drop_trait = match self.tcx.lang_items.drop_trait() {
Some(id) => self.tcx.lookup_trait_def(id), None => { return }
};
drop_trait.for_each_impl(self.tcx, |drop_impl| {
for destructor in &self.tcx.impl_items.borrow()[&drop_impl] {
let destructor_did = destructor.def_id();
if destructor_did.is_local() {
self.reachable_symbols.insert(destructor_did.node);
}
}
}
})
}
}

36 changes: 34 additions & 2 deletions src/librustc/middle/traits/error_reporting.rs
Original file line number Diff line number Diff line change
@@ -28,11 +28,32 @@ use middle::def_id::DefId;
use middle::infer::InferCtxt;
use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty};
use middle::ty::fold::TypeFoldable;
use std::collections::HashMap;
use util::nodemap::{FnvHashMap, FnvHashSet};

use std::fmt;
use syntax::codemap::Span;
use syntax::attr::{AttributeMethods, AttrMetaMethods};

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct TraitErrorKey<'tcx> {
is_warning: bool,
span: Span,
predicate: ty::Predicate<'tcx>
}

impl<'tcx> TraitErrorKey<'tcx> {
fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
e: &FulfillmentError<'tcx>) -> Self {
let predicate =
infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
TraitErrorKey {
is_warning: is_warning(&e.obligation),
span: e.obligation.cause.span,
predicate: infcx.tcx.erase_regions(&predicate)
}
}
}

pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
errors: &Vec<FulfillmentError<'tcx>>) {
for error in errors {
@@ -42,6 +63,13 @@ pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,

fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
error: &FulfillmentError<'tcx>) {
let error_key = TraitErrorKey::from_error(infcx, error);
debug!("report_fulfillment_errors({:?}) - key={:?}",
error, error_key);
if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
debug!("report_fulfillment_errors: skipping duplicate");
return;
}
match error.code {
FulfillmentErrorCode::CodeSelectionError(ref e) => {
report_selection_error(infcx, &error.obligation, e);
@@ -97,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
(gen.name.as_str().to_string(),
trait_ref.substs.types.get(param, i)
.to_string())
}).collect::<HashMap<String, String>>();
}).collect::<FnvHashMap<String, String>>();
generic_map.insert("Self".to_string(),
trait_ref.self_ty().to_string());
let parser = Parser::new(&istring);
@@ -308,7 +336,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
"the trait `{}` cannot be made into an object",
tcx.item_path_str(trait_def_id));

let mut reported_violations = FnvHashSet();
for violation in violations {
if !reported_violations.insert(violation.clone()) {
continue;
}
match violation {
ObjectSafetyViolation::SizedSelf => {
tcx.sess.fileline_note(
6 changes: 6 additions & 0 deletions src/librustc/middle/traits/fulfill.rs
Original file line number Diff line number Diff line change
@@ -49,6 +49,12 @@ pub struct FulfillmentContext<'tcx> {
// than the `SelectionCache`: it avoids duplicate errors and
// permits recursive obligations, which are often generated from
// traits like `Send` et al.
//
// Note that because of type inference, a predicate can still
// occur twice in the predicates list, for example when 2
// initially-distinct type variables are unified after being
// inserted. Deduplicating the predicate set on selection had a
// significant performance cost the last time I checked.
duplicate_set: FulfilledPredicates<'tcx>,

// A list of all obligations that have been registered with this
2 changes: 2 additions & 0 deletions src/librustc/middle/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -21,10 +21,12 @@ use middle::subst;
use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty::fold::TypeFoldable;
use middle::infer::{self, fixup_err_to_string, InferCtxt};

use std::rc::Rc;
use syntax::ast;
use syntax::codemap::{Span, DUMMY_SP};

pub use self::error_reporting::TraitErrorKey;
pub use self::error_reporting::report_fulfillment_errors;
pub use self::error_reporting::report_overflow_error;
pub use self::error_reporting::report_selection_error;
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/object_safety.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty};
use std::rc::Rc;
use syntax::ast;

#[derive(Debug)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation<'tcx> {
/// Self : Sized declared on the trait
SizedSelf,
4 changes: 0 additions & 4 deletions src/librustc/middle/ty/context.rs
Original file line number Diff line number Diff line change
@@ -245,9 +245,6 @@ pub struct ctxt<'tcx> {
/// True if the variance has been computed yet; false otherwise.
pub variance_computed: Cell<bool>,

/// A method will be in this list if and only if it is a destructor.
pub destructors: RefCell<DefIdSet>,

/// Maps a DefId of a type to a list of its inherent impls.
/// Contains implementations of methods that are inherent to a type.
/// Methods in these implementations don't need to be exported.
@@ -475,7 +472,6 @@ impl<'tcx> ctxt<'tcx> {
normalized_cache: RefCell::new(FnvHashMap()),
lang_items: lang_items,
provided_method_sources: RefCell::new(DefIdMap()),
destructors: RefCell::new(DefIdSet()),
inherent_impls: RefCell::new(DefIdMap()),
impl_items: RefCell::new(DefIdMap()),
used_unsafe: RefCell::new(NodeSet()),
20 changes: 14 additions & 6 deletions src/librustc/middle/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -272,6 +272,20 @@ impl<'tcx> Method<'tcx> {
}
}

impl<'tcx> PartialEq for Method<'tcx> {
#[inline]
fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id }
}

impl<'tcx> Eq for Method<'tcx> {}

impl<'tcx> Hash for Method<'tcx> {
#[inline]
fn hash<H: Hasher>(&self, s: &mut H) {
self.def_id.hash(s)
}
}

#[derive(Clone, Copy, Debug)]
pub struct AssociatedConst<'tcx> {
pub name: Name,
@@ -1681,7 +1695,6 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
}

pub fn set_destructor(&self, dtor: DefId) {
assert!(self.destructor.get().is_none());
self.destructor.set(Some(dtor));
}

@@ -2315,11 +2328,6 @@ impl<'tcx> ctxt<'tcx> {
self.lookup_adt_def_master(did)
}

/// Return the list of all interned ADT definitions
pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
self.adt_defs.borrow().values().cloned().collect()
}

/// Given the did of an item, returns its full set of predicates.
pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
lookup_locally_or_in_crate_store(
19 changes: 9 additions & 10 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -1213,15 +1213,14 @@ impl LintPass for DropWithReprExtern {

impl LateLintPass for DropWithReprExtern {
fn check_crate(&mut self, ctx: &LateContext, _: &hir::Crate) {
for dtor_did in ctx.tcx.destructors.borrow().iter() {
let (drop_impl_did, dtor_self_type) =
if dtor_did.is_local() {
let impl_did = ctx.tcx.map.get_parent_did(dtor_did.node);
let ty = ctx.tcx.lookup_item_type(impl_did).ty;
(impl_did, ty)
} else {
continue;
};
let drop_trait = match ctx.tcx.lang_items.drop_trait() {
Some(id) => ctx.tcx.lookup_trait_def(id), None => { return }
};
drop_trait.for_each_impl(ctx.tcx, |drop_impl_did| {
if !drop_impl_did.is_local() {
return;
}
let dtor_self_type = ctx.tcx.lookup_item_type(drop_impl_did).ty;

match dtor_self_type.sty {
ty::TyEnum(self_type_def, _) |
@@ -1247,6 +1246,6 @@ impl LateLintPass for DropWithReprExtern {
}
_ => {}
}
}
})
}
}
8 changes: 1 addition & 7 deletions src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
@@ -620,13 +620,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
ty::TraitContainer(trait_def_id) => {
callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
}
ty::ImplContainer(..) => {
// Since `drop` is a trait method, we expect that any
// potential calls to it will wind up in the other
// arm. But just to be sure, check that the method id
// does not appear in the list of destructors.
assert!(!self.tcx().destructors.borrow().contains(&pick.item.def_id()));
}
ty::ImplContainer(..) => {}
}
}

10 changes: 6 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -431,17 +431,19 @@ pub fn check_item_bodies(ccx: &CrateCtxt) {
}

pub fn check_drop_impls(ccx: &CrateCtxt) {
for drop_method_did in ccx.tcx.destructors.borrow().iter() {
if drop_method_did.is_local() {
let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
let drop_trait = match ccx.tcx.lang_items.drop_trait() {
Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
};
drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
if drop_impl_did.is_local() {
match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
Ok(()) => {}
Err(()) => {
assert!(ccx.tcx.sess.has_errors());
}
}
}
}
});

ccx.tcx.sess.abort_if_errors();
}
7 changes: 2 additions & 5 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
@@ -126,7 +126,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Populate the table of destructors. It might seem a bit strange to
// do this here, but it's actually the most convenient place, since
// the coherence tables contain the trait -> type mappings.
self.populate_destructor_table();
self.populate_destructors();

// Check to make sure implementations of `Copy` are legal.
self.check_implementations_of_copy();
@@ -286,7 +286,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Destructors
//

fn populate_destructor_table(&self) {
fn populate_destructors(&self) {
let tcx = self.crate_context.tcx;
let drop_trait = match tcx.lang_items.drop_trait() {
Some(id) => id, None => { return }
@@ -309,9 +309,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
ty::TyEnum(type_def, _) |
ty::TyStruct(type_def, _) => {
type_def.set_destructor(method_def_id.def_id());
tcx.destructors
.borrow_mut()
.insert(method_def_id.def_id());
}
_ => {
// Destructors only work on nominal types.
Original file line number Diff line number Diff line change
@@ -32,5 +32,4 @@ fn ice<A>(a: A) {
let r = loop {};
r = r + a;
//~^ ERROR not implemented
//~| ERROR not implemented
}
1 change: 0 additions & 1 deletion src/test/compile-fail/associated-types-path-2.rs
Original file line number Diff line number Diff line change
@@ -39,7 +39,6 @@ pub fn f1_int_uint() {
pub fn f1_uint_uint() {
f1(2u32, 4u32);
//~^ ERROR the trait `Foo` is not implemented
//~| ERROR the trait `Foo` is not implemented
}

pub fn f1_uint_int() {
1 change: 0 additions & 1 deletion src/test/compile-fail/coerce-unsafe-to-closure.rs
Original file line number Diff line number Diff line change
@@ -11,5 +11,4 @@
fn main() {
let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
//~^ ERROR E0277
//~| ERROR E0277
}
2 changes: 0 additions & 2 deletions src/test/compile-fail/const-eval-overflow-4b.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR mismatched types
//~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
//~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
= [0; (i8::MAX as usize) + 1];

fn main() {
@@ -33,4 +32,3 @@ fn main() {
fn foo<T:fmt::Debug>(x: T) {
println!("{:?}", x);
}

2 changes: 0 additions & 2 deletions src/test/compile-fail/fn-variance-1.rs
Original file line number Diff line number Diff line change
@@ -20,10 +20,8 @@ fn main() {
apply(&3, takes_imm);
apply(&3, takes_mut);
//~^ ERROR (values differ in mutability)
//~| ERROR (values differ in mutability)

apply(&mut 3, takes_mut);
apply(&mut 3, takes_imm);
//~^ ERROR (values differ in mutability)
//~| ERROR (values differ in mutability)
}
3 changes: 0 additions & 3 deletions src/test/compile-fail/for-loop-bogosity.rs
Original file line number Diff line number Diff line change
@@ -25,9 +25,6 @@ pub fn main() {
y: 2,
};
for x in bogus { //~ ERROR `core::iter::Iterator` is not implemented for the type `MyStruct`
//~^ ERROR
//~^^ ERROR
// FIXME(#21528) not fulfilled obligation error should be reported once, not thrice
drop(x);
}
}
1 change: 0 additions & 1 deletion src/test/compile-fail/indexing-requires-a-uint.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@
fn main() {
fn bar<T>(_: T) {}
[0][0u8]; //~ ERROR: the trait `core::ops::Index<u8>` is not implemented
//~^ ERROR: the trait `core::ops::Index<u8>` is not implemented

[0][0]; // should infer to be a usize

8 changes: 0 additions & 8 deletions src/test/compile-fail/integral-indexing.rs
Original file line number Diff line number Diff line change
@@ -14,21 +14,13 @@ pub fn main() {
v[3_usize];
v[3];
v[3u8]; //~ERROR the trait `core::ops::Index<u8>` is not implemented
//~^ ERROR the trait `core::ops::Index<u8>` is not implemented
v[3i8]; //~ERROR the trait `core::ops::Index<i8>` is not implemented
//~^ ERROR the trait `core::ops::Index<i8>` is not implemented
v[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
//~^ ERROR the trait `core::ops::Index<u32>` is not implemented
v[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
//~^ ERROR the trait `core::ops::Index<i32>` is not implemented
s.as_bytes()[3_usize];
s.as_bytes()[3];
s.as_bytes()[3u8]; //~ERROR the trait `core::ops::Index<u8>` is not implemented
//~^ ERROR the trait `core::ops::Index<u8>` is not implemented
s.as_bytes()[3i8]; //~ERROR the trait `core::ops::Index<i8>` is not implemented
//~^ ERROR the trait `core::ops::Index<i8>` is not implemented
s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
//~^ ERROR the trait `core::ops::Index<u32>` is not implemented
s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
//~^ ERROR the trait `core::ops::Index<i32>` is not implemented
}
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-11771.rs
Original file line number Diff line number Diff line change
@@ -12,12 +12,10 @@ fn main() {
let x = ();
1 +
x //~^ ERROR E0277
//~| ERROR E0277
;

let x: () = ();
1 +
x //~^ ERROR E0277
//~| ERROR E0277
;
}
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-13352.rs
Original file line number Diff line number Diff line change
@@ -18,5 +18,4 @@ fn main() {
});
2_usize + (loop {});
//~^ ERROR E0277
//~| ERROR E0277
}
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-14084.rs
Original file line number Diff line number Diff line change
@@ -14,5 +14,4 @@
fn main() {
in () { 0 };
//~^ ERROR: the trait `core::ops::Placer<_>` is not implemented
//~| ERROR: the trait `core::ops::Placer<_>` is not implemented
}
3 changes: 0 additions & 3 deletions src/test/compile-fail/issue-20605.rs
Original file line number Diff line number Diff line change
@@ -11,9 +11,6 @@
fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
for item in *things { *item = 0 }
//~^ ERROR the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator
//~^^ ERROR
//~^^^ ERROR
// FIXME(#21528) error should be reported once, not thrice
}

fn main() {}
23 changes: 23 additions & 0 deletions src/test/compile-fail/issue-20692.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

trait Array: Sized {}

fn f<T: Array>(x: &T) {
let _ = x
//~^ ERROR `Array` cannot be made into an object
//~| NOTE the trait cannot require that `Self : Sized`
as
&Array;
//~^ ERROR `Array` cannot be made into an object
//~| NOTE the trait cannot require that `Self : Sized`
}

fn main() {}
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-2149.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ impl<A> vec_monad<A> for Vec<A> {
let mut r = panic!();
for elt in self { r = r + f(*elt); }
//~^ ERROR E0277
//~| ERROR E0277
}
}
fn main() {
4 changes: 1 addition & 3 deletions src/test/compile-fail/issue-22645.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,5 @@ impl<RHS: Scalar> Add <RHS> for Bob {
fn main() {
let b = Bob + 3.5;
b + 3 //~ ERROR: is not implemented
//~^ ERROR: is not implemented
//~^^ ERROR: is not implemented
//~^^^ ERROR: mismatched types
//~^ ERROR: mismatched types
}
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-24352.rs
Original file line number Diff line number Diff line change
@@ -11,5 +11,4 @@
fn main() {
1.0f64 - 1.0;
1.0f64 - 1 //~ ERROR: is not implemented
//~^ ERROR: is not implemented
}
35 changes: 35 additions & 0 deletions src/test/compile-fail/issue-28098.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
let _ = Iterator::next(&mut ());
//~^ ERROR the trait `core::iter::Iterator` is not implemented

for _ in false {}
//~^ ERROR the trait `core::iter::Iterator` is not implemented

let _ = Iterator::next(&mut ());
//~^ ERROR the trait `core::iter::Iterator` is not implemented

other()
}

pub fn other() {
// check errors are still reported globally

let _ = Iterator::next(&mut ());
//~^ ERROR the trait `core::iter::Iterator` is not implemented

let _ = Iterator::next(&mut ());
//~^ ERROR the trait `core::iter::Iterator` is not implemented

for _ in false {}
//~^ ERROR the trait `core::iter::Iterator` is not implemented
}
23 changes: 23 additions & 0 deletions src/test/compile-fail/issue-28568.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct MyStruct;

impl Drop for MyStruct {
//~^ ERROR conflicting implementations for trait
fn drop(&mut self) { }
}

impl Drop for MyStruct {
//~^ NOTE conflicting implementation here
fn drop(&mut self) { }
}

fn main() {}
3 changes: 0 additions & 3 deletions src/test/compile-fail/shift-various-bad-types.rs
Original file line number Diff line number Diff line change
@@ -18,15 +18,12 @@ struct Panolpy {
fn foo(p: &Panolpy) {
22 >> p.char;
//~^ ERROR E0277
//~| ERROR E0277

22 >> p.str;
//~^ ERROR E0277
//~| ERROR E0277

22 >> p;
//~^ ERROR E0277
//~| ERROR E0277

let x;
22 >> x; // ambiguity error winds up being suppressed
1 change: 0 additions & 1 deletion src/test/compile-fail/str-idx.rs
Original file line number Diff line number Diff line change
@@ -11,5 +11,4 @@
pub fn main() {
let s: &str = "hello";
let c: u8 = s[4]; //~ ERROR the trait `core::ops::Index<_>` is not implemented
//~^ ERROR the trait `core::ops::Index<_>` is not implemented
}
1 change: 0 additions & 1 deletion src/test/compile-fail/str-mut-idx.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ fn mutate(s: &mut str) {
s[1usize] = bot();
//~^ ERROR `core::ops::Index<usize>` is not implemented for the type `str`
//~| ERROR `core::ops::IndexMut<usize>` is not implemented for the type `str`
//~| ERROR `core::ops::Index<usize>` is not implemented for the type `str`
}

pub fn main() {}
1 change: 0 additions & 1 deletion src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@ fn b() {
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}

fn main() { }
1 change: 0 additions & 1 deletion src/test/compile-fail/unboxed-closures-wrong-abi.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@ fn b() {
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}

fn main() { }
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ fn b() {
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}

fn main() { }