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

No index for a field #50493

Closed
dtolnay opened this issue May 7, 2018 · 7 comments
Closed

No index for a field #50493

dtolnay opened this issue May 7, 2018 · 7 comments
Labels
P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@dtolnay
Copy link
Member

dtolnay commented May 7, 2018

This is a strange one to summarize. As best as I have been able to tell: the compiler ICEs with "no index for a field" if two derived functions each independently acknowledge the existence of a field that is not visible to them.

In any case, here is as far as I got minimizing this one:

#!/bin/sh

cargo new --lib repro
cargo new --lib repro_derive

echo >repro/src/lib.rs '
#[macro_use]
extern crate repro_derive;

#[derive(Derive)]
struct Restricted {
    pub(in restricted) field: usize,
}

mod restricted {}

fn main() {}
'

echo >>repro/Cargo.toml '
repro_derive = { path = "../repro_derive" }
'

echo >repro_derive/src/lib.rs '
extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro_derive(Derive)]
pub fn derive(_: TokenStream) -> TokenStream {
    let code = "
        fn one(r: Restricted) {
            r.field;
        }
        fn two(r: Restricted) {
            r.field;
        }
    ";
    
    code.parse().unwrap()
}
'

echo >>repro_derive/Cargo.toml '
[lib]
proc-macro = true
'

cargo build --manifest-path repro/Cargo.toml

Reasonable error message on stable and beta. But on nightly:

error: visibilities can only be restricted to ancestor modules
 --> src/lib.rs:7:12
  |
7 |     pub(in restricted) field: usize,
  |            ^^^^^^^^^^

error[E0616]: field `field` of struct `Restricted` is private
 --> src/lib.rs:5:10
  |
5 | #[derive(Derive)]
  |          ^^^^^^

thread 'main' panicked at 'no index for a field', libcore/option.rs:914:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0616`.

error: internal compiler error: unexpected panic

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

Mentioning @petrochenkov who added the panicking function in #49718.

@dtolnay dtolnay added the regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. label May 7, 2018
@pietroalbini pietroalbini added this to the 1.27 milestone May 7, 2018
@pietroalbini
Copy link
Member

Yep, a bisect points to #49718 as the cause. Also cc-ing the reviewer: @eddyb

@pietroalbini pietroalbini added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. labels May 8, 2018
@nikomatsakis
Copy link
Contributor

triage: P-high

@petrochenkov -- do you think you'll have time to investigate this?

@dtolnay dtolnay added the P-high High priority label May 10, 2018
@petrochenkov
Copy link
Contributor

Well, it's clear what happens - due to some earlier errors we do not resolve (to index) some field access so it ends up without entry in "resolution table" (TypeckTables::field_indices).
This probably needs a self.is_tainted_by_errors() check inserted somewhere before the tcx.field_index(...) causing the ICE.

(It would be nice if someone could post a backtrace, RUST_BACKTRACE=1 never worked on mingw and gdb breakpoints on panics in rustc also stopped working some time ago.)

@dtolnay
Copy link
Member Author

dtolnay commented May 10, 2018

$ rustc --version && RUST_BACKTRACE=1 ./repro.sh 
rustc 1.27.0-nightly (e5f80f2a4 2018-05-09)
     Created library `repro` project
     Created library `repro_derive` project
   Compiling repro_derive v0.1.0
   Compiling repro v0.1.0
error: visibilities can only be restricted to ancestor modules
 --> src/lib.rs:7:12
  |
7 |     pub(in restricted) field: usize,
  |            ^^^^^^^^^^

error[E0616]: field `field` of struct `Restricted` is private
 --> src/lib.rs:5:10
  |
5 | #[derive(Derive)]
  |          ^^^^^^

thread 'main' panicked at 'no index for a field', libcore/option.rs:914:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:467
   6: std::panicking::begin_panic_fmt
             at libstd/panicking.rs:350
   7: rust_begin_unwind
             at libstd/panicking.rs:328
   8: core::panicking::panic_fmt
             at libcore/panicking.rs:71
   9: core::option::expect_failed
             at libcore/option.rs:914
  10: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::field_index
  11: rustc::middle::mem_categorization::MemCategorizationContext::cat_expr_unadjusted
  12: rustc_typeck::check::regionck::RegionCtxt::constrain_adjustments
  13: <rustc_typeck::check::regionck::RegionCtxt<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
  14: rustc::hir::intravisit::walk_block
  15: <rustc_typeck::check::regionck::RegionCtxt<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
  16: rustc_typeck::check::regionck::RegionCtxt::visit_fn_body
  17: rustc_typeck::check::regionck::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::regionck_fn
  18: rustc::ty::context::tls::with_related_context
  19: rustc::infer::InferCtxtBuilder::enter
  20: rustc_typeck::check::typeck_tables_of
  21: rustc::ty::maps::<impl rustc::ty::maps::config::QueryConfig<'tcx> for rustc::ty::maps::queries::typeck_tables_of<'tcx>>::compute
  22: rustc::ty::context::tls::with_context
  23: rustc::dep_graph::graph::DepGraph::with_task_impl
  24: rustc::ty::context::tls::with_related_context
  25: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  26: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  27: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
  28: rustc::session::Session::track_errors
  29: rustc_typeck::check::typeck_item_bodies
  30: rustc::ty::context::tls::with_context
  31: rustc::dep_graph::graph::DepGraph::with_task_impl
  32: rustc::ty::context::tls::with_related_context
  33: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  34: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  35: rustc_typeck::check_crate
  36: rustc::ty::context::tls::enter_context
  37: <std::thread::local::LocalKey<T>>::with
  38: rustc::ty::context::TyCtxt::create_and_enter
  39: rustc_driver::driver::compile_input
  40: rustc_driver::run_compiler_impl
  41: <scoped_tls::ScopedKey<T>>::set
  42: syntax::with_globals
  43: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  44: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  45: rustc_driver::run
  46: rustc_driver::main
  47: std::rt::lang_start::{{closure}}
  48: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  49: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  50: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:374
             at libstd/rt.rs:58
  51: main
  52: __libc_start_main
  53: <unknown>
query stack during panic:
#0 [typeck_tables_of] processing `two`
#1 [typeck_item_bodies] type-checking all item bodies
end of query stack
error: aborting due to 2 previous errors

@dlrobertson
Copy link
Contributor

I took a quick look at this since I just worked on another ICE with TypeckTables::field_indices(#50618). Similar to the fix for #50618 I think a better fix would be to fix typeck by returning tcx.types.err here instead of field_ty, but someone with more experience may want to weigh in on that.

@vegard
Copy link

vegard commented May 14, 2018

I found this smaller input (which seems to be crashing in the same way) by fuzzing:

fn main() {
    |x: Vec<u8>| x.len;
}

I can open a new issue if you think it's a different bug.

@dlrobertson
Copy link
Contributor

@vegard I get the expected output when I use my local build for the linked PR. Thanks for the additional test case!

bors added a commit that referenced this issue May 14, 2018
typeck: Save the index of private fields

Save the index of all fields regardless of their visibility. Problems
could occur later when attempting to index fields in error recovery if
they are not inserted.

Fixes: #50493
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants