From b34503e60ee674b31797790b2b8d8a20f1a54e48 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 18 Aug 2018 00:52:34 +0300 Subject: [PATCH] Stabilize a few secondary macro features `tool_attributes`, `proc_macro_path_invoc`, partially `proc_macro_gen` --- .../src/language-features/tool-attributes.md | 26 ------------------- src/librustc_resolve/macros.rs | 15 ----------- src/libsyntax/ext/expand.rs | 15 ++++------- src/libsyntax/feature_gate.rs | 9 +++---- .../proc-macro/auxiliary/more-gates.rs | 11 -------- .../proc-macro/more-gates.rs | 7 +---- .../proc-macro/proc-macro-gates.rs | 6 ----- .../run-pass-fulldeps/proc-macro/derive-b.rs | 2 +- .../proc-macro/issue-42708.rs | 2 +- .../proc-macro/issue-50061.rs | 2 +- src/test/run-pass/tool_attributes.rs | 1 - .../ui-fulldeps/proc-macro/generate-mod.rs | 2 -- .../proc-macro/generate-mod.stderr | 16 ++++++------ src/test/ui/custom-attribute-multisegment.rs | 2 +- .../feature-gate-tool_attributes.rs | 15 ----------- .../feature-gate-tool_attributes.stderr | 11 -------- .../tool-attributes-misplaced-1.rs | 2 +- .../tool-attributes-misplaced-2.rs | 2 -- .../tool-attributes-misplaced-2.stderr | 4 +-- .../tool-attributes-shadowing.rs | 2 -- .../tool-attributes-shadowing.stderr | 2 +- src/test/ui/unknown-tool-name.rs | 2 -- src/test/ui/unknown-tool-name.stderr | 2 +- 23 files changed, 27 insertions(+), 131 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/tool-attributes.md delete mode 100644 src/test/ui/feature-gates/feature-gate-tool_attributes.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-tool_attributes.stderr diff --git a/src/doc/unstable-book/src/language-features/tool-attributes.md b/src/doc/unstable-book/src/language-features/tool-attributes.md deleted file mode 100644 index 15fc84a3e2a3..000000000000 --- a/src/doc/unstable-book/src/language-features/tool-attributes.md +++ /dev/null @@ -1,26 +0,0 @@ -# `tool_attributes` - -The tracking issue for this feature is: [#44690] - -[#44690]: /~https://github.com/rust-lang/rust/issues/44690 - ------------------------- - -Tool attributes let you use scoped attributes to control the behavior -of certain tools. - -Currently tool names which can be appear in scoped attributes are restricted to -`clippy` and `rustfmt`. - -## An example - -```rust -#![feature(tool_attributes)] - -#[rustfmt::skip] -fn foo() { println!("hello, world"); } - -fn main() { - foo(); -} -``` diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 1161d57417b1..382a53b720ac 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -367,17 +367,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let def = def?; - if path.segments.len() > 1 { - if kind != MacroKind::Bang { - if def != Def::NonMacroAttr(NonMacroAttrKind::Tool) && - !self.session.features_untracked().proc_macro_path_invoc { - let msg = format!("non-ident {} paths are unstable", kind.descr()); - emit_feature_err(&self.session.parse_sess, "proc_macro_path_invoc", - path.span, GateIssue::Language, &msg); - } - } - } - match def { Def::Macro(def_id, macro_kind) => { self.unused_macros.remove(&def_id); @@ -390,10 +379,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Def::NonMacroAttr(attr_kind) => { if kind == MacroKind::Attr { let features = self.session.features_untracked(); - if attr_kind == NonMacroAttrKind::Tool && !features.tool_attributes { - feature_err(&self.session.parse_sess, "tool_attributes", path.span, - GateIssue::Language, "tool attributes are unstable").emit(); - } if attr_kind == NonMacroAttrKind::Custom { assert!(path.segments.len() == 1); let name = path.segments[0].ident.name.as_str(); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 97279e00869c..494f6d29832d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -666,30 +666,25 @@ impl<'a, 'b> MacroExpander<'a, 'b> { None => return, }; - fragment.visit_with(&mut DisallowModules { + fragment.visit_with(&mut DisallowMacros { span, parse_sess: self.cx.parse_sess, }); - struct DisallowModules<'a> { + struct DisallowMacros<'a> { span: Span, parse_sess: &'a ParseSess, } - impl<'ast, 'a> Visitor<'ast> for DisallowModules<'a> { + impl<'ast, 'a> Visitor<'ast> for DisallowMacros<'a> { fn visit_item(&mut self, i: &'ast ast::Item) { - let name = match i.node { - ast::ItemKind::Mod(_) => Some("modules"), - ast::ItemKind::MacroDef(_) => Some("macro definitions"), - _ => None, - }; - if let Some(name) = name { + if let ast::ItemKind::MacroDef(_) = i.node { emit_feature_err( self.parse_sess, "proc_macro_gen", self.span, GateIssue::Language, - &format!("procedural macros cannot expand to {}", name), + &format!("procedural macros cannot expand to macro definitions"), ); } visit::walk_item(self, i); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 71ad118ed8ea..5e569025ab37 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -438,9 +438,6 @@ declare_features! ( (active, tbm_target_feature, "1.27.0", Some(44839), None), (active, wasm_target_feature, "1.30.0", Some(44839), None), - // Allows macro invocations of the form `#[foo::bar]` - (active, proc_macro_path_invoc, "1.27.0", Some(38356), None), - // Allows macro invocations on modules expressions and statements and // procedural macros to expand to non-items. (active, proc_macro_mod, "1.27.0", Some(38356), None), @@ -454,8 +451,6 @@ declare_features! ( // Access to crate names passed via `--extern` through prelude (active, extern_prelude, "1.27.0", Some(44660), Some(Edition::Edition2018)), - // Scoped attributes - (active, tool_attributes, "1.25.0", Some(44690), None), // Scoped lints (active, tool_lints, "1.28.0", Some(44690), None), @@ -652,6 +647,10 @@ declare_features! ( (accepted, use_extern_macros, "1.30.0", Some(35896), None), // Allows keywords to be escaped for use as identifiers (accepted, raw_identifiers, "1.30.0", Some(48589), None), + // Attributes scoped to tools + (accepted, tool_attributes, "1.30.0", Some(44690), None), + // Allows multi-segment paths in attributes and derives + (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs index 4d89384137b8..67fe93058aa8 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs @@ -16,11 +16,6 @@ extern crate proc_macro; use proc_macro::*; -#[proc_macro_attribute] -pub fn attr2mod(_: TokenStream, _: TokenStream) -> TokenStream { - "mod test {}".parse().unwrap() -} - #[proc_macro_attribute] pub fn attr2mac1(_: TokenStream, _: TokenStream) -> TokenStream { "macro_rules! foo1 { (a) => (a) }".parse().unwrap() @@ -31,11 +26,6 @@ pub fn attr2mac2(_: TokenStream, _: TokenStream) -> TokenStream { "macro foo2(a) { a }".parse().unwrap() } -#[proc_macro] -pub fn mac2mod(_: TokenStream) -> TokenStream { - "mod test2 {}".parse().unwrap() -} - #[proc_macro] pub fn mac2mac1(_: TokenStream) -> TokenStream { "macro_rules! foo3 { (a) => (a) }".parse().unwrap() @@ -49,7 +39,6 @@ pub fn mac2mac2(_: TokenStream) -> TokenStream { #[proc_macro] pub fn tricky(_: TokenStream) -> TokenStream { "fn foo() { - mod test {} macro_rules! foo { (a) => (a) } }".parse().unwrap() } diff --git a/src/test/compile-fail-fulldeps/proc-macro/more-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/more-gates.rs index b7ab978b8ed0..4c038179544f 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/more-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/more-gates.rs @@ -14,9 +14,6 @@ extern crate more_gates as foo; use foo::*; -#[attr2mod] -//~^ ERROR: cannot expand to modules -pub fn a() {} #[attr2mac1] //~^ ERROR: cannot expand to macro definitions pub fn a() {} @@ -24,12 +21,10 @@ pub fn a() {} //~^ ERROR: cannot expand to macro definitions pub fn a() {} -mac2mod!(); //~ ERROR: cannot expand to modules mac2mac1!(); //~ ERROR: cannot expand to macro definitions mac2mac2!(); //~ ERROR: cannot expand to macro definitions tricky!(); -//~^ ERROR: cannot expand to modules -//~| ERROR: cannot expand to macro definitions +//~^ ERROR: cannot expand to macro definitions fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs index 96f68341db7a..5cf65103ba3e 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs @@ -10,7 +10,6 @@ // aux-build:proc-macro-gates.rs // gate-test-proc_macro_non_items -// gate-test-proc_macro_path_invoc // gate-test-proc_macro_mod line // gate-test-proc_macro_expr // gate-test-proc_macro_mod @@ -22,20 +21,15 @@ extern crate proc_macro_gates as foo; use foo::*; -#[foo::a] //~ ERROR: non-ident attribute macro paths are unstable -fn _test() {} - fn _test_inner() { #![a] // OK } #[a] //~ ERROR: custom attributes cannot be applied to modules -//~| ERROR: procedural macros cannot expand to modules mod _test2 {} mod _test2_inner { #![a] //~ ERROR: custom attributes cannot be applied to modules - //~| ERROR: procedural macros cannot expand to modules } #[a = y] //~ ERROR: must only be followed by a delimiter token diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs index 1de6496e29f8..ac9eca382266 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs @@ -11,7 +11,7 @@ // aux-build:derive-b.rs // ignore-stage1 -#![feature(proc_macro_path_invoc, unrestricted_attribute_tokens)] +#![feature(unrestricted_attribute_tokens)] extern crate derive_b; diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs index d4af99f97c5c..7bbdbc6505db 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs @@ -11,7 +11,7 @@ // aux-build:issue-42708.rs // ignore-stage1 -#![feature(decl_macro, proc_macro_path_invoc)] +#![feature(decl_macro)] #![allow(unused)] extern crate issue_42708; diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs b/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs index 53783e7fedb2..410faaeb3eea 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs @@ -11,7 +11,7 @@ // aux-build:issue-50061.rs // ignore-stage1 -#![feature(proc_macro_path_invoc, decl_macro)] +#![feature(decl_macro)] extern crate issue_50061; diff --git a/src/test/run-pass/tool_attributes.rs b/src/test/run-pass/tool_attributes.rs index eb13930de403..9d8e56e44cbb 100644 --- a/src/test/run-pass/tool_attributes.rs +++ b/src/test/run-pass/tool_attributes.rs @@ -10,7 +10,6 @@ // Scoped attributes should not trigger an unused attributes lint. -#![feature(tool_attributes)] #![deny(unused_attributes)] fn main() { diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.rs b/src/test/ui-fulldeps/proc-macro/generate-mod.rs index 6ac6e4f6def5..977faf7decdf 100644 --- a/src/test/ui-fulldeps/proc-macro/generate-mod.rs +++ b/src/test/ui-fulldeps/proc-macro/generate-mod.rs @@ -12,8 +12,6 @@ // aux-build:generate-mod.rs -#![feature(proc_macro_gen, proc_macro_path_invoc)] - extern crate generate_mod; struct FromOutside; diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.stderr b/src/test/ui-fulldeps/proc-macro/generate-mod.stderr index 87e5fe255426..a981b1bc8b85 100644 --- a/src/test/ui-fulldeps/proc-macro/generate-mod.stderr +++ b/src/test/ui-fulldeps/proc-macro/generate-mod.stderr @@ -1,29 +1,29 @@ error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:21:1 + --> $DIR/generate-mod.rs:19:1 | LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `Outer` in this scope - --> $DIR/generate-mod.rs:21:1 + --> $DIR/generate-mod.rs:19:1 | LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:24:1 + --> $DIR/generate-mod.rs:22:1 | LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `OuterAttr` in this scope - --> $DIR/generate-mod.rs:24:1 + --> $DIR/generate-mod.rs:22:1 | LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope warning: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:28:10 + --> $DIR/generate-mod.rs:26:10 | LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -33,7 +33,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside = note: for more information, see issue #50504 warning: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:28:10 + --> $DIR/generate-mod.rs:26:10 | LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -42,7 +42,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside = note: for more information, see issue #50504 warning: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:35:14 + --> $DIR/generate-mod.rs:33:14 | LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -51,7 +51,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOut = note: for more information, see issue #50504 warning: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:35:14 + --> $DIR/generate-mod.rs:33:14 | LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import diff --git a/src/test/ui/custom-attribute-multisegment.rs b/src/test/ui/custom-attribute-multisegment.rs index ad8e0e76e141..a8d82a359464 100644 --- a/src/test/ui/custom-attribute-multisegment.rs +++ b/src/test/ui/custom-attribute-multisegment.rs @@ -10,7 +10,7 @@ // Unresolved multi-segment attributes are not treated as custom. -#![feature(custom_attribute, proc_macro_path_invoc)] +#![feature(custom_attribute)] mod existent {} diff --git a/src/test/ui/feature-gates/feature-gate-tool_attributes.rs b/src/test/ui/feature-gates/feature-gate-tool_attributes.rs deleted file mode 100644 index 5aa1670b8288..000000000000 --- a/src/test/ui/feature-gates/feature-gate-tool_attributes.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - #[rustfmt::skip] //~ ERROR tool attributes are unstable - let x = 3 - ; -} diff --git a/src/test/ui/feature-gates/feature-gate-tool_attributes.stderr b/src/test/ui/feature-gates/feature-gate-tool_attributes.stderr deleted file mode 100644 index b024059d4501..000000000000 --- a/src/test/ui/feature-gates/feature-gate-tool_attributes.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: tool attributes are unstable (see issue #44690) - --> $DIR/feature-gate-tool_attributes.rs:12:7 - | -LL | #[rustfmt::skip] //~ ERROR tool attributes are unstable - | ^^^^^^^^^^^^^ - | - = help: add #![feature(tool_attributes)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs index 7a6b9ae9943b..8d3cfb5a1670 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(tool_attributes, custom_attribute)] +#![feature(custom_attribute)] type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt` type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip` diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs index 102edf2813b2..e61ea9d5b443 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(tool_attributes)] - #[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute struct S; diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr index 5b968cd6b8ec..ae47203a9758 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr @@ -1,11 +1,11 @@ error: expected a macro, found tool attribute - --> $DIR/tool-attributes-misplaced-2.rs:13:10 + --> $DIR/tool-attributes-misplaced-2.rs:11:10 | LL | #[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute | ^^^^^^^^^^^^^ error: expected a macro, found tool attribute - --> $DIR/tool-attributes-misplaced-2.rs:17:5 + --> $DIR/tool-attributes-misplaced-2.rs:15:5 | LL | rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute | ^^^^^^^^^^^^^ diff --git a/src/test/ui/tool-attributes/tool-attributes-shadowing.rs b/src/test/ui/tool-attributes/tool-attributes-shadowing.rs index 7913c9f40b55..b6a24ccf748e 100644 --- a/src/test/ui/tool-attributes/tool-attributes-shadowing.rs +++ b/src/test/ui/tool-attributes/tool-attributes-shadowing.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(tool_attributes, proc_macro_path_invoc)] - mod rustfmt {} #[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt` diff --git a/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr b/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr index f668d677f7a2..d593350f123c 100644 --- a/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve. Could not find `skip` in `rustfmt` - --> $DIR/tool-attributes-shadowing.rs:15:12 + --> $DIR/tool-attributes-shadowing.rs:13:12 | LL | #[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt` | ^^^^ Could not find `skip` in `rustfmt` diff --git a/src/test/ui/unknown-tool-name.rs b/src/test/ui/unknown-tool-name.rs index 99c336c28cd2..cd2aeb7494a5 100644 --- a/src/test/ui/unknown-tool-name.rs +++ b/src/test/ui/unknown-tool-name.rs @@ -8,7 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(proc_macro_path_invoc)] - #[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo` fn main() {} diff --git a/src/test/ui/unknown-tool-name.stderr b/src/test/ui/unknown-tool-name.stderr index 151f957ac568..8381c6de83a6 100644 --- a/src/test/ui/unknown-tool-name.stderr +++ b/src/test/ui/unknown-tool-name.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve. Use of undeclared type or module `foo` - --> $DIR/unknown-tool-name.rs:13:3 + --> $DIR/unknown-tool-name.rs:11:3 | LL | #[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo` | ^^^ Use of undeclared type or module `foo`