Skip to content

Bad error message with Self in inner function #12796

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

Closed
tbu- opened this issue Mar 9, 2014 · 10 comments
Closed

Bad error message with Self in inner function #12796

tbu- opened this issue Mar 9, 2014 · 10 comments

Comments

@tbu-
Copy link
Contributor

tbu- commented Mar 9, 2014

Updated example

trait Trait {
    fn outer(self) {
        fn inner(_: Self) {
        }
    }
}

fn main() { }
error: missing `Self` type param in the substitution of `fn(Self)`

Original issue

I have no idea where this came from, so here's a stacktrace.

Starting program: /usr/bin/rustc datafile_raw.rs
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
warning: File "/usr/lib/libstdc++.so.6.0.19-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
[New Thread 0x7ffff1f78480 (LWP 4681)]
datafile_raw.rs:348:75: 348:81 error: mismatched types: expected `fn(<generic #1>, &&'a Self) -> <generic #2>` but found `fn(uint, &'a Self) -> DatafileItem<'a>` (expected &-ptr but found self)
datafile_raw.rs:348         MapIterator { data: self, iterator: range(0, self.num_items()), map_fn: map_fn }
                                                    ^~~~~~
datafile_raw.rs:348:3: 348:83 error: mismatched types: expected `DatafileItemIterator<'a,Self>` but found `MapIterator<<generic #1>,<generic #2>,&'a Self,std::iter::Range<uint>>` (expected struct DatafileItemIterator but found struct MapIterator)
datafile_raw.rs:348         MapIterator { data: self, iterator: range(0, self.num_items()), map_fn: map_fn }
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[Switching to Thread 0x7ffff1f78480 (LWP 4681)]

Breakpoint 1, std::rt::unwind::Unwinder::begin_unwind::rust_fail () at src/libstd/rt/global_heap.rs:71
71  pub unsafe fn exchange_malloc(size: uint) -> *u8 {
(gdb) bt
#0  std::rt::unwind::Unwinder::begin_unwind::rust_fail () at src/libstd/rt/global_heap.rs:71
#1  0x00007ffff775c961 in std::rt::unwind::Unwinder::begin_unwind (self=0x6066a8, cause=...) at src/libstd/rt/unwind.rs:220
#2  0x00007ffff76bfa29 in std::rt::unwind::begin_unwind_inner (msg=..., file=..., line=148) at src/libstd/rt/unwind.rs:538
#3  0x00007ffff371240e in rt::unwind::begin_unwind::h2c1d88c0eb2e464eqik::v0.10.pre () from /usr/lib/librustc-6ccece0c-0.10-pre.so
#4  0x00007ffff3964b1c in lookup_vtable (vcx=<optimized out>, location_info=<optimized out>, trait_ref=<optimized out>, is_early=<optimized out>)
    at src/librustc/middle/typeck/check/vtable.rs:272
#5  push_inherent_candidates_from_self (self=<optimized out>, restrict_to=..., rcvr_ty=...) at src/librustc/middle/typeck/check/method.rs:498
#6  rustc::middle::typeck::check::method::LookupContext<'a>::push_bound_candidates (self=<optimized out>, restrict_to=..., self_ty=...) at src/librustc/middle/typeck/check/method.rs:364
#7  0x00007ffff39625b7 in rustc::middle::typeck::check::method::lookup (fcx=0x7fffecc18a60, expr=<optimized out>, self_expr=<optimized out>, m_name=<optimized out>, deref_args=<optimized out>, 
    check_traits=<optimized out>, autoderef_receiver=<optimized out>, self_ty=..., supplied_tps=...) at src/librustc/middle/typeck/check/method.rs:164
#8  0x00007ffff39a11af in trans_if (fcx=<optimized out>, ast_ty=<optimized out>, expr=<optimized out>, method_name=..., method_name=..., method_name=..., bcx=<optimized out>, 
    if_id=<optimized out>, cond=<optimized out>, thn=<optimized out>, els=..., dest=...) at src/librustc/middle/typeck/check/mod.rs:1921
#9  rustc::middle::typeck::check::check_expr_with_unifier (fcx=0x7fffecc18a60, expr=0x7fffec25f8c0, expected=..., lvalue_pref=<optimized out>, unifier=<optimized out>)
    at src/librustc/middle/typeck/check/mod.rs:2976
#10 0x00007ffff397fae8 in rustc::middle::typeck::check::check_block_with_expected (fcx=0x7fffecc18a60, blk=0x7fffec25f980, expected=...) at src/librustc/middle/typeck/check/mod.rs:1411
#11 0x00007ffff397be11 in rustc::middle::typeck::check::check_fn (ccx=0x7fffec0848c0, body=0x7fffec25f980, fn_kind=Vanilla, inherited=0x7fffecba4c00, purity=<optimized out>, 
    fn_sig=<optimized out>, decl=<optimized out>, id=<optimized out>) at src/librustc/middle/typeck/check/mod.rs:490
#12 0x00007ffff397b6bb in rustc::middle::typeck::check::check_bare_fn (ccx=0x7fffec0848c0, decl=0x7fffec1100b0, body=0x7fffec25f980, id=2447, param_env=..., fty=...)
    at src/librustc/middle/typeck/check/mod.rs:330
#13 0x00007ffff39766da in rustc::middle::typeck::check::check_item (ccx=0x7fffec0848c0, it=<optimized out>) at src/librustc/middle/typeck/check/mod.rs:575
#14 0x00007ffff397a460 in visit::walk_decl::h9cf355b08c4aabd1K1n::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:311
#15 0x00007ffff397a37e in visit::walk_stmt::h5901a3f261b3e26dy0n::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:312
#16 0x00007ffff397a113 in visit::walk_block::h45c060989eb1a99ftWn::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:312
#17 0x00007ffff397abbf in visit::walk_fn::he7254c7311eedc6e1ao::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:312
#18 0x00007ffff397b238 in visit::walk_method_helper::he88096d2d7de079fQfq::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:312
#19 0x00007ffff3978625 in visit::walk_item::h0447c6568c46391bN1p::v0.10.pre () at src/librustc/middle/typeck/check/mod.rs:312
#20 0x00007ffff397b4b4 in rustc::middle::typeck::check::check_item_types (ccx=0x7fffec0848c0, krate=<optimized out>) at src/librustc/middle/typeck/check/mod.rs:311
#21 0x00007ffff3a695fc in rustc::util::common::time<(),()> (what=..., do_it=<optimized out>, u=<optimized out>, f=<optimized out>) at src/librustc/util/common.rs:25
#22 0x00007ffff3a684b7 in rustc::middle::typeck::check_crate (tcx=0x7fffec2b1b90, krate=0x7ffff1f763c0, trait_map=...) at src/librustc/middle/typeck/mod.rs:463
#23 0x00007ffff3da21fa in rustc::driver::driver::phase_3_run_analysis_passes (sess=0x7fffec00ad00, krate=0x7ffff1f763c0, ast_map=...) at src/librustc/driver/driver.rs:316
#24 0x00007ffff3daa32f in rustc::driver::driver::compile_input (sess=0x7fffec00ad00, cfg=..., input=<optimized out>, outdir=<optimized out>, output=<optimized out>)
    at src/librustc/driver/driver.rs:573
#25 0x00007ffff3dcefe5 in rustc::run_compiler (args=...) at src/librustc/lib.rs:339
#26 0x00007ffff3ddef5d in fn91262 () at src/librustc/lib.rs:426
#27 0x00007ffff3ddd622 in fn91110 () at src/librustc/lib.rs:388
#28 0x00007ffff3dd958b in task::TaskBuilder::try::closure () at src/librustc/lib.rs:374
#29 0x00007ffff319517c in fn7303 () at src/libnative/task.rs:103
#30 0x00007ffff7756588 in fn42893 () at src/libstd/unstable/finally.rs:45
#31 try_finally<(),(),()> (mutate=<optimized out>, drop=<optimized out>, try_fn=<optimized out>, finally_fn=<optimized out>) at src/libstd/unstable/finally.rs:99
#32 finally (self=0xf000007ffff55187, dtor=<optimized out>) at src/libstd/unstable/finally.rs:44
#33 fn42888 () at src/libstd/rt/task.rs:128
#34 0x00007ffff776031c in rust_try () from /usr/lib/libstd-31b43f22-0.10-pre.so
#35 0x00007ffff77564f1 in std::rt::task::Task::run (self=<optimized out>, f={void (void)} 0x7ffff1f77b98) at src/libstd/rt/local.rs:30
#36 0x00007ffff3195003 in fn7279 () at src/libnative/task.rs:103
#37 0x00007ffff7759d24 in rt::thread::thread_start::h9d943e1fec71bd92kSc::v0.10.pre () at src/libstd/rt/thread.rs:48
#38 0x00007ffff26a30a2 in start_thread () from /usr/lib/libpthread.so.0
#39 0x00007ffff2ea2d1d in clone () from /usr/lib/libc.so.6
@alexcrichton
Copy link
Member

Can you provide the code that triggers the assertion as well? Ideally minimized as well, but we can attempt to do that as well.

@tbu-
Copy link
Contributor Author

tbu- commented Mar 10, 2014

Here's a minimized (probably not minimal) non-working example:

use std::iter;

struct Struct {
    data: i32,
}

struct MapIterator<T,U,D,I> {
    data: D,
    iterator: I,
    // `map` is already an function of an iterator, so we can't use `map` as a name here
    map_fn: fn (T, &D) -> U,
}

impl<T,U,D,I:Iterator<T>> Iterator<U> for MapIterator<T,U,D,I> {
    fn next(&mut self) -> Option<U> {
        self.iterator.next().map(|x| (self.map_fn)(x, &self.data))
    }
}

trait Trait {
    fn item(&self, index: uint) -> Struct;
    fn num_items(&self) -> uint;

    fn items<'a>(&'a self) -> MapIterator<uint,Struct,&'a Self,iter::Range<uint>> {
        fn map_fn<'a>(index: uint, df: & &'a Self) -> Struct {
            df.item(index)
        }
        MapIterator { data: self, iterator: range(0, self.num_items()), map_fn: map_fn }
    }
}

fn main() { }

@tbu-
Copy link
Contributor Author

tbu- commented Mar 10, 2014

I'll check whether I can reduce it furtherly.

@tbu-
Copy link
Contributor Author

tbu- commented Mar 10, 2014

use std::iter;

struct MapIterator<T,U,D,I> {
    data: D,
    iterator: I,
    // `map` is already an function of an iterator, so we can't use `map` as a name here
    map_fn: fn (T, &D) -> U,
}

impl<T,U,D,I:Iterator<T>> Iterator<U> for MapIterator<T,U,D,I> {
    fn next(&mut self) -> Option<U> {
        self.iterator.next().map(|x| (self.map_fn)(x, &self.data))
    }
}

trait Trait {
    fn items<'a>(&'a self) -> MapIterator<uint,i32,&'a Self,iter::Range<uint>> {
        fn map_fn<'a>(index: uint, df: & &'a Self) -> i32 {
            0
        }
        MapIterator { data: self, iterator: range(0u, 1), map_fn: map_fn }
    }
}

fn main() { }

When I changed the third type of MapIterator to (), the ICE stopped to appear.

@alexcrichton
Copy link
Member

Updating title to ICE message.

@tbu-
Copy link
Contributor Author

tbu- commented Mar 10, 2014

Now it's even shorter:

trait Trait {
    fn outer(self) {
        fn inner(_: Self) {
        }
    }
}

fn main() { }

@lilyball
Copy link
Contributor

I just hit this. Oddly, in my original code, the ICE was actually "Option.unwrap() called on None", but it appears to be the same issue.

@alexcrichton alexcrichton changed the title ICE: unimplemented type_of: ty_self Bad error message with Self in inner function May 21, 2014
@alexcrichton
Copy link
Member

Updating, this is no longer an ICE but rather just a pretty bad error message.

@bombless
Copy link
Contributor

bombless commented May 1, 2015

error: use of undeclared type name `Self`

The example code still give bad error message above, but the problem is actually a different one today.

@bombless
Copy link
Contributor

bombless commented May 1, 2015

BTW, no need to reopen this issue, #24968 already cover the new problem.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
chore: change str_ref_to_string to str_ref_to_owned

`ToString` is implemented by many different types than `&str`, and represents a serialization into string data. The fact that said data is returned as owned, is an implementation detail resulting from the lack of a parameter for a pre-allocated buffer.

If merely copying borrowed string data to owned string data is all that is desired, `ToOwned` is a much better choice, because if the user later refactors the code such that the input is no longer an `&str`, then they will get a compiler error instead of a mysterious runtime-behavioral change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants