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

Output type of indexing op. wrongly inferred in custom libcore #96661

Closed
gheoan opened this issue May 3, 2022 · 1 comment
Closed

Output type of indexing op. wrongly inferred in custom libcore #96661

gheoan opened this issue May 3, 2022 · 1 comment
Labels
A-inference Area: Type inference A-lang-item Area: Language items C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Low priority requires-internal-features This issue requires the use of internal features. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gheoan
Copy link
Contributor

gheoan commented May 3, 2022

I tried this code:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=42c97cceb10fc5cb71915f95d28a2956

Click to show 100 lines of code
#![crate_type = "lib"] #![allow(dead_code)]

#![feature(no_core, lang_items, auto_traits)]
#![no_core]

impl<T> Index<i32> for [T] {
    type Output = T;

    fn index(&self, index: i32) -> &Self::Output {
        &self[index as usize]
    }
}

fn f() {
    struct Decimal { digits: [u8; 9] }
    let d = Decimal { digits: [0; 9] };

            /* use 0_i32 to fix */
    match d.digits[0] {
  /* or 5_u8 here */
        5 => {}
        _ => {}
    };
}

// The code below is a slimmed down version of
// https://github.com/rust-lang/rust/blob/ec8619dca239f57201a3ceb59e93149659c07b58/compiler/rustc_codegen_cranelift/example/mini_core.rs
// It can be replaced with the whole mini_core or with the full standard library
///////////////////////////////////////////

#[lang = "index"]
pub trait Index<Idx: ?Sized> {
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}

impl<T> Index<usize> for [T] {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

#[lang = "sized"]
pub trait Sized {}

#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {}

#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}

#[lang = "receiver"]
pub trait Receiver {}
impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}

#[lang = "copy"]
pub unsafe trait Copy {}
unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for u128 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for f32 {}
unsafe impl Copy for f64 {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
unsafe impl<T: ?Sized> Copy for *mut T {}

#[lang = "freeze"]
unsafe auto trait Freeze {}

#[lang = "panic_location"]
struct PanicLocation {
    file: &'static str,
    line: u32,
    column: u32,
}

I expected to see this happen: code compiles without errors.

Instead, this happened: the output type of the Index operation is incorrectly inferred as i32.

error[E0271]: type mismatch resolving `<[u8] as Index<i32>>::Output == i32`
  --> ./type-inference-bug.rs:19:11
   |
19 |     match d.digits[0] {
   |           ^^^^^^^^^^^ type mismatch resolving `<[u8] as Index<i32>>::Output == i32`
   |
note: expected this to be `u8`
  --> ./type-inference-bug.rs:7:19
   |
7  |     type Output = T;
   |                   ^

Affects both v1.56 and nightly.

rustc 1.62.0-nightly (082e4ca49 2022-04-26)
binary: rustc
commit-hash: 082e4ca49770ebc9cb0ee616f3726a67471be8cb
commit-date: 2022-04-26
host: x86_64-unknown-linux-gnu
release: 1.62.0-nightly
LLVM version: 14.0.1

@rustbot label A-inference T-compiler C-enhancement requires-nightly A-lang-item

@rustbot rustbot added A-inference Area: Type inference A-lang-item Area: Language items C-enhancement Category: An issue proposing an enhancement or a PR with one. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 3, 2022
@Noratrieb Noratrieb added requires-internal-features This issue requires the use of internal features. P-low Low priority labels Apr 5, 2023
@Noratrieb
Copy link
Member

the compiler assumes that the lang items are the way it thinks they are. you'd need to patch the compiler as well.
so I'm closing this as wontfix.
related: rust-lang/compiler-team#620

@Noratrieb Noratrieb closed this as not planned Won't fix, can't repro, duplicate, stale Aug 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-lang-item Area: Language items C-enhancement Category: An issue proposing an enhancement or a PR with one. P-low Low priority requires-internal-features This issue requires the use of internal features. requires-nightly This issue requires a nightly compiler in some way. 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

3 participants