diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 864aa7f6dc4..bfcd96cd75a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -863,7 +863,6 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> { let invocation = self.resolver.invocations[&mark]; invocation.module.set(self.resolver.current_module); invocation.parent_legacy_scope.set(self.current_legacy_scope); - invocation.output_legacy_scope.set(self.current_legacy_scope); invocation } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 23fff0d0126..7acbf3c2a8d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -97,6 +97,12 @@ fn is_known_tool(name: Name) -> bool { ["clippy", "rustfmt"].contains(&&*name.as_str()) } +enum DeterminacyExt { + Determined, + Undetermined, + WeakUndetermined, +} + /// A free importable items suggested in case of resolution failure. struct ImportSuggestion { path: Path, @@ -2022,7 +2028,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, - false, record_used, path_span, ); @@ -2053,7 +2058,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, - false, record_used, path_span, ); @@ -2095,7 +2099,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ident, ns, false, - false, path_span, ) { return Some(LexicalScopeBinding::Item(binding)); @@ -2170,7 +2173,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } let result = self.resolve_ident_in_module_unadjusted( - module, ident, ns, false, record_used, span, + module, ident, ns, record_used, span, ); self.current_module = orig_current_module; result @@ -4411,7 +4414,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ident, ns, false, - false, module.span, ).is_ok() { let import_id = match binding.kind { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e38ffaca324..4bbcb90f53b 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,7 +9,7 @@ // except according to those terms. use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error}; +use {CrateLint, DeterminacyExt, Resolver, ResolutionError, is_known_tool, resolve_error}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; use ModuleOrUniformRoot; use Namespace::{self, *}; @@ -54,8 +54,8 @@ pub struct InvocationData<'a> { crate parent_legacy_scope: Cell>, /// Legacy scope *produced* by expanding this macro invocation, /// includes all the macro_rules items, other invocations, etc generated by it. - /// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing). - crate output_legacy_scope: Cell>, + /// `None` if the macro is not expanded yet. + crate output_legacy_scope: Cell>>, } impl<'a> InvocationData<'a> { @@ -64,7 +64,7 @@ impl<'a> InvocationData<'a> { module: Cell::new(graph_root), def_index: CRATE_DEF_INDEX, parent_legacy_scope: Cell::new(LegacyScope::Empty), - output_legacy_scope: Cell::new(LegacyScope::Empty), + output_legacy_scope: Cell::new(Some(LegacyScope::Empty)), } } } @@ -110,7 +110,7 @@ pub struct ParentScope<'a> { // Macro namespace is separated into two sub-namespaces, one for bang macros and // one for attribute-like macros (attributes, derives). // We ignore resolutions from one sub-namespace when searching names in scope for another. -fn sub_namespace_mismatch(requirement: Option, candidate: Option) -> bool { +fn sub_namespace_match(candidate: Option, requirement: Option) -> bool { #[derive(PartialEq)] enum SubNS { Bang, AttrLike } let sub_ns = |kind| match kind { @@ -121,7 +121,7 @@ fn sub_namespace_mismatch(requirement: Option, candidate: Option base::Resolver for Resolver<'a, 'crateloader> { @@ -136,7 +136,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { module: Cell::new(module), def_index: module.def_id().unwrap().index, parent_legacy_scope: Cell::new(LegacyScope::Empty), - output_legacy_scope: Cell::new(LegacyScope::Empty), + output_legacy_scope: Cell::new(Some(LegacyScope::Empty)), })); mark } @@ -212,7 +212,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { expansion: mark, }; fragment.visit_with(&mut visitor); - invocation.output_legacy_scope.set(visitor.current_legacy_scope); + invocation.output_legacy_scope.set(Some(visitor.current_legacy_scope)); } fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc) { @@ -624,26 +624,36 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let mut innermost_result: Option<(&NameBinding, Flags)> = None; // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = WhereToResolve::DeriveHelpers; + let mut where_to_resolve = if ns == MacroNS { + WhereToResolve::DeriveHelpers + } else { + WhereToResolve::Module(parent_scope.module) + }; let mut use_prelude = !parent_scope.module.no_implicit_prelude; + let mut determinacy = Determinacy::Determined; loop { let result = match where_to_resolve { WhereToResolve::DeriveHelpers => { let mut result = Err(Determinacy::Determined); for derive in &parent_scope.derives { let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; - if let Ok((_, ext)) = self.resolve_macro_to_def(derive, MacroKind::Derive, - &parent_scope, force) { - if let SyntaxExtension::ProcMacroDerive(_, helper_attrs, _) = &*ext { - if helper_attrs.contains(&ident.name) { - let binding = - (Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper), - ty::Visibility::Public, derive.span, Mark::root()) - .to_name_binding(self.arenas); - result = Ok((binding, Flags::empty())); - break; + match self.resolve_macro_to_def(derive, MacroKind::Derive, + &parent_scope, force) { + Ok((_, ext)) => { + if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext { + if helpers.contains(&ident.name) { + let binding = + (Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper), + ty::Visibility::Public, derive.span, Mark::root()) + .to_name_binding(self.arenas); + result = Ok((binding, Flags::empty())); + break; + } } } + Err(Determinacy::Determined) => {} + Err(Determinacy::Undetermined) => + result = Err(Determinacy::Undetermined), } } result @@ -651,11 +661,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => Ok((legacy_binding.binding, Flags::MACRO_RULES)), + LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() => + Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), } WhereToResolve::Module(module) => { let orig_current_module = mem::replace(&mut self.current_module, module); - let binding = self.resolve_ident_in_module_unadjusted( + let binding = self.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, ns, @@ -664,21 +676,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> { path_span, ); self.current_module = orig_current_module; - let misc_flags = if module.is_normal() { - Flags::MISC_SUGGEST_SELF - } else { - Flags::empty() - }; - binding.map(|binding| (binding, Flags::MODULE | misc_flags)) + match binding { + Ok(binding) => { + let misc_flags = if module.is_normal() { + Flags::MISC_SUGGEST_SELF + } else { + Flags::empty() + }; + Ok((binding, Flags::MODULE | misc_flags)) + } + Err(DeterminacyExt::Undetermined) => + return Err(Determinacy::determined(force)), + Err(DeterminacyExt::WeakUndetermined) => Err(Determinacy::Undetermined), + Err(DeterminacyExt::Determined) => Err(Determinacy::Determined), + } } WhereToResolve::MacroUsePrelude => { - let mut result = Err(Determinacy::Determined); if use_prelude || self.session.rust_2015() { - if let Some(binding) = self.macro_use_prelude.get(&ident.name).cloned() { - result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); + match self.macro_use_prelude.get(&ident.name).cloned() { + Some(binding) => + Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)), + None => Err(Determinacy::determined( + self.graph_root.unresolved_invocations.borrow().is_empty() + )) } + } else { + Err(Determinacy::Determined) } - result } WhereToResolve::BuiltinMacros => { match self.builtin_macros.get(&ident.name).cloned() { @@ -709,14 +733,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } WhereToResolve::ExternPrelude => { - let mut result = Err(Determinacy::Determined); if use_prelude { - if let Some(binding) = self.extern_prelude_get(ident, !record_used, - innermost_result.is_some()) { - result = Ok((binding, Flags::PRELUDE)); + match self.extern_prelude_get(ident, !record_used, + innermost_result.is_some()) { + Some(binding) => Ok((binding, Flags::PRELUDE)), + None => Err(Determinacy::determined( + self.graph_root.unresolved_invocations.borrow().is_empty() + )), } + } else { + Err(Determinacy::Determined) } - result } WhereToResolve::ToolPrelude => { if use_prelude && is_known_tool(ident.name) { @@ -736,7 +763,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { ident, ns, false, - false, path_span, ) { result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); @@ -757,54 +783,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } }; - macro_rules! continue_search { () => { - where_to_resolve = match where_to_resolve { - WhereToResolve::DeriveHelpers => - WhereToResolve::MacroRules(parent_scope.legacy), - WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { - LegacyScope::Binding(binding) => - WhereToResolve::MacroRules(binding.parent_legacy_scope), - LegacyScope::Invocation(invocation) => - WhereToResolve::MacroRules(invocation.output_legacy_scope.get()), - LegacyScope::Empty => WhereToResolve::Module(parent_scope.module), - LegacyScope::Uninitialized => unreachable!(), - } - WhereToResolve::Module(module) => { - match self.hygienic_lexical_parent(module, &mut ident.span) { - Some(parent_module) => WhereToResolve::Module(parent_module), - None => { - use_prelude = !module.no_implicit_prelude; - match ns { - TypeNS => WhereToResolve::ExternPrelude, - ValueNS => WhereToResolve::StdLibPrelude, - MacroNS => WhereToResolve::MacroUsePrelude, - } - } - } - } - WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros, - WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, - WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers, - WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search - WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, - WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, - WhereToResolve::StdLibPrelude => match ns { - TypeNS => WhereToResolve::BuiltinTypes, - ValueNS => break, // nowhere else to search - MacroNS => unreachable!(), - } - WhereToResolve::BuiltinTypes => break, // nowhere else to search - }; - - continue; - }} - match result { - Ok((binding, flags)) => { - if sub_namespace_mismatch(macro_kind, binding.macro_kind()) { - continue_search!(); - } - + Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => { if !record_used { return Ok(binding); } @@ -865,14 +845,52 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Found the first solution. innermost_result = Some((binding, flags)); } - - continue_search!(); - }, - Err(Determinacy::Determined) => { - continue_search!(); } - Err(Determinacy::Undetermined) => return Err(Determinacy::determined(force)), + Ok(..) | Err(Determinacy::Determined) => {} + Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined } + + where_to_resolve = match where_to_resolve { + WhereToResolve::DeriveHelpers => + WhereToResolve::MacroRules(parent_scope.legacy), + WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { + LegacyScope::Binding(binding) => WhereToResolve::MacroRules( + binding.parent_legacy_scope + ), + LegacyScope::Invocation(invoc) => WhereToResolve::MacroRules( + invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope.get()) + ), + LegacyScope::Empty => WhereToResolve::Module(parent_scope.module), + LegacyScope::Uninitialized => unreachable!(), + } + WhereToResolve::Module(module) => { + match self.hygienic_lexical_parent(module, &mut ident.span) { + Some(parent_module) => WhereToResolve::Module(parent_module), + None => { + use_prelude = !module.no_implicit_prelude; + match ns { + TypeNS => WhereToResolve::ExternPrelude, + ValueNS => WhereToResolve::StdLibPrelude, + MacroNS => WhereToResolve::MacroUsePrelude, + } + } + } + } + WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros, + WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, + WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers, + WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search + WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, + WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, + WhereToResolve::StdLibPrelude => match ns { + TypeNS => WhereToResolve::BuiltinTypes, + ValueNS => break, // nowhere else to search + MacroNS => unreachable!(), + } + WhereToResolve::BuiltinTypes => break, // nowhere else to search + }; + + continue; } // The first found solution was the only one, return it. @@ -880,7 +898,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Ok(binding); } - let determinacy = Determinacy::determined(force); + let determinacy = Determinacy::determined(determinacy == Determinacy::Determined || force); if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) { // For single-segment attributes interpret determinate "no resolution" as a custom // attribute. (Lexical resolution implies the first segment and attr kind should imply @@ -1026,7 +1044,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { def_index: invoc.def_index, module: Cell::new(graph_root), parent_legacy_scope: Cell::new(LegacyScope::Uninitialized), - output_legacy_scope: Cell::new(LegacyScope::Uninitialized), + output_legacy_scope: Cell::new(None), }) }); }; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 890655c398c..8cfeb2b12fb 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Module, ModuleOrUniformRoot, PerNS}; +use {CrateLint, DeterminacyExt, Module, ModuleOrUniformRoot, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use {Resolver, Segment}; @@ -135,16 +135,33 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { .or_insert_with(|| self.arenas.alloc_name_resolution()) } + crate fn resolve_ident_in_module_unadjusted( + &mut self, + module: ModuleOrUniformRoot<'a>, + ident: Ident, + ns: Namespace, + record_used: bool, + path_span: Span, + ) -> Result<&'a NameBinding<'a>, Determinacy> { + self.resolve_ident_in_module_unadjusted_ext( + module, ident, ns, false, record_used, path_span + ).map_err(|determinacy_ext| match determinacy_ext { + DeterminacyExt::Determined => Determined, + DeterminacyExt::Undetermined | DeterminacyExt::WeakUndetermined => Undetermined, + }) + } + /// Attempts to resolve `ident` in namespaces `ns` of `module`. /// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete. - pub fn resolve_ident_in_module_unadjusted(&mut self, - module: ModuleOrUniformRoot<'a>, - ident: Ident, - ns: Namespace, - restricted_shadowing: bool, - record_used: bool, - path_span: Span) - -> Result<&'a NameBinding<'a>, Determinacy> { + crate fn resolve_ident_in_module_unadjusted_ext( + &mut self, + module: ModuleOrUniformRoot<'a>, + ident: Ident, + ns: Namespace, + restricted_shadowing: bool, + record_used: bool, + path_span: Span, + ) -> Result<&'a NameBinding<'a>, DeterminacyExt> { let module = match module { ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::UniformRoot(root) => { @@ -157,7 +174,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let mut ctxt = ident.span.ctxt().modern(); let self_module = self.resolve_self(&mut ctxt, self.current_module); - let binding = self.resolve_ident_in_module_unadjusted( + let binding = self.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(self_module), ident, ns, @@ -211,12 +228,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { return Ok(binding); } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { // Macro-expanded `extern crate`items still can add names to extern prelude. - return Err(Undetermined); + return Err(DeterminacyExt::Undetermined); } else { - return Err(Determined); + return Err(DeterminacyExt::Determined); } } else { - return Err(Determined); + return Err(DeterminacyExt::Determined); }; self.populate_module_if_necessary(crate_root); let binding = (crate_root, ty::Visibility::Public, @@ -229,7 +246,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let resolution = self.resolution(module, ident, ns) .try_borrow_mut() - .map_err(|_| Determined)?; // This happens when there is a cycle of imports + // This happens when there is a cycle of imports. + .map_err(|_| DeterminacyExt::Determined)?; if let Some(binding) = resolution.binding { if !restricted_shadowing && binding.expansion != Mark::root() { @@ -264,13 +282,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } } - return resolution.binding.ok_or(Determined); + return resolution.binding.ok_or(DeterminacyExt::Determined); } let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { // `extern crate` are always usable for backwards compatibility, see issue #37020. let usable = this.is_accessible(binding.vis) || binding.is_extern_crate(); - if usable { Ok(binding) } else { Err(Determined) } + if usable { Ok(binding) } else { Err(DeterminacyExt::Determined) } }; // Items and single imports are not shadowable, if we have one, then it's determined. @@ -288,7 +306,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if !self.is_accessible(single_import.vis.get()) { continue; } - let module = unwrap_or!(single_import.imported_module.get(), return Err(Undetermined)); + let module = unwrap_or!(single_import.imported_module.get(), + return Err(DeterminacyExt::Undetermined)); let ident = match single_import.subclass { SingleImport { source, .. } => source, _ => unreachable!(), @@ -298,7 +317,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { Ok(binding) if !self.is_accessible_from( binding.vis, single_import.parent_scope.module ) => continue, - Ok(_) | Err(Undetermined) => return Err(Undetermined), + Ok(_) | Err(Undetermined) => return Err(DeterminacyExt::Undetermined), } } @@ -319,7 +338,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if !unexpanded_macros || ns == MacroNS || restricted_shadowing { return check_usable(self, binding); } else { - return Err(Undetermined); + return Err(DeterminacyExt::Undetermined); } } @@ -328,17 +347,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // Now we are in situation when new item/import can appear only from a glob or a macro // expansion. With restricted shadowing names from globs and macro expansions cannot // shadow names from outer scopes, so we can freely fallback from module search to search - // in outer scopes. To continue search in outer scopes we have to lie a bit and return - // `Determined` to `early_resolve_ident_in_lexical_scope` even if the correct answer - // for in-module resolution could be `Undetermined`. - if restricted_shadowing { - return Err(Determined); - } + // in outer scopes. For `early_resolve_ident_in_lexical_scope` to continue search in outer + // scopes we return `WeakUndetermined` instead of full `Undetermined`. // Check if one of unexpanded macros can still define the name, // if it can then our "no resolution" result is not determined and can be invalidated. if unexpanded_macros { - return Err(Undetermined); + return Err(DeterminacyExt::WeakUndetermined); } // Check if one of glob imports can still define the name, @@ -350,7 +365,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let module = match glob_import.imported_module.get() { Some(ModuleOrUniformRoot::Module(module)) => module, Some(ModuleOrUniformRoot::UniformRoot(_)) => continue, - None => return Err(Undetermined), + None => return Err(DeterminacyExt::WeakUndetermined), }; let (orig_current_module, mut ident) = (self.current_module, ident.modern()); match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) { @@ -363,7 +378,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { ident, ns, false, - false, path_span, ); self.current_module = orig_current_module; @@ -373,12 +387,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { Ok(binding) if !self.is_accessible_from( binding.vis, glob_import.parent_scope.module ) => continue, - Ok(_) | Err(Undetermined) => return Err(Undetermined), + Ok(_) | Err(Undetermined) => return Err(DeterminacyExt::WeakUndetermined), } } // No resolution and no one else can define the name - determinate error. - Err(Determined) + Err(DeterminacyExt::Determined) } // Add an import directive to the current module. diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr index 3988dec88d5..8a40556a6cd 100644 --- a/src/test/ui/span/macro-ty-params.stderr +++ b/src/test/ui/span/macro-ty-params.stderr @@ -4,6 +4,12 @@ error: unexpected generic arguments in path LL | m!(MyTrait<>); //~ ERROR generic arguments in macro path | ^^^^^^^^^ +error: generic arguments in macro path + --> $DIR/macro-ty-params.rs:20:15 + | +LL | m!(MyTrait<>); //~ ERROR generic arguments in macro path + | ^^ + error: generic arguments in macro path --> $DIR/macro-ty-params.rs:18:8 | @@ -16,11 +22,5 @@ error: generic arguments in macro path LL | foo::<>!(); //~ ERROR generic arguments in macro path | ^^^^ -error: generic arguments in macro path - --> $DIR/macro-ty-params.rs:20:15 - | -LL | m!(MyTrait<>); //~ ERROR generic arguments in macro path - | ^^ - error: aborting due to 4 previous errors