diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b64f7b8ad1b11..8a16652834c43 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1894,6 +1894,8 @@ pub struct AssocConstraint { pub gen_args: Option, pub kind: AssocConstraintKind, pub span: Span, + + pub impl_trait_id: NodeId, } /// The kinds of an `AssocConstraint`. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 85bb52964865b..9586854c7193e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -430,11 +430,13 @@ pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[ } pub fn noop_visit_constraint( - AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint, + AssocConstraint { id, ident, gen_args, kind, span, impl_trait_id }: &mut AssocConstraint, vis: &mut T, ) { vis.visit_id(id); vis.visit_ident(ident); + vis.visit_id(impl_trait_id); + if let Some(ref mut gen_args) = gen_args { vis.visit_generic_args(gen_args); } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 51e5c3384a791..7b6b85ad1843b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -928,20 +928,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => (false, itctx), }; - if desugar_to_impl_trait { + let desugar = if let ImplTraitContext::Universal = itctx { + self.is_in_dyn_type + } else { + self.resolver.opt_local_def_id(constraint.impl_trait_id).is_some() + }; + //if desugar_to_impl_trait { + //if self.resolver.opt_local_def_id(constraint.impl_trait_id).is_some() { + if desugar { // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by // constructing the HIR for `impl bounds...` and then lowering that. + debug!("desugaring occurs: {:?}, {:?}", desugar_to_impl_trait, itctx); + //let parent_def_id = self.current_hir_id_owner; + let impl_trait_node_id = constraint.impl_trait_id; - let parent_def_id = self.current_hir_id_owner; - let impl_trait_node_id = self.resolver.next_node_id(); - self.resolver.create_def( + /*self.resolver.create_def( parent_def_id, impl_trait_node_id, DefPathData::ImplTrait, ExpnId::root(), constraint.span, - ); - + );*/ self.with_dyn_type_scope(false, |this| { let node_id = this.resolver.next_node_id(); let ty = this.lower_ty( @@ -960,6 +967,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Desugar `AssocTy: Bounds` into a type binding where the // later desugars into a trait predicate. let bounds = self.lower_param_bounds(bounds, itctx); + debug!("desugaring does not occur: {:?}, {:?}", desugar_to_impl_trait, itctx); hir::TypeBindingKind::Constraint { bounds } } @@ -1289,6 +1297,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); + // impl_trait_node_id let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); let mut collected_lifetimes = FxHashMap::default(); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 21db7d0eebcc0..e6daee6066bd3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1733,6 +1733,8 @@ fn deny_equality_constraints( term: predicate.rhs_ty.clone().into(), }, span: ident.span, + + impl_trait_id: rustc_ast::node_id::DUMMY_NODE_ID, }); // Add `` to `Foo`. match &mut assoc_path.segments[len].args { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 5c6fb376cd41a..fb9f7ac29b784 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -549,8 +549,14 @@ impl<'a> Parser<'a> { if let AssocConstraintKind::Bound { .. } = kind { self.sess.gated_spans.gate(sym::associated_type_bounds, span); } - let constraint = - AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span }; + let constraint = AssocConstraint { + id: ast::DUMMY_NODE_ID, + ident, + gen_args, + kind, + span, + impl_trait_id: ast::DUMMY_NODE_ID, + }; Ok(Some(AngleBracketedArg::Constraint(constraint))) } else { Ok(Some(AngleBracketedArg::Arg(arg))) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index f9aff7fd68685..8e156f2d6cb0e 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -1,5 +1,5 @@ use crate::{ImplTraitContext, Resolver}; -use rustc_ast::visit::{self, FnKind}; +use rustc_ast::visit::{self, BoundKind, FnKind}; use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_lowering::ResolverAstLowering; @@ -117,18 +117,36 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { let def = self.create_def(i.id, def_data, i.span); self.with_parent(def, |this| { - this.with_impl_trait(ImplTraitContext::Existential, |this| { - match i.kind { - ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { - // If this is a unit or tuple-like struct, register the constructor. - if let Some(ctor_hir_id) = struct_def.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); + if let ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) = i.kind + { + this.with_impl_trait(ImplTraitContext::Existential, |this| { + //visit::walk_item(this, i); + this.visit_vis(&i.vis); + this.visit_ident(i.ident); + + this.visit_generics(generics); + walk_list!(this, visit_param_bound, bounds, BoundKind::Bound); + + this.with_impl_trait(ImplTraitContext::TyAliasOpaqueTy, |this| { + walk_list!(this, visit_ty, ty) + }); + walk_list!(this, visit_attribute, &i.attrs); + }) + } else { + this.with_impl_trait(ImplTraitContext::Existential, |this| { + match i.kind { + ItemKind::Struct(ref struct_def, _) + | ItemKind::Union(ref struct_def, _) => { + // If this is a unit or tuple-like struct, register the constructor. + if let Some(ctor_hir_id) = struct_def.ctor_id() { + this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); + } } + _ => {} } - _ => {} - } - visit::walk_item(this, i); - }) + visit::walk_item(this, i); + }) + } }); } @@ -154,8 +172,24 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { self.with_parent(closure_def, |this| walk_list!(this, visit_block, body)); return; } - } + if let FnRetTy::Ty(ref ty) = &sig.decl.output { + if let TyKind::ImplTrait(..) = ty.kind { + //let node_id = self.create_def(node_id, DefPathData::Impl, span); + self.visit_generics(generics); + + self.visit_fn_header(&sig.header); + for param in &sig.decl.inputs { + self.visit_param(param); + } + self.with_impl_trait(ImplTraitContext::ReturnOpaquePositionTy, |this| { + this.visit_fn_ret_ty(&sig.decl.output) + }); + walk_list!(self, visit_block, body); + return; + } + } + } visit::walk_fn(self, fn_kind, span); } @@ -285,19 +319,42 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), TyKind::ImplTrait(node_id, _) => { let parent_def = match self.impl_trait_context { - ImplTraitContext::Universal(item_def) => self.resolver.create_def( - item_def, - node_id, - DefPathData::ImplTrait, - self.expansion.to_expn_id(), - ty.span, - ), - ImplTraitContext::Existential => { - self.create_def(node_id, DefPathData::ImplTrait, ty.span) + ImplTraitContext::Universal(item_def) + | ImplTraitContext::UniversalInDyn(item_def) => { + let def_id = self.resolver.create_def( + item_def, + node_id, + DefPathData::ImplTrait, + self.expansion.to_expn_id(), + ty.span, + ); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + def_id + } + ImplTraitContext::Existential | ImplTraitContext::TyAliasOpaqueTy => { + let def_id = self.create_def(node_id, DefPathData::ImplTrait, ty.span); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + def_id + } + ImplTraitContext::ReturnOpaquePositionTy => { + let def_id = self.create_def(node_id, DefPathData::ImplTrait, ty.span); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + def_id } }; + self.with_parent(parent_def, |this| visit::walk_ty(this, ty)) } + TyKind::TraitObject(_, TraitObjectSyntax::Dyn) => { + self.with_impl_trait(ImplTraitContext::UniversalInDyn(self.parent_def), |this| { + visit::walk_ty(this, ty) + }); + } + TyKind::TraitObject(..) => { + self.with_impl_trait(ImplTraitContext::Universal(self.parent_def), |this| { + visit::walk_ty(this, ty) + }); + } _ => visit::walk_ty(self, ty), } } @@ -352,4 +409,39 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { visit::walk_crate(self, krate) } } + + fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) { + match self.impl_trait_context { + ImplTraitContext::UniversalInDyn(item_def) => { + if let AssocConstraintKind::Bound { .. } = constraint.kind { + let node_id = constraint.impl_trait_id; + let def_id = self.resolver.create_def( + item_def, + node_id, + DefPathData::ImplTrait, + self.expansion.to_expn_id(), + constraint.span, + ); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + } + } + ImplTraitContext::ReturnOpaquePositionTy => { + if let AssocConstraintKind::Bound { .. } = constraint.kind { + let node_id = constraint.impl_trait_id; + let def_id = self.create_def(node_id, DefPathData::ImplTrait, constraint.span); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + } + } + ImplTraitContext::TyAliasOpaqueTy => { + if let AssocConstraintKind::Bound { .. } = constraint.kind { + let node_id = constraint.impl_trait_id; + let def_id = self.create_def(node_id, DefPathData::ImplTrait, constraint.span); + self.resolver.impl_trait_context.insert(def_id, self.impl_trait_context); + } + } + _ => {} + } + + visit::walk_assoc_constraint(self, constraint); + } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 49c15d2c9ef1f..e9c2ea3c59538 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -164,6 +164,9 @@ impl<'a> ParentScope<'a> { enum ImplTraitContext { Existential, Universal(LocalDefId), + UniversalInDyn(LocalDefId), + ReturnOpaquePositionTy, + TyAliasOpaqueTy, } #[derive(Eq)] @@ -1041,6 +1044,8 @@ pub struct Resolver<'a> { confused_type_with_std_module: FxHashMap, access_levels: AccessLevels, + + impl_trait_context: FxHashMap, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1397,6 +1402,8 @@ impl<'a> Resolver<'a> { proc_macros: Default::default(), confused_type_with_std_module: Default::default(), access_levels: Default::default(), + + impl_trait_context: FxHashMap::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver);