Rollup merge of #65738 - ohadravid:re-rebalance-coherence-allow-fundamental-local, r=nikomatsakis

Coherence should allow fundamental types to impl traits when they are local

After #64414, `impl<T> Remote for Box<T> { }` is disallowed, but it is also disallowed in liballoc, where `Box` is a local type!

Enabling `#![feature(re_rebalance_coherence)]` in `liballoc` results in:
```
error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct<F>`)
    --> src\liballoc\boxed.rs:1098:1
     |
1098 | impl<F: ?Sized + Future + Unpin> Future for Box<F> {
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `F` must be used as the type parameter for some local type
```

This PR relaxes `uncover_fundamental_ty` to skip local fundamental types.
I didn't add a test since `liballoc` already fails to compile, but I can add one if needed.

r? @nikomatsakis

cc #63599
This commit is contained in:
Mazdak Farrokhzad 2019-10-27 16:46:52 +01:00 committed by GitHub
commit 53568f3fb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 4 deletions

View file

@ -378,15 +378,21 @@ fn orphan_check_trait_ref<'tcx>(
// Let Ti be the first such type.
// - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
//
fn uncover_fundamental_ty(ty: Ty<'_>) -> Vec<Ty<'_>> {
if fundamental_ty(ty) {
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(ty)).collect()
fn uncover_fundamental_ty<'a>(
tcx: TyCtxt<'_>,
ty: Ty<'a>,
in_crate: InCrate,
) -> Vec<Ty<'a>> {
if fundamental_ty(ty) && !ty_is_local(tcx, ty, in_crate) {
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).collect()
} else {
vec![ty]
}
}
for input_ty in trait_ref.input_types().flat_map(uncover_fundamental_ty) {
for input_ty in
trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
{
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
if ty_is_local(tcx, input_ty, in_crate) {
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);

View file

@ -0,0 +1,16 @@
#![feature(fundamental)]
#![feature(re_rebalance_coherence)]
// compile-flags:--crate-name=test
// aux-build:coherence_lib.rs
// check-pass
extern crate coherence_lib as lib;
use lib::*;
#[fundamental]
struct Local;
impl Remote for Local {}
fn main() {}

View file

@ -0,0 +1,16 @@
#![feature(fundamental)]
#![feature(re_rebalance_coherence)]
// compile-flags:--crate-name=test
// aux-build:coherence_lib.rs
// check-pass
extern crate coherence_lib as lib;
use lib::*;
#[fundamental]
struct MyBox<T>(T);
impl<T> Remote for MyBox<T> {}
fn main() {}