Skip to content

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

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

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 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 @@ -1911,6 +1911,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
24 changes: 19 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
AssocConstraintKind::Bound { ref bounds } => {
let mut parent_def_id = self.current_hir_id_owner;
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let (desugar_to_impl_trait, itctx) = match itctx {
let (/*desugar_to_impl_trait*/ _, itctx) = match itctx {
// We are in the return position:
//
// fn foo() -> impl Iterator<Item: Debug>
Expand Down Expand Up @@ -1020,21 +1020,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
_ => (false, itctx),
};

if desugar_to_impl_trait {
//if desugar_to_impl_trait {
if self.resolver.opt_local_def_id(constraint.impl_trait_id).is_some() {
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
// constructing the HIR for `impl bounds...` and then lowering that.

let impl_trait_node_id = self.resolver.next_node_id();
// temporary added to avoid error unused parent_def_id
debug!("{:?}", parent_def_id);
// impl_trait_node_id already exists! No need to create it, return it.
//let impl_trait_node_id = self.resolver.next_node_id();
let impl_trait_node_id = constraint.impl_trait_id;
// definition has been already created in def_collector assoc constraint
self.resolver.create_def(
parent_def_id,
impl_trait_node_id,
DefPathData::ImplTrait,
ExpnId::root(),
constraint.span,
);

self.lower_node_id(impl_trait_node_id);
self.with_dyn_type_scope(false, |this| {
let node_id = this.resolver.next_node_id();
// impl_trait_node_id gets lowered in lower_ty_direct here:
// hir_id: self.lower_node_id(def_node_id), (line 1300)
let ty = this.lower_ty(
&Ty {
id: node_id,
Expand Down Expand Up @@ -1273,8 +1280,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
parent_def_id,
) => {
// Add a definition for the in-band `Param`.

// get the def_id that we created in the desugaring
// self.create_def(..)
let def_id = self.resolver.local_def_id(def_node_id);

// lower param bounds `impl Bound1 + Bound2`
let hir_bounds = self.lower_param_bounds(
bounds,
ImplTraitContext::Universal(
Expand All @@ -1285,6 +1296,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
// Set the name to `impl Bound1 + Bound2`.
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
// add the new generic param GenericParam desugaring of the
// impl Bound1 (GenericParameters in place of impl Traits)
in_band_ty_params.push(hir::GenericParam {
hir_id: self.lower_node_id(def_node_id),
name: ParamName::Plain(self.lower_ident(ident)),
Expand Down Expand Up @@ -1353,6 +1366,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 @@ -1726,6 +1726,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
60 changes: 51 additions & 9 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 @@ -285,19 +285,36 @@ 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::Universal(item_def) => {
//| ImplTraitContext::UniversalInDyn(item_def) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//| ImplTraitContext::UniversalInDyn(item_def) => {
| ImplTraitContext::UniversalInDyn(item_def) => {

This is the correct behaviour here.

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, ImplTraitContext::Universal(item_def));
def_id
}
ImplTraitContext::Existential => {
self.create_def(node_id, DefPathData::ImplTrait, ty.span)
let def_id = self.create_def(node_id, DefPathData::ImplTrait, ty.span);
self.resolver
.impl_trait_context
.insert(def_id, ImplTraitContext::Existential);
def_id
}
ImplTraitContext::UniversalInDyn(_) => self.parent_def,
};
self.with_parent(parent_def, |this| visit::walk_ty(this, ty))
}
TyKind::TraitObject(ref bounds, ..) => {
self.with_impl_trait(ImplTraitContext::UniversalInDyn(self.parent_def), |this| {
walk_list!(this, visit_param_bound, bounds, BoundKind::TraitObject);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
walk_list!(this, visit_param_bound, bounds, BoundKind::TraitObject);
visit::walk_ty(self, ty)

No need to re-code the default behaviour.

});
}
_ => visit::walk_ty(self, ty),
}
}
Expand Down Expand Up @@ -352,4 +369,29 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
visit::walk_crate(self, krate)
}
}

fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
/*if let ImplTraitContext::UniversalInDyn(item_def) = self.impl_trait_context {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version is correct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only create the definition is constraint.kind is AssocConstraintKind::Bound.
dyn Foo<T: Trait> becomes dyn Foo<T = impl Trait>.

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, ImplTraitContext::UniversalInDyn(item_def));
}*/
if let ImplTraitContext::UniversalInDyn(_) = self.impl_trait_context {
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, ImplTraitContext::UniversalInDyn(def_id));
}

visit::walk_assoc_constraint(self, constraint);
}
}
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl<'a> ParentScope<'a> {
enum ImplTraitContext {
Existential,
Universal(LocalDefId),
UniversalInDyn(LocalDefId),
}

#[derive(Eq)]
Expand Down Expand Up @@ -1042,6 +1043,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 @@ -1398,6 +1401,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