Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: impl Trait desugaring in trait objects' assoc constraints #97335

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
383825b
fix: generic bounds to impl Trait desugaring in trait objects
randomicon00 May 23, 2022
95dc803
fix: generic bounds to impl Trait desugaring in trait objects
randomicon00 May 23, 2022
192b6f6
fix: generic bounds to impl Trait desugaring in trait objects
randomicon00 May 23, 2022
8d1a48c
use assoc constaint impl_context_id to create binding
randomicon00 May 24, 2022
711fc0e
use impl_trait_id to create impl trait def in ast lowering
randomicon00 May 24, 2022
a02dc2f
attempt to fix ICE No HirId for DefId plus comments
randomicon00 May 25, 2022
3c4e763
fix tidy errors
randomicon00 May 25, 2022
305ef51
fix tidy errors
randomicon00 May 25, 2022
032d3d3
fix tidy errors
randomicon00 May 25, 2022
48f8cae
add desugaring from def_collector
randomicon00 May 25, 2022
d8138a2
additional changes
randomicon00 Jun 2, 2022
3f55d23
tidy fixes
randomicon00 Jun 2, 2022
a9ff3f3
changes to def_collector
randomicon00 Jun 2, 2022
ba2aa48
fix UniveralInDyn and replace desugar_to_impl_trait
randomicon00 Jun 6, 2022
e4adc7e
fix tidy errors
randomicon00 Jun 6, 2022
573e1e8
remove comments
randomicon00 Jun 6, 2022
fdd03bc
fix impltrait and def
randomicon00 Jun 6, 2022
44a1135
fix tidy errors
randomicon00 Jun 6, 2022
9629511
Merge branch 'master' into impldesugar
randomicon00 Jun 6, 2022
d942c14
solve conflicts
randomicon00 Jun 6, 2022
4cab123
fix conflicts
randomicon00 Jun 6, 2022
b818e30
Merge branch 'impldesugar' of github.com:randomicon00/rust into impld…
randomicon00 Jun 6, 2022
3b67462
fix build error
randomicon00 Jun 6, 2022
1e69472
fix build error
randomicon00 Jun 6, 2022
6deece1
solve conflicts
randomicon00 Jun 6, 2022
adaa6b0
fix tidy errors
randomicon00 Jun 6, 2022
550a550
Merge branch 'impldesugar' of github.com:randomicon00/rust into impld…
randomicon00 Jun 6, 2022
61f6677
remove duplicate def creation
randomicon00 Jun 7, 2022
2743ece
add creation of impl_trait_id for opaque type
randomicon00 Jun 14, 2022
7068ec0
fix tidy
randomicon00 Jun 14, 2022
1cd9779
fix tidy 2
randomicon00 Jun 14, 2022
05ad36a
fix: add return type to impl_trait_id
randomicon00 Jun 24, 2022
2f17fa2
fix: ui tests
randomicon00 Jun 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,8 @@ pub struct AssocConstraint {
pub gen_args: Option<GenericArgs>,
pub kind: AssocConstraintKind,
pub span: Span,

pub impl_trait_id: NodeId,
}

/// The kinds of an `AssocConstraint`.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,13 @@ pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[
}

pub fn noop_visit_constraint<T: MutVisitor>(
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);
}
Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 }
}
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Bar = RhsTy>` to `Foo`.
match &mut assoc_path.segments[len].args {
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down
134 changes: 113 additions & 21 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
})
}
});
}

Expand All @@ -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);
}

Expand Down Expand Up @@ -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),
}
}
Expand Down Expand Up @@ -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);
}
}
7 changes: 7 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ impl<'a> ParentScope<'a> {
enum ImplTraitContext {
Existential,
Universal(LocalDefId),
UniversalInDyn(LocalDefId),
ReturnOpaquePositionTy,
TyAliasOpaqueTy,
}

#[derive(Eq)]
Expand Down Expand Up @@ -1041,6 +1044,8 @@ pub struct Resolver<'a> {
confused_type_with_std_module: FxHashMap<Span, Span>,

access_levels: AccessLevels,

impl_trait_context: FxHashMap<LocalDefId, ImplTraitContext>,
}

/// Nothing really interesting here; it just provides memory for the rest of the crate.
Expand Down Expand Up @@ -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);
Expand Down