diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index e60f5ca9b85d..e4913e6608df 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -831,8 +831,6 @@ DefaultASTVisitor::visit (AST::Function &function) visit (function.get_qualifiers ()); for (auto &generic : function.get_generic_params ()) visit (generic); - if (function.has_self_param ()) - visit (function.get_self_param ()); for (auto ¶m : function.get_function_params ()) visit (param); if (function.has_return_type ()) diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index 42513fe22d3c..d3a833649bfa 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -435,7 +435,7 @@ class DefaultASTVisitor : public ASTVisitor virtual void visit (AST::StructPatternElements &spe); virtual void visit (AST::MaybeNamedParam ¶m); - void visit (AST::Attribute &attribute) {} + virtual void visit (AST::Attribute &attribute) {} template void visit_outer_attrs (T &node) { diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/rust-feature-gate.cc index 5f07d22f1ac1..2b15f1142a62 100644 --- a/gcc/rust/checks/errors/rust-feature-gate.cc +++ b/gcc/rust/checks/errors/rust-feature-gate.cc @@ -17,11 +17,19 @@ // . #include "rust-feature-gate.h" +#include "config.h" +#include "is-a.h" #include "rust-abi.h" +#include "rust-ast.h" #include "rust-attribute-values.h" #include "rust-ast-visitor.h" #include "rust-feature.h" #include "rust-ast-full.h" +#include "rust-item.h" +#include "rust-path.h" +#include "rust-type.h" +#include "rust-tyty.h" +#include namespace Rust { @@ -236,4 +244,40 @@ FeatureGate::visit (AST::UseTreeGlob &use) // #[feature(prelude_import)] } +void +FeatureGate::visit (AST::RawPointerType &type) +{ + auto &t = static_cast (type.get_type_pointed_to ()); + if (t.get_num_segments () == 1) + { + auto seg + = static_cast (*t.get_segments ().at (0).get ()); + if (seg.is_big_self_seg ()) + gate (Feature::Name::ARBITRARY_SELF_TYPES, type.get_locus (), + "arbitrary self types are experimental"); + } +} + +void +FeatureGate::visit (AST::ImplTraitType &type) +{ + gate (Feature::Name::IMPL_TRAIT_IN_ASSOC_TYPE, type.get_locus (), + "impl trait in assoc type is experimental"); +} + +void +FeatureGate::visit (AST::ImplTraitTypeOneBound &type) +{ + gate (Feature::Name::IMPL_TRAIT_IN_ASSOC_TYPE, type.get_locus (), + "impl trait in assoc type is experimental"); +} + +void +FeatureGate::visit (AST::Attribute &attr) +{ + if (attr.get_path ().as_string () == "register_tool") + gate (Feature::Name::REGISTER_TOOL, attr.get_locus (), + "register tool is an experimental feature"); +} + } // namespace Rust diff --git a/gcc/rust/checks/errors/rust-feature-gate.h b/gcc/rust/checks/errors/rust-feature-gate.h index 2d63f4cfdbe1..d5b5041de8b0 100644 --- a/gcc/rust/checks/errors/rust-feature-gate.h +++ b/gcc/rust/checks/errors/rust-feature-gate.h @@ -20,7 +20,11 @@ #define RUST_FEATURE_GATE_H #include "rust-ast-visitor.h" +#include "rust-ast.h" #include "rust-feature.h" +#include "rust-item.h" +#include "rust-path.h" +#include "rust-type.h" namespace Rust { @@ -47,6 +51,10 @@ class FeatureGate : public AST::DefaultASTVisitor void visit (AST::ExternBlock &block) override; void visit (AST::MacroRulesDefinition &rules_def) override; void visit (AST::RangePattern &pattern) override; + void visit (AST::RawPointerType &type) override; + void visit (AST::ImplTraitType &type) override; + void visit (AST::ImplTraitTypeOneBound &type) override; + void visit (AST::Attribute &attr) override; private: void gate (Feature::Name name, location_t loc, const std::string &error_msg); diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/rust-feature.cc index 04872613d114..5d0c2344f877 100644 --- a/gcc/rust/checks/errors/rust-feature.cc +++ b/gcc/rust/checks/errors/rust-feature.cc @@ -58,6 +58,23 @@ Feature::create (Feature::Name f) case Feature::Name::AUTO_TRAITS: return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits", "1.0.0", 13231); + case Feature::Name::ARBITRARY_SELF_TYPES: + return Feature (f, Feature::State::ACCEPTED, "arbitrary_self_types", + "1.49.0", 44874); + case Feature::Name::DOC_CFG: + return Feature (f, Feature::State::ACCEPTED, "doc_cfg", "1.49.0", 43781); + case Feature::Name::IMPL_TRAIT_IN_ASSOC_TYPE: + return Feature (f, Feature::State::ACCEPTED, "impl_trait_in_assoc_type", + "1.49.0", 63063); + case Feature::Name::REGISTER_TOOL: + return Feature (f, Feature::State::ACCEPTED, "register_tool", "1.49.0", + 66079); + case Feature::Name::ASSOCIATED_TYPE_DEFAULTS: + return Feature (f, Feature::State::ACCEPTED, "associated_type_defaults", + "1.49.0", 29661); + case Feature::Name::CONST_TRAIT_IMPL: + return Feature (f, Feature::State::ACCEPTED, "const_trait_impl", "1.49.0", + 67792); default: rust_unreachable (); } @@ -80,6 +97,13 @@ const std::map Feature::name_hash_map = { {"raw_ref_op", Feature::Name::RAW_REF_OP}, {"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN}, {"prelude_import", Feature::Name::PRELUDE_IMPORT}, + // Required features for Rust for Linux + {"arbitrary_self_types", Feature::Name::ARBITRARY_SELF_TYPES}, + {"doc_cfg", Feature::Name::DOC_CFG}, + {"impl_trait_in_assoc_type", Feature::Name::IMPL_TRAIT_IN_ASSOC_TYPE}, + {"register_tool", Feature::Name::REGISTER_TOOL}, + {"associated_type_defaults", Feature::Name::ASSOCIATED_TYPE_DEFAULTS}, + {"const_trait_impl", Feature::Name::CONST_TRAIT_IMPL}, }; // namespace Rust tl::optional diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/rust-feature.h index b4e5f2cef077..5690321c7ff8 100644 --- a/gcc/rust/checks/errors/rust-feature.h +++ b/gcc/rust/checks/errors/rust-feature.h @@ -51,6 +51,12 @@ class Feature RAW_REF_OP, EXCLUSIVE_RANGE_PATTERN, PRELUDE_IMPORT, + ARBITRARY_SELF_TYPES, + DOC_CFG, + IMPL_TRAIT_IN_ASSOC_TYPE, + REGISTER_TOOL, + ASSOCIATED_TYPE_DEFAULTS, + CONST_TRAIT_IMPL, }; const std::string &as_string () { return m_name_str; } diff --git a/gcc/testsuite/rust/compile/features/arbitrary_self_types_activated.rs b/gcc/testsuite/rust/compile/features/arbitrary_self_types_activated.rs new file mode 100644 index 000000000000..5ef73eedbd35 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/arbitrary_self_types_activated.rs @@ -0,0 +1,5 @@ +#![feature(arbitrary_self_types)] + +trait Foo { + fn bar(self: *const Self); +} diff --git a/gcc/testsuite/rust/compile/features/arbitrary_self_types_not_activated.rs b/gcc/testsuite/rust/compile/features/arbitrary_self_types_not_activated.rs new file mode 100644 index 000000000000..b9eace62d064 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/arbitrary_self_types_not_activated.rs @@ -0,0 +1,3 @@ +trait Foo { + fn bar(self: *const Self); // { dg-error "arbitrary self types are experimental." } +} diff --git a/gcc/testsuite/rust/compile/features/associated_type_defaults_activated.rs b/gcc/testsuite/rust/compile/features/associated_type_defaults_activated.rs new file mode 100644 index 000000000000..90bb023f7055 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/associated_type_defaults_activated.rs @@ -0,0 +1,15 @@ +// check-pass + +// This is another instance of the "normalizations don't work" issue with +// defaulted associated types. + +#![feature(associated_type_defaults)] + +pub trait Emitter<'a> { + type Ctxt: 'a; + type CtxtBrw: 'a = &'a Self::Ctxt; + + fn get_cx(&'a self) -> Self::CtxtBrw; +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/features/associated_type_defaults_not_activated.rs b/gcc/testsuite/rust/compile/features/associated_type_defaults_not_activated.rs new file mode 100644 index 000000000000..579703a1d132 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/associated_type_defaults_not_activated.rs @@ -0,0 +1,15 @@ +// check-pass + +// This is another instance of the "normalizations don't work" issue with +// defaulted associated types. + +// #![feature(associated_type_defaults)] + +pub trait Emitter<'a> { + type Ctxt: 'a; + type CtxtBrw: 'a = &'a Self::Ctxt; + + fn get_cx(&'a self) -> Self::CtxtBrw; +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/features/const_trait_impl_activated.rs b/gcc/testsuite/rust/compile/features/const_trait_impl_activated.rs new file mode 100644 index 000000000000..846055db8f39 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/const_trait_impl_activated.rs @@ -0,0 +1 @@ +#![feature(const_trait_impl)] diff --git a/gcc/testsuite/rust/compile/features/doc_cfg_activated.rs b/gcc/testsuite/rust/compile/features/doc_cfg_activated.rs new file mode 100644 index 000000000000..73c83e133878 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/doc_cfg_activated.rs @@ -0,0 +1,20 @@ +#![feature(doc_cfg)] + +#[cfg(any(windows, doc))] +#[doc(cfg(windows))] +/// The application's icon in the notification area (a.k.a. system tray). +/// +/// # Examples +/// +/// ```no_run +/// extern crate my_awesome_ui_library; +/// use my_awesome_ui_library::current_app; +/// use my_awesome_ui_library::windows::notification; +/// +/// let icon = current_app().get::(); +/// icon.show(); +/// icon.show_message("Hello"); +/// ``` +pub struct Icon { + // ... +} diff --git a/gcc/testsuite/rust/compile/features/doc_cfg_not_activated.rs b/gcc/testsuite/rust/compile/features/doc_cfg_not_activated.rs new file mode 100644 index 000000000000..0266f4f71ca4 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/doc_cfg_not_activated.rs @@ -0,0 +1,18 @@ +#[cfg(any(windows, doc))] +#[doc(cfg(windows))] +/// The application's icon in the notification area (a.k.a. system tray). +/// +/// # Examples +/// +/// ```no_run +/// extern crate my_awesome_ui_library; +/// use my_awesome_ui_library::current_app; +/// use my_awesome_ui_library::windows::notification; +/// +/// let icon = current_app().get::(); +/// icon.show(); +/// icon.show_message("Hello"); +/// ``` +pub struct Icon { + // ... +} diff --git a/gcc/testsuite/rust/compile/feature_extern_types.rs b/gcc/testsuite/rust/compile/features/extern_types.rs similarity index 100% rename from gcc/testsuite/rust/compile/feature_extern_types.rs rename to gcc/testsuite/rust/compile/features/extern_types.rs diff --git a/gcc/testsuite/rust/compile/features/feature.exp b/gcc/testsuite/rust/compile/features/feature.exp new file mode 100644 index 000000000000..ac891db246e3 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/feature.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2021-2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Compile tests, no torture testing. +# +# These tests raise errors in the front end; torture testing doesn't apply. + +# Load support procs. +load_lib rust-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +set saved-dg-do-what-default ${dg-do-what-default} + +set dg-do-what-default "compile" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" "" +set dg-do-what-default ${saved-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_activated.rs b/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_activated.rs new file mode 100644 index 000000000000..b08eddcfac64 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_activated.rs @@ -0,0 +1,28 @@ +// check-pass +// { dg-additional-options "-frust-compile-until=lowering" } + +#![feature(impl_trait_in_assoc_type)] + +fn main() {} + +trait Bar { + type Assoc; +} + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocIsCopy; +impl Bar for AssocIsCopy { + type Assoc = u8; +} + +impl Thing for AssocIsCopy { + type Out = impl Bar; + + fn func() -> Self::Out { + AssocIsCopy + } +} diff --git a/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_not_activated.rs b/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_not_activated.rs new file mode 100644 index 000000000000..341931bb452b --- /dev/null +++ b/gcc/testsuite/rust/compile/features/impl_trait_in_assoc_type_not_activated.rs @@ -0,0 +1,25 @@ +// { dg-additional-options "-frust-compile-until=lowering" } + +fn main() {} + +trait Bar { + type Assoc; +} + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocIsCopy; +impl Bar for AssocIsCopy { + type Assoc = u8; +} + +impl Thing for AssocIsCopy { + type Out = impl Bar; // { dg-error "impl trait in assoc type is experimental" } + + fn func() -> Self::Out { + AssocIsCopy + } +} diff --git a/gcc/testsuite/rust/compile/feature_intrinsics.rs b/gcc/testsuite/rust/compile/features/intrinsics.rs similarity index 100% rename from gcc/testsuite/rust/compile/feature_intrinsics.rs rename to gcc/testsuite/rust/compile/features/intrinsics.rs diff --git a/gcc/testsuite/rust/compile/features/register_tool_activated.rs b/gcc/testsuite/rust/compile/features/register_tool_activated.rs new file mode 100644 index 000000000000..6e7ad924b8c1 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/register_tool_activated.rs @@ -0,0 +1,4 @@ +#![feature(register_tool)] +#![register_tool(my_tool)] + +fn main() {} diff --git a/gcc/testsuite/rust/compile/features/register_tool_not_activated.rs b/gcc/testsuite/rust/compile/features/register_tool_not_activated.rs new file mode 100644 index 000000000000..b16bd98b2345 --- /dev/null +++ b/gcc/testsuite/rust/compile/features/register_tool_not_activated.rs @@ -0,0 +1,3 @@ +#![register_tool(my_tool)] // { dg-error "register tool is an experimental feature" } + +fn main() {}