Skip to content

No index for a field #50493

Closed
Closed

Description

@dtolnay

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.

Activity

  1. added this to the 1.27 milestone on May 7, 2018
  2. emilyalbini commented on May 7, 2018

    @emilyalbini
    Member

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

  3. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    and removed on May 8, 2018
  4. nikomatsakis commented on May 10, 2018

    @nikomatsakis
    Contributor

    triage: P-high

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

  5. petrochenkov commented on May 10, 2018

    @petrochenkov
    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.)

  6. dtolnay commented on May 10, 2018

    @dtolnay
    MemberAuthor
    $ 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
  7. dlrobertson commented on May 12, 2018

    @dlrobertson
    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.

  8. vegard commented on May 14, 2018

    @vegard

    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.

  9. dlrobertson commented on May 14, 2018

    @dlrobertson
    Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions