aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-02-03 15:25:50 +0000
committerPhilip Herron <philip.herron@embecosm.com>2025-02-03 20:35:58 +0000
commit68e24e2562e267f7ca42b6c7fc8b536b4a2459b3 (patch)
tree175431b1701cf631ad57e2a807fc904f762a1a08 /gcc
parent842c1cf95d6e731e72449b36539d85624fa77161 (diff)
downloadgcc-68e24e2562e267f7ca42b6c7fc8b536b4a2459b3.zip
gcc-68e24e2562e267f7ca42b6c7fc8b536b4a2459b3.tar.gz
gcc-68e24e2562e267f7ca42b6c7fc8b536b4a2459b3.tar.bz2
gccrs: Fix bad generic substitution error on fn/adt types
When passing generics around we try to adjust them because there are cases where the names are adjusted from other generics this can fail for traits because of the implicit Self and we just need to continue on without adjustment. Fxies Rust-GCC#3382 gcc/rust/ChangeLog: * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): continue on for trait item mode. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: nr2 cant handle this. * rust/compile/issue-3382.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc8
-rw-r--r--gcc/testsuite/rust/compile/issue-3382.rs61
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude1
3 files changed, 68 insertions, 2 deletions
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index 394dfe4..49c4505 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -192,8 +192,10 @@ SubstMapperInternal::visit (TyTy::FnType &type)
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
- if (adjusted.is_error ())
+ if (adjusted.is_error () && !mappings.trait_item_mode ())
return;
+ if (adjusted.is_error () && mappings.trait_item_mode ())
+ adjusted = mappings;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
@@ -205,8 +207,10 @@ SubstMapperInternal::visit (TyTy::ADTType &type)
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
- if (adjusted.is_error ())
+ if (adjusted.is_error () && !mappings.trait_item_mode ())
return;
+ if (adjusted.is_error () && mappings.trait_item_mode ())
+ adjusted = mappings;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
diff --git a/gcc/testsuite/rust/compile/issue-3382.rs b/gcc/testsuite/rust/compile/issue-3382.rs
new file mode 100644
index 0000000..6f4382f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3382.rs
@@ -0,0 +1,61 @@
+#[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)
+ }
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index 29d6e21..8229b54 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -123,4 +123,5 @@ issue-3030.rs
traits12.rs
try-trait.rs
derive-debug1.rs
+issue-3382.rs
# please don't delete the trailing newline