Change:
<ins> // Test to ensure that trait bounds are propertly // checked on specializable associated types #![allow(incomplete_features)] #![feature(specialization)] trait UncheckedCopy: Sized { type Output: From<Self> + Copy + Into<Self>; } impl<T> UncheckedCopy for T { default type Output = Self; //~^ ERROR: the trait bound `T: Copy` is not satisfied } fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T { (*other).into() } fn bug(origin: String) { // Turn the String into it's Output type... // Which we can just do by `.into()`, the assoc type states `From<Self>`. let origin_output = origin.into(); // Make a copy of String::Output, which is a String... let mut copy: String = unchecked_copy::<String>(&origin_output); // Turn the Output type into a String again, // Which we can just do by `.into()`, the assoc type states `Into<Self>`. let mut origin: String = origin_output.into(); // assert both Strings use the same buffer. assert_eq!(copy.as_ptr(), origin.as_ptr()); // Any use of the copy we made becomes invalid, drop(origin); // OH NO! UB UB UB UB! copy.push_str(" world!"); println!("{}", copy); } fn main() { bug(String::from("hello")); } </ins>

Discussion:
The following code creates a trait (creatively named ) that has an associated type (creatively named ). An default implementation of this trait is given for all types, with . Specializing the trait (for , for example) works, except that doing causes an ICE. () Expected behavior: I believe this code should compile just fine, with 's being equivalent to to 's . Actual behavior: ICE: T/ Rust version: Backtrace:
This looks related to (see in particular ).
Triage: This is no longer ICE with the latest nightly:

:
Triage: still an issue.
I just hit this, though the error is a bit different now: "resolving bounds after type-checking" rather than "fulfilling during trans". error: internal compiler error: Encountered errors resolving bounds after type-checking note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: run with for a backtrace thread 'rustc' panicked at 'Box<Any', stack backtrace: 1: 0x7f91a71b237a - std::sys::imp::backtrace::tracing::imp::write::h944c02ac40aee2d7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 2: 0x7f91a71c122f - std::panicking::defaulthook::{{closure}}::h6875a2976258b020 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 3: 0x7f91a71c0dcd - std::panicking::defaulthook::h88ffbc5922643264 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 4: 0x7f91a71c16d7 - std::panicking::rustpanicwithhook::ha5aed1dfc0e220e3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 5: 0x7f91a67fae4b - std::panicking::beginpanic::h264cdc75d51b518b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 6: 0x7f91a6817d93 - rustc::session::optspanbugfmt::{{closure}}::h4a9b70c3df8b4b3a at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/<panic macros:3 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 7: 0x7f91a6817bb6 - rustc::session::spanbugfmt::h0c5d2225aa96fe42 at

/buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 8: 0x7f91a688fc77 - rustctrans::common::fulfillobligation::{{closure}}::{{closure}}::hf13a4d09f7cbb18e at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 9: 0x7f91a688c0dc - rustctrans::common::fulfillobligation::h6bfd7b7f15728b60 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 10: 0x7f91a6887278 - rustctrans::collector::dostaticdispatch::h9456c98c4201c352 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 11: 0x7f91a68868aa -

<rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitoperand::h7428e8287ff72240 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 12: 0x7f91a6886fe6 - <rustctrans::collector::MirNeighborCollector<'a, 'tcxas rustc::mir::visit::Visitor<'tcx::visitterminatorkind::h8233aed64e4688ea at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 13: 0x7f91a6813387 - rustc::mir::visit::Visitor::visitmir::hc23b408d887d8c09 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 14: 0x7f91a688524c - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 15: 0x7f91a68858ff - rustctrans::collector::collectitemsrec::h9535e33b3068eb29 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 16: 0x7f91a686f200 - rustctrans::base::collectandpartitiontranslationitems::{{closure}}::h9f2b052ae16b5f0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at

/buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 17: 0x7f91a686b59f - rustctrans::base::collectandpartitiontranslationitems::h6a325f48a6efa8c7 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 18: 0x7f91a685ddca - rustctrans::base::transcrate::h6e0b0bf1b66798ce at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 19: 0x7f91a7571401 - rustcdriver::driver::phase4translatetollvm::h48ed91c172294403 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 20: 0x7f91a7541c36 - rustcdriver::driver::compileinput::{{closure}}::hf13172fc4e5a2f4d at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 21: 0x7f91a755f503 - rustcdriver::driver::phase3runanalysispasses::{{closure}}::h97a3a12d948df547 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 22: 0x7f91a7558833 - rustcdriver::driver::phase3runanalysispasses::hb0ad9de18d423e67 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at

/buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 23: 0x7f91a753fb77 - rustcdriver::driver::compileinput::h8e119234b60571d5 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 24: 0x7f91a7585cd8 - rustcdriver::runcompiler::hbdfc4f84e2e0f4b9 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 25: 0x7f91a74a1158 - std::panicking::try::docall::hf679f17bf3b43b0b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 26: 0x7f91a71cbc1a - _rustmaybecatchpanic at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 27: 0x7f91a74c31b8 - <F as alloc::boxed::FnBox<A::callbox::h506fb5d7b8891cd4 at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 28: 0x7f91a71c0094 - std::sys::imp::thread::Thread::new::threadstart::h8084b1107992ae5b at /buildslave/rust-buildbot/slave/nightly-dist-rustc- at

/buildslave/rust-buildbot/slave/nightly-dist-rustc- at /buildslave/rust-buildbot/slave/nightly-dist-rustc- 29: 0x7f919f3f5709 - start_thread 30: 0x7f91a6e7a82c - clone 31: 0x0 - <unknown
ping how is this unsound?
Given that has seen fit to tag this as a soundness bug I'm nominating it so that it can receive a priority assessment, though I'll second ubsan in asking for a demonstration of the unsoundness here.
In general, having trait bounds that are not checked can lead to unsoundness, since some part of the code will assume that they hold when in fact they do not (consider, e.g., what might happen if the bound were ).
I'm going to mark this as P-medium and tag it from the specialization issue (it is specific to specialization, right?)
triage: P-medium
The code in the OP compiles for me with the latest nightly Rust (1.29.0-nightly ( 2018-08-01)). However, the following still fails (and I assume it's the same issue; if not I can file a new issue): Backtrace:
So I think this is "fixed-by-chalk", but this is fixed-by-chalk in a way that breaks specialization (cc Let's have a more easy-to-understand version of the problem: The problem is the following: our impl needs to prove the where-clause, which in the environment is . holds by (by the impl we are checking), so we can prove that obligation by (which will be a ) that depends on the . Therefore, wfchecking is OK. Therefore, fun. why isn't this a problem every time we have a projection? Normally, rustc normalizes to the real associated type, and then it can't find the , so no problem. With specialization, rustc can't normalize the associated type, so it sees the bug. I can't have a proof for this working, but this seems reasonably likely to work.

way that might solve this in the rustc model would be to basically say that for any given trait ref, only the most specialized impl is supposed to be checking the wf requirement (for every trait-ref, there is always a most-specialized impl, so this is OK), and when checking wf, add the associated types for our own impl explicitly to our parameter environment (e.g., add - note no quantification over - to the param env in our example). That will make things normalize and work, and I'm not even sure is particularly ugly. I don't think it is less sound than , but then I don't quite know when is sound. what's going on with Chalk? Last time I saw it, the way we made implied bounds work was to move to the environment - in rustc terms, basically only allow it if we have proven the impl using . This solves the problem, because our impl was proven in a well-formed way, so a will ensure we make progress and there will be no cycles. The reason this does not work in specialization, is that we do want users to be able to prove things like , even while they might not know what is. For that, they need to have a keyed off a . I have no idea how to do this in the Chalk model. Was Chalk changed to do something else by now? Does this have a different interaction with specialization?
A PoC to show the unsoundness of this. It's a use-after free by 'copying' a String: Link to the playground:
This is fixed now: and needs a test