Skip to content

Commit b4f5ddb

Browse files
committed
Make coherence more tolerant of error types.
Fixes #29857. Fixes #30589.
1 parent 64a8ffe commit b4f5ddb

File tree

8 files changed

+174
-1
lines changed

8 files changed

+174
-1
lines changed

src/librustc/middle/traits/coherence.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,11 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
330330
tt.principal_def_id().is_local()
331331
}
332332

333-
ty::TyClosure(..) |
334333
ty::TyError => {
334+
true
335+
}
336+
337+
ty::TyClosure(..) => {
335338
tcx.sess.bug(
336339
&format!("ty_is_local invoked on unexpected type: {:?}",
337340
ty))

src/librustc_typeck/coherence/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,23 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
149149
trait_ref,
150150
item.name);
151151

152+
// Skip impls where one of the self type is an error type.
153+
// This occurs with e.g. resolve failures (#30589).
154+
if trait_ref.references_error() {
155+
return;
156+
}
157+
152158
enforce_trait_manually_implementable(self.crate_context.tcx,
153159
item.span,
154160
trait_ref.def_id);
155161
self.add_trait_impl(trait_ref, impl_did);
156162
} else {
163+
// Skip inherent impls where the self type is an error
164+
// type. This occurs with e.g. resolve failures (#30589).
165+
if self_type.ty.references_error() {
166+
return;
167+
}
168+
157169
// Add the implementation to the mapping from implementation to base
158170
// type def ID, if there is a base type for this implementation and
159171
// the implementation does not have any associated traits.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
13+
// Here we expect a coherence conflict because, even though `i32` does
14+
// not implement `Iterator`, we cannot rely on that negative reasoning
15+
// due to the orphan rules. Therefore, `A::Item` may yet turn out to
16+
// be `i32`.
17+
18+
pub trait Foo<P> {}
19+
20+
pub trait Bar {
21+
type Output: 'static;
22+
}
23+
24+
impl Foo<i32> for i32 { } //~ ERROR E0119
25+
26+
impl<A:Iterator> Foo<A::Item> for A { }
27+
28+
fn main() {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::marker::PhantomData;
12+
13+
pub trait Foo<P> {}
14+
15+
pub trait Bar {
16+
type Output: 'static;
17+
}
18+
19+
impl Foo<i32> for i32 { } //~ ERROR E0119
20+
21+
impl<A:Bar> Foo<A::Output> for A { }
22+
23+
impl Bar for i32 {
24+
type Output = i32;
25+
}
26+
27+
fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
#![allow(dead_code)]
13+
14+
// Here we do not get a coherence conflict because `Baz: Iterator`
15+
// does not hold and (due to the orphan rules), we can rely on that.
16+
17+
pub trait Foo<P> {}
18+
19+
pub trait Bar {
20+
type Output: 'static;
21+
}
22+
23+
struct Baz;
24+
impl Foo<i32> for Baz { }
25+
26+
impl<A:Iterator> Foo<A::Item> for A { }
27+
28+
#[rustc_error]
29+
fn main() {} //~ ERROR compilation successful
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
13+
pub trait Foo<P> {}
14+
15+
pub trait Bar {
16+
type Output: 'static;
17+
}
18+
19+
impl Foo<i32> for i32 { }
20+
21+
impl<A:Bar> Foo<A::Output> for A { }
22+
23+
impl Bar for i32 {
24+
type Output = u32;
25+
}
26+
27+
#[rustc_error]
28+
fn main() {} //~ ERROR compilation successful

src/test/compile-fail/issue-29857.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::marker::PhantomData;
12+
13+
pub trait Foo<P> {}
14+
15+
impl <P, T: Foo<P>> Foo<P> for Option<T> {} //~ ERROR E0119
16+
17+
pub struct Qux<T> (PhantomData<*mut T>);
18+
19+
impl<T> Foo<*mut T> for Option<Qux<T>> {}
20+
21+
pub trait Bar {
22+
type Output: 'static;
23+
}
24+
25+
impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {}
26+
27+
fn main() {}

src/test/compile-fail/issue-30589.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::fmt;
12+
13+
impl fmt::Display for DecoderError { //~ ERROR E0412
14+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15+
write!(f, "Missing data: {}", self.0)
16+
}
17+
}
18+
fn main() {
19+
}

0 commit comments

Comments
 (0)