-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gccrs: Fix compilation of trait-items which map to impl items
When we have paths such as Try::from_error the Try references the Trait and then from_error references the from_error trait item. So this resolves directly to a trait implementation which has the type: fn <Self> (v: placeholder) -> Self Remember that a path such as: Try::from_error gets handled by doing a clever substitution: <T? as Try>::from_error The main piece here is that we resolve this function type and for monomoprhization we know this is a trait call but we know that all trait's have an implicit Self type param which in this case is Result<i32, i32> so when it comes to knowing which impl block this is we got rid of the old bad insert/lookup receiver hack and use the specified type to know which impl block we are talking about to generate the function. The hard part here is inside rust-compil-item.cc, where we have the 'concete' type which is the trait item fntype of: fn <Result<i32, i32>> (v : i32) -> Result<i32,i32> This does not really match the signiture of the impl item for Result which is: fn <T, E> (v: i32) -> Result<T, E> So what we need to do is actually infer this by inputing inference variables on the impl fntype then unify'ing the trait object to this to compute the types of this to monomorphize this. Fixes #3381 gcc/rust/ChangeLog: * backend/rust-compile-expr.cc (CompileExpr::visit): remove receiver interface * backend/rust-compile-item.cc (CompileItem::visit): monomorphize trait to impl item * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): use trait item Self * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): remove receiver interface (TypeCheckExpr::resolve_fn_trait_call): likewise * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): likewise (TypeCheckExpr::resolve_segments): likewise * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise * typecheck/rust-hir-type-check.h: likewise * typecheck/rust-typecheck-context.cc (TypeCheckContext::insert_receiver): remove (TypeCheckContext::lookup_receiver): remove gcc/testsuite/ChangeLog: * rust/execute/torture/issue-3381.rs: New test. Signed-off-by: Philip Herron <[email protected]>
- Loading branch information
Showing
9 changed files
with
129 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* { dg-output "Err: 15\r*\n" } */ | ||
#[lang = "sized"] | ||
trait Sized {} | ||
|
||
enum Result<T, E> { | ||
#[lang = "Ok"] | ||
Ok(T), | ||
#[lang = "Err"] | ||
Err(E), | ||
} | ||
|
||
#[lang = "try"] | ||
pub trait Try { | ||
type Ok; | ||
type Error; | ||
|
||
#[lang = "into_result"] | ||
#[unstable(feature = "try_trait", issue = "42327")] | ||
fn into_result(self) -> Result<Self::Ok, Self::Error>; | ||
|
||
#[lang = "from_error"] | ||
#[unstable(feature = "try_trait", issue = "42327")] | ||
fn from_error(v: Self::Ok) -> Self; | ||
|
||
#[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) | ||
} | ||
} | ||
|
||
pub trait From<T>: Sized { | ||
fn from(_: T) -> Self; | ||
} | ||
|
||
impl<T> From<T> for T { | ||
fn from(t: T) -> Self { | ||
t | ||
} | ||
} | ||
|
||
fn print(s: &str, value: i32) { | ||
extern "C" { | ||
fn printf(s: *const i8, ...); | ||
} | ||
|
||
unsafe { | ||
printf(s as *const str as *const i8, value); | ||
} | ||
} | ||
|
||
fn baz() -> Result<i32, i32> { | ||
Result::Err(15) | ||
} | ||
|
||
fn foo() -> Result<i32, i32> { | ||
let b = match baz() { | ||
Result::Ok(value) => value, | ||
Result::Err(err) => { | ||
return Try::from_error(From::from(err)); | ||
} | ||
}; | ||
|
||
Result::Ok(15 + b) | ||
} | ||
|
||
fn main() -> i32 { | ||
let a = foo(); | ||
match a { | ||
Result::Ok(value) => print("Ok: %i\n", value), | ||
Result::Err(err) => print("Err: %i\n", err), | ||
}; | ||
|
||
0 | ||
} |