diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index 51ce8277b427..ce8e7595c6d7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc @@ -724,6 +724,14 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block, } TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ()); + if (self->is ()) + { + // we cannot check for unconstrained type arguments when the Self type is + // not resolved it will just add extra errors that dont help as well as + // the case where this could just be a recursive type query that should + // fail and will work later on anyway + return {substitutions, region_constraints}; + } // inherit the bounds if (!specified_bound.is_error ()) diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index f2e0405966df..f3aee8a97210 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -426,11 +426,8 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset, if (!query_type (ref, &lookup)) { if (is_root) - { - rust_error_at (seg->get_locus (), - "failed to resolve root segment"); - return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); - } + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + return root_tyty; } diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc index 48dcd95e181a..83d0e355f35d 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.cc +++ b/gcc/rust/typecheck/rust-tyty-subst.cc @@ -634,8 +634,6 @@ SubstitutionRef::get_mappings_from_generic_args ( if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR) { - rust_error_at (binding.get_locus (), - "failed to resolve type arguments"); return SubstitutionArgumentMappings::error (); } @@ -701,7 +699,6 @@ SubstitutionRef::get_mappings_from_generic_args ( BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ()); if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR) { - rust_error_at (args.get_locus (), "failed to resolve type arguments"); return SubstitutionArgumentMappings::error (); } diff --git a/gcc/testsuite/rust/compile/issue-2905-1.rs b/gcc/testsuite/rust/compile/issue-2905-1.rs new file mode 100644 index 000000000000..9b0c19da9bb5 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2905-1.rs @@ -0,0 +1,27 @@ +#![feature(lang_items)] + +#[lang = "sized"] +trait Sized {} + +pub struct A(T); + +pub trait B { + type C; +} + +// ------ +// swap these two items + +impl B for i32 { + type C = Weird; +} + +pub struct Weird(A<(T,)>); + +// ------ + +trait Foo {} + +impl Foo for Weird {} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-2905-2.rs b/gcc/testsuite/rust/compile/issue-2905-2.rs new file mode 100644 index 000000000000..83c54ed92e5f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2905-2.rs @@ -0,0 +1,136 @@ +// { dg-options "-w" } +#![feature(intrinsics)] +#![feature(lang_items)] + +#[lang = "sized"] +trait Sized {} + +extern "rust-intrinsic" { + fn transmute(_: T) -> U; + fn offset(src: *const T, offset: isize) -> *const T; +} + +pub mod core { + pub mod marker { + #[lang = "phantom_data"] + pub struct PhantomData; + } + + pub mod slice { + use core::marker::PhantomData; + use core::option::Option; + + impl core::iter::IntoIterator for &[T] { + type Item = &T; + type IntoIter = Weird; + + fn into_iter(self) -> Weird { + self.iter() + } + } + + pub struct Weird { + ptr: *const T, // should be NonNull but here it does not matter + end: *const T, + _marker: PhantomData<&T>, + } + + impl Weird { + pub(super) fn new(slice: &[T]) -> Self { + let ptr = slice.as_ptr(); + // SAFETY: Similar to `IterMut::new`. + unsafe { + // should be: ptr.add(slice.len()) + let end = transmute::<*const T, usize>(ptr) + slice.len(); // TODO(Arthur): Missing `* size_of::()`? + let end = transmute::(end); + + Self { + ptr, + end, + _marker: PhantomData, + } + } + } + + fn is_empty(&self) -> bool { + self.ptr == self.end + } + + fn next_unchecked(&mut self) -> *const T { + let old = self.ptr; + + self.ptr = unsafe { offset(self.ptr, 1) }; + + old + } + } + + trait Foo {} + + impl Foo for Weird {} + + // impl core::iter::Iterator for Iter { + // type Item = &T; + + // fn next(&mut self) -> Option<&T> { + // if self.is_empty() { + // Option::None + // } else { + // Option::Some(&*self.next_unchecked()) + // } + // } + // } + + union Repr { + pub(crate) rust: *const [T], + rust_mut: *mut [T], + pub(crate) raw: FatPtr, + } + + struct FatPtr { + data: *const T, + pub(crate) len: usize, + } + + impl [T] { + pub fn iter(&self) -> Weird { + Weird::new(self) + } + + pub fn as_ptr(&self) -> *const T { + self as *const [T] as *const T + } + + pub fn len(&self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + } + } + + pub mod iter { + use option::Option; + + pub trait IntoIterator { + type Item; + + type IntoIter: Iterator; + + fn into_iter(self) -> Self::IntoIter; + } + + pub trait Iterator { + type Item; + + fn next(&mut self) -> Option; + } + } + + pub mod option { + pub enum Option { + Some(T), + None, + } + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index efee0fd1e2dd..a73b1f027b1d 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -217,4 +217,6 @@ issue-2323.rs issue-2953-1.rs issue-2953-2.rs issue-1773.rs +issue-2905-1.rs +issue-2905-2.rs # please don't delete the trailing newline