Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ bidirectional_lang_item_map! {
// tidy-alphabetical-start
DynMetadata,
Option,
OwnedBox,
Poll,
// tidy-alphabetical-end
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_next_trait_solver/src/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ops::ControlFlow;

use derive_where::derive_where;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::SolverAdtLangItem;
use rustc_type_ir::{
self as ty, InferCtxtLike, Interner, Region, TrivialTypeTraversalImpls, TypeVisitable,
TypeVisitableExt, TypeVisitor,
Expand Down Expand Up @@ -407,12 +408,17 @@ where
}

// For fundamental types, we just look inside of them.
// Certain lang items (currently, `Box`) have special behaviour here
// and so are special cased.
ty::Ref(_, ty, _) => ty.visit_with(self),
ty::Adt(def, args) => {
if self.def_id_is_local(def.def_id()) {
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
} else if def.is_fundamental() {
args.visit_with(self)
match self.infcx.cx().as_adt_lang_item(def.def_id()) {
Some(SolverAdtLangItem::OwnedBox) => args.type_at(0).visit_with(self),
Some(..) | None => args.visit_with(self)
}
} else {
self.found_non_local_ty(ty)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum SolverAdtLangItem {
// tidy-alphabetical-start
DynMetadata,
Option,
OwnedBox,
Poll,
// tidy-alphabetical-end
}
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/coherence/impl-foreign-for-box[foreign_local].rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//@ compile-flags:--crate-name=test
//@ aux-build:coherence_lib.rs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test should likely be named for box, and there should be a comment.

// Ensure that `Box` in particular isn't fundamental over
// the allocator parameter (but is over T).

#![feature(allocator_api)]

extern crate coherence_lib as lib;

use lib::*;
use std::alloc::{Allocator, AllocError, Layout};
use std::ptr::NonNull;

struct Local;

unsafe impl Allocator for Local {
fn allocate(&self, _layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
Err(AllocError)
}
unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {}
}

impl Remote for Box<str, Local> {}
//~^ ERROR: only traits defined in the current crate can be implemented for types defined outside of the crate [E0117]

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/coherence/impl-foreign-for-box[foreign_local].stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> $DIR/impl-foreign-for-box[foreign_local].rs:24:1
|
LL | impl Remote for Box<str, Local> {}
| ^^^^^^^^^^^^^^^^---------------
| |
| `str` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
= note: define and implement a trait or new type instead

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0117`.
14 changes: 6 additions & 8 deletions tests/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ error[E0117]: only traits defined in the current crate can be implemented for ty
--> $DIR/impl-foreign-for-fundamental[foreign].rs:10:1
|
LL | impl Remote for Box<i32> {
| ^^^^^------^^^^^--------
| | |
| | `i32` is not defined in the current crate
| `std::alloc::Global` is not defined in the current crate
| ^^^^^^^^^^^^^^^^--------
| |
| `i32` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
Expand All @@ -15,10 +14,9 @@ error[E0117]: only traits defined in the current crate can be implemented for ty
--> $DIR/impl-foreign-for-fundamental[foreign].rs:14:1
|
LL | impl<T> Remote for Box<Rc<T>> {
| ^^^^^^^^------^^^^^----------
| | |
| | `Rc` is not defined in the current crate
| `std::alloc::Global` is not defined in the current crate
| ^^^^^^^^^^^^^^^^^^^----------
| |
| `Rc` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ LL | impl Remote1<Box<String>> for i32 {
| | |
| | `i32` is not defined in the current crate
| `String` is not defined in the current crate
| `std::alloc::Global` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
Expand All @@ -20,7 +19,6 @@ LL | impl Remote1<Box<Rc<i32>>> for f64 {
| | |
| | `f64` is not defined in the current crate
| `Rc` is not defined in the current crate
| `std::alloc::Global` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
Expand All @@ -34,7 +32,6 @@ LL | impl<T> Remote1<Box<Rc<T>>> for f32 {
| | |
| | `f32` is not defined in the current crate
| `Rc` is not defined in the current crate
| `std::alloc::Global` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
Expand Down
Loading