]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix bad generic substitution error on fn/adt types
authorPhilip Herron <herron.philip@googlemail.com>
Mon, 3 Feb 2025 15:25:50 +0000 (15:25 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 24 Mar 2025 12:07:01 +0000 (13:07 +0100)
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>
gcc/rust/typecheck/rust-substitution-mapper.cc
gcc/testsuite/rust/compile/issue-3382.rs [new file with mode: 0644]
gcc/testsuite/rust/compile/nr2/exclude

index dbf49bef5b764ad796b1fcbc35409e7c7e8b0e6a..1e15157718027ae615e6cf4ee4d22fdc2aa22e51 100644 (file)
@@ -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 (file)
index 0000000..6f4382f
--- /dev/null
@@ -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)
+    }
+}
index 29d6e21b7732bb5b92bd79b9abf267de9a55903b..8229b541bbc728eb7015cbd697178844c70009d4 100644 (file)
@@ -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