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 resolve field substitution in generic impl of Try for Result<T, E> #3382

Open
1 task
CohenArthur opened this issue Jan 23, 2025 · 0 comments · May be fixed by #3394
Open
1 task

Failed to resolve field substitution in generic impl of Try for Result<T, E> #3382

CohenArthur opened this issue Jan 23, 2025 · 0 comments · May be fixed by #3394

Comments

@CohenArthur
Copy link
Member

CohenArthur commented Jan 23, 2025

Summary

We can't compile the actual implementation of Try for Result<T, E> in Rust 1.49

Reproducer

I tried this code:

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

enum Result<T, E> {
    #[lang = "Ok"]
    Ok(T),
    #[lang = "Err"]
    Err(E)
}

#[lang = "try"]
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.
    #[lang = "into_result"]
    #[unstable(feature = "try_trait", issue = "42327")]
    fn into_result(self) -> Result<Self::Ok, Self::Error>;

    /// Wrap an error value to construct the composite result. For example,
    /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
    #[lang = "from_error"]
    #[unstable(feature = "try_trait", issue = "42327")]
    fn from_error(v: Self::Ok) -> Self;

    /// Wrap an OK value to construct the composite result. For example,
    /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
    #[lang = "from_ok"]
    #[unstable(feature = "try_trait", issue = "42327")]
    fn from_ok(v: Self::Error) -> Self;
}

impl<T, E> Try for Result<T, E> {
    type Ok = T;
    type Error = E;

    fn into_result(self) -> Result<T, E> {
        self
    }

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

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

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

  • Nightly

Godbolt link

Actual behavior

We get the following error:

try-trait1.rs:57:12: error: Failed to resolve field substitution type: Result<T, E>{Ok (0:<placeholder:<Projection=<T, E>::T=T REF: 95>>), Err (0:<placeholder:<Projection=<T, E>::E=E REF: 96>>)}
   57 | impl<T, E> Try for Result<T, E> {
      |            ^~~
try-trait1.rs:61:5: error: mismatched types, expected ‘<tyty::error>’ but got ‘fn<T, E> (self Result<T, E>{Ok (0:T), Err (0:E)},) -> Result<T, E>{Ok (0:T), Err (0:E)}’ [E0308]
   42 |     fn into_result(self) -> Result<Self::Ok, Self::Error>;
      |     ~~
......
   61 |     fn into_result(self) -> Result<T, E> {
      |     ^~
try-trait1.rs:61:5: error: method ‘into_result’ has an incompatible type for trait ‘Try’ [E0053]
   42 |     fn into_result(self) -> Result<Self::Ok, Self::Error>;
      |     ~~
......
   61 |     fn into_result(self) -> Result<T, E> {
      |     ^~

Expected behavior

No error

GCC Version

latest master

philberty added a commit that referenced this issue Jan 29, 2025
When we pass generic types as the Self on traits they need to be handled
via a special case on fntypes, ADT's and placeholders as the type params
won't necessarily match up because of the implicit Self.

Fixes #3382

gcc/rust/ChangeLog:

	* typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): special case

gcc/testsuite/ChangeLog:

	* rust/compile/nr2/exclude: nr2 cant handle this
	* rust/compile/issue-3382.rs: New test.

Signed-off-by: Philip Herron <[email protected]>
@philberty philberty linked a pull request Jan 29, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

Successfully merging a pull request may close this issue.

2 participants