Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Computing <MyStruct as std::ptr::Pointee>::Metadata fails when trailing field has a projection #92577

Closed
Zalathar opened this issue Jan 5, 2022 · 7 comments · Fixed by #92248
Assignees
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Zalathar
Copy link
Contributor

Zalathar commented Jan 5, 2022

Code

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8e31db4a857f6bcdbf287b8d9745ca22

use std::collections::HashMap;

trait HasType {
    type Type;
}

impl HasType for () {
    type Type = ();
}

pub struct MyStruct {
    _field: <() as HasType>::Type,
}

pub fn do_insert(map: &mut HashMap<*const MyStruct, ()>, key: *const MyStruct) {
    map.insert(key, ());
}

Meta

(Build fails with an ICE on current stable/beta/nightly on the playground.)

Error output

   Compiling playground v0.0.1 (/playground)
thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', compiler/rustc_monomorphize/src/collector.rs:894:93
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.57.0 (f1edd0429 2021-11-29) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [collect_and_partition_mono_items] collect_and_partition_mono_items
#1 [exported_symbols] exported_symbols
end of query stack
error: could not compile `playground`
Backtrace

   Compiling playground v0.0.1 (/playground)
thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', compiler/rustc_monomorphize/src/collector.rs:894:93
stack backtrace:
   0: rust_begin_unwind
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/panicking.rs:100:14
   2: core::panicking::panic
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/panicking.rs:50:5
   3: <rustc_monomorphize::collector::MirNeighborCollector as rustc_middle::mir::visit::Visitor>::visit_terminator
   4: rustc_monomorphize::collector::collect_neighbours
   5: rustc_monomorphize::collector::collect_items_rec
   6: rustc_monomorphize::collector::collect_items_rec
   7: rustc_monomorphize::collector::collect_items_rec
   8: rustc_monomorphize::collector::collect_items_rec
   9: rustc_monomorphize::collector::collect_items_rec
  10: rustc_session::utils::<impl rustc_session::session::Session>::time
  11: rustc_monomorphize::collector::collect_crate_mono_items
  12: rustc_monomorphize::partitioning::collect_and_partition_mono_items
  13: rustc_query_system::query::plumbing::try_execute_query
  14: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::collect_and_partition_mono_items
  15: rustc_codegen_ssa::back::symbol_export::exported_symbols_provider_local
  16: rustc_query_system::query::plumbing::try_execute_query
  17: rustc_query_system::query::plumbing::get_query
  18: rustc_metadata::rmeta::encoder::EncodeContext::encode_crate_root
  19: rustc_metadata::rmeta::encoder::encode_metadata_impl
  20: rustc_data_structures::sync::join
  21: rustc_metadata::rmeta::encoder::encode_metadata
  22: rustc_interface::queries::Queries::ongoing_codegen
  23: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  24: rustc_span::with_source_map
  25: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.57.0 (f1edd0429 2021-11-29) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [collect_and_partition_mono_items] collect_and_partition_mono_items
#1 [exported_symbols] exported_symbols
end of query stack
error: could not compile `playground`

@Zalathar Zalathar added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 5, 2022
@Zalathar
Copy link
Contributor Author

Zalathar commented Jan 5, 2022

Same error message as #90738, though it's unclear whether that issue is related.

@Zalathar
Copy link
Contributor Author

Zalathar commented Jan 5, 2022

@Aaron1011 Aaron1011 self-assigned this Jan 5, 2022
@Aaron1011
Copy link
Member

Aaron1011 commented Jan 5, 2022

Minimized:

#![feature(ptr_metadata)]

trait HasType {
    type Type;
}

impl HasType for () {
    type Type = ();
}

pub struct MyStruct {
    _field: <() as HasType>::Type,
}

pub fn bar() {
    let val: <MyStruct as std::ptr::Pointee>::Metadata;
}

The Pointee trait gets used by the Hash impl for *const MyStruct, which leads to the bad monomorphization:

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Hash for *const T {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let (address, metadata) = self.to_raw_parts();
state.write_usize(address as usize);
metadata.hash(state);
}
}

The issue is caused by how we handle projections when computing the Metadata type. We don't normalize the 'tail' type:

// FIXME: should this normalize?
let tail = selcx.tcx().struct_tail_without_normalization(self_ty);

which causes us to not create a candidate for the projection type in the tail of MyField (which is <() as HasType>::Type):

ty::Projection(..)
| ty::Opaque(..)
| ty::Param(..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)
| ty::Error(_) => false,

cc @SimonSapin - we need to be normalizing somewhere, but I'm not exactly sure where the correct place is.

@SimonSapin
Copy link
Contributor

I’m sorry but I don’t think I can help much. I don’t even know what normalizing means precisely. As I mentioned in #81172

For this I mostly imitated what the compiler was already doing for the DiscriminantKind trait. I’m very unfamiliar with compiler internals

So the only hint I can offer is: does the code for DiscriminantKind do something differently? Or is there a reason it’s not affected by this problem?

@Aaron1011 Aaron1011 changed the title thread 'rustc' panicked at 'called Option::unwrap() on a None value', compiler/rustc_monomorphize/src/collector.rs:894:93 Computing <MyStruct as std::ptr::Pointee>::Metadata fails when trailing field has a projection Jan 5, 2022
@Aaron1011
Copy link
Member

cc @rust-lang/wg-traits - I'm not quite sure what the proper normalization behavior is. We need to be able to perform this projection during typecheck (e.g. let a: <MyType as Pointee>::Metadata = foo();), so I think we need to try to faillibly normalize the trailing field type here?

@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Jan 5, 2022
@jackh726
Copy link
Member

jackh726 commented Jan 5, 2022

Why are we not normalizing? Because we don't want to replace with an inference var?

@compiler-errors
Copy link
Member

compiler-errors commented Jan 6, 2022

@Aaron1011, so I put up a fix for this in #92248. Someone mind reviewing that PR? It's gone some time without being touched. My PR seems to successfully compile both examples linked in this issue.

we need to be normalizing somewhere, but I'm not exactly sure where the correct place is.

Is it really not sufficient to just normalize during selection? Are there any consequences of normalization failing here, other than giving us errors the regular ambiguity "type annotation needed" errors?

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 9, 2022
…pointee, r=jackh726

Normalize struct tail type when checking Pointee trait

Let's go ahead and implement the FIXMEs by properly normalizing the struct-tail type when satisfying a Pointee obligation. This should fix the ICE when we try to calculate a layout depending on `<Ty as Pointee>::Metadata` later.
Fixes rust-lang#92128
Fixes rust-lang#92577

Additionally, mark the obligation as ambiguous if there are any infer types in that struct-tail type. This has the effect of causing `<_ as Pointee>::Metadata` to be properly replaced with an infer variable ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/traits/project.rs#L813)) and registered as an obligation... this turns out to be very important in unifying function parameters with formals that are assoc types.

Fixes rust-lang#91446
@bors bors closed this as completed in 6466f89 Jan 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants