Make coherence more tolerant of error types.

Fixes #29857.
Fixes #30589.
This commit is contained in:
Niko Matsakis 2016-01-02 04:57:55 -05:00
parent 64a8ffeffa
commit b4f5ddba67
8 changed files with 174 additions and 1 deletions

View File

@ -330,8 +330,11 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
tt.principal_def_id().is_local()
}
ty::TyClosure(..) |
ty::TyError => {
true
}
ty::TyClosure(..) => {
tcx.sess.bug(
&format!("ty_is_local invoked on unexpected type: {:?}",
ty))

View File

@ -149,11 +149,23 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
trait_ref,
item.name);
// Skip impls where one of the self type is an error type.
// This occurs with e.g. resolve failures (#30589).
if trait_ref.references_error() {
return;
}
enforce_trait_manually_implementable(self.crate_context.tcx,
item.span,
trait_ref.def_id);
self.add_trait_impl(trait_ref, impl_did);
} else {
// Skip inherent impls where the self type is an error
// type. This occurs with e.g. resolve failures (#30589).
if self_type.ty.references_error() {
return;
}
// Add the implementation to the mapping from implementation to base
// type def ID, if there is a base type for this implementation and
// the implementation does not have any associated traits.

View File

@ -0,0 +1,28 @@
// 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 <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.
#![feature(rustc_attrs)]
// Here we expect a coherence conflict because, even though `i32` does
// not implement `Iterator`, we cannot rely on that negative reasoning
// due to the orphan rules. Therefore, `A::Item` may yet turn out to
// be `i32`.
pub trait Foo<P> {}
pub trait Bar {
type Output: 'static;
}
impl Foo<i32> for i32 { } //~ ERROR E0119
impl<A:Iterator> Foo<A::Item> for A { }
fn main() {}

View File

@ -0,0 +1,27 @@
// 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 <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.
use std::marker::PhantomData;
pub trait Foo<P> {}
pub trait Bar {
type Output: 'static;
}
impl Foo<i32> for i32 { } //~ ERROR E0119
impl<A:Bar> Foo<A::Output> for A { }
impl Bar for i32 {
type Output = i32;
}
fn main() {}

View File

@ -0,0 +1,29 @@
// 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 <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.
#![feature(rustc_attrs)]
#![allow(dead_code)]
// Here we do not get a coherence conflict because `Baz: Iterator`
// does not hold and (due to the orphan rules), we can rely on that.
pub trait Foo<P> {}
pub trait Bar {
type Output: 'static;
}
struct Baz;
impl Foo<i32> for Baz { }
impl<A:Iterator> Foo<A::Item> for A { }
#[rustc_error]
fn main() {} //~ ERROR compilation successful

View File

@ -0,0 +1,28 @@
// 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 <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.
#![feature(rustc_attrs)]
pub trait Foo<P> {}
pub trait Bar {
type Output: 'static;
}
impl Foo<i32> for i32 { }
impl<A:Bar> Foo<A::Output> for A { }
impl Bar for i32 {
type Output = u32;
}
#[rustc_error]
fn main() {} //~ ERROR compilation successful

View File

@ -0,0 +1,27 @@
// 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 <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.
use std::marker::PhantomData;
pub trait Foo<P> {}
impl <P, T: Foo<P>> Foo<P> for Option<T> {} //~ ERROR E0119
pub struct Qux<T> (PhantomData<*mut T>);
impl<T> Foo<*mut T> for Option<Qux<T>> {}
pub trait Bar {
type Output: 'static;
}
impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {}
fn main() {}

View File

@ -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 <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.
use std::fmt;
impl fmt::Display for DecoderError { //~ ERROR E0412
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Missing data: {}", self.0)
}
}
fn main() {
}