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

Failed to find candidates after PathProbeImplTrait #3381

Open
1 task
CohenArthur opened this issue Jan 23, 2025 · 1 comment
Open
1 task

Failed to find candidates after PathProbeImplTrait #3381

CohenArthur opened this issue Jan 23, 2025 · 1 comment
Assignees

Comments

@CohenArthur
Copy link
Member

Summary

We get zero candidates after a probing for a trait function call

Reproducer

I tried this code:

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

enum Result {
    Ok(i32),
    Err(i32)
}

pub trait From<T>: Sized {
    /// Performs the conversion.
    fn from(_: T) -> Self;
}

impl<T> From<T> for T {
    fn from(t: T) -> Self { t }
}

pub trait Try {
    /// The type of this value when viewed as successful.
    // #[unstable(feature = "try_trait", issue = "42327")]
    // type Ok;
    /// The type of this value when viewed as failed.
    // #[unstable(feature = "try_trait", issue = "42327")]
    // type Error;

    /// Applies the "?" operator. A return of `Ok(t)` means that the
    /// execution should continue normally, and the result of `?` is the
    /// value `t`. A return of `Err(e)` means that execution should branch
    /// to the innermost enclosing `catch`, or return from the function.
    ///
    /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
    /// in the return type of the enclosing scope (which must itself implement
    /// `Try`). Specifically, the value `X::from_error(From::from(e))`
    /// is returned, where `X` is the return type of the enclosing function.
    fn into_result(self) -> Result;

    /// Wrap an error value to construct the composite result. For example,
    /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
    fn from_error(v: i32) -> Self;

    /// Wrap an OK value to construct the composite result. For example,
    /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
    fn from_ok(v: i32) -> Self;
}

impl Try for Result {
    // type Ok = i32;
    // type Error = i32;

    fn into_result(self) -> Result {
        self
    }

    fn from_ok(v: i32) -> Self {
        Result::Ok(v)
    }

    fn from_error(v: i32) -> Self {
        Result::Err(v)
    }
}

fn print(s: &str, value: i32) {
    extern "C" { fn printf(s: *const i8, ...); }

    unsafe { printf(s as *const str as *const i8, value); }
}

fn bar() -> Result {
    Result::Ok(15)
}

fn baz() -> Result {
    Result::Err(15)
}

fn foo() -> Result {
    let b = match baz() {
        Result::Ok(value) => value,
        Result::Err(err) => { return Try::from_error(From::from(err)); },
    };

    Result::Ok(15 + b)
}

fn main() {
    foo();
}

Does the code make use of any (1.49) nightly feature ?

  • Nightly

Godbolt link

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

Actual behavior

The following assertion is triggered:

	  auto candidates
	    = Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
						   trait_ref);
	  if (candidates.size () == 0)
	    {
	      // this means we are defaulting back to the trait_item if
	      // possible
	      Resolver::TraitItemReference *trait_item_ref = nullptr;
	      bool ok = trait_ref->lookup_hir_trait_item (*trait_item.value (),
							  &trait_item_ref);
	      rust_assert (ok);				    // found
	      rust_assert (trait_item_ref->is_optional ()); // has definition

              // ^ HERE

so since we didn't find any candidates, we assume that there must be a default implementation for the function in the trait definition itself - but we should actually typecheck this to the definition of from_error in the impl of Try by Result.

This doesn't cause any issues with rustc

Expected behavior

No error

GCC Version

latest master

@CohenArthur
Copy link
Member Author

Note that using the expected type works as expected:

<Result as Try>::from_error(From::from(err))

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

2 participants