visit (generic);
if (impl.has_where_clause ())
visit (impl.get_where_clause ());
- visit (impl.get_type ());
+ visit_impl_type (impl.get_type ());
ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_inner);
};
visit (generic);
if (impl.has_where_clause ())
visit (impl.get_where_clause ());
- visit (impl.get_type ());
+ visit_impl_type (impl.get_type ());
visit (impl.get_trait_path ());
ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_inner);
void visit (AST::Trait &) override;
// used to handle Self insertion in TopLevel
virtual void maybe_insert_big_self (AST::Impl &) {}
+ virtual void visit_impl_type (AST::Type &type) { visit (type); }
void visit (AST::InherentImpl &) override;
void visit (AST::TraitImpl &) override;
namespace Resolver2_0 {
Late::Late (NameResolutionContext &ctx)
- : DefaultResolver (ctx), funny_error (false)
+ : DefaultResolver (ctx), funny_error (false), block_big_self (false)
{}
static NodeId
Definition (resolved->get_node_id ()));
}
+void
+Late::visit_impl_type (AST::Type &type)
+{
+ // TODO: does this have to handle reentrancy?
+ rust_assert (!block_big_self);
+ block_big_self = true;
+ visit (type);
+ block_big_self = false;
+}
+
void
Late::visit (AST::TypePath &type)
{
DefaultResolver::visit (type);
+ // prevent "impl Self {}" and similar
+ if (type.get_segments ().size () == 1
+ && !type.get_segments ().front ()->is_lang_item ()
+ && type.get_segments ().front ()->is_big_self_seg () && block_big_self)
+ {
+ rust_error_at (type.get_locus (),
+ "%<Self%> is not valid in the self type of an impl block");
+ return;
+ }
+
// this *should* mostly work
// TODO: make sure typepath-like path resolution (?) is working
auto resolved = ctx.resolve_path (type, Namespace::Types);
void visit (AST::ContinueExpr &) override;
void visit (AST::LoopLabel &) override;
void visit (AST::PathInExpression &) override;
+ void visit_impl_type (AST::Type &) override;
void visit (AST::TypePath &) override;
void visit (AST::Visibility &) override;
void visit (AST::Trait &) override;
void setup_builtin_types ();
bool funny_error;
+
+ /* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
+ bool block_big_self;
};
// TODO: Add missing mappings and data structures
-impl Self<0> {}
+impl Foo<0> {}
// { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
issue-2905-2.rs
torture/alt_patterns1.rs
torture/name_resolve1.rs
-issue-3671.rs
issue-3652.rs
issue-1487.rs
issue-2015.rs
--- /dev/null
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
+// the error message here is what rustc >=1.66 emits
+// rustc <1.66 emits a "cycle detected" error when
+// trying to calculate the impl type
+//
+// since we aren't trying to match error messages too closely
+// and the >=1.66 error message is nicer
+// we may as well mimic that
+
+impl ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
+
+trait Foo {}
+
+impl Foo for ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }