From 68197060ec7804a9ce8e09d5aa05fa18f4c47147 Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Sat, 6 Jan 2024 09:36:37 -0800 Subject: [PATCH 1/8] Fix doc typo in LateResolutionVisitor rustc_resolve::late::LateResolutionVisitor contained a typo, claiming that `in_func_body` could hold a `None` value. From context clues, I am guessing that at some point `in_func_body` was an optional. --- compiler/rustc_resolve/src/late.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index a82f7bdfbf3fd..d623f77d8075b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -669,7 +669,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// State used to know whether to ignore resolution errors for function bodies. /// /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items. - /// In most cases this will be `None`, in which case errors will always be reported. + /// In most cases this will be `false`, in which case errors will always be reported. /// If it is `true`, then it will be updated when entering a nested function or trait body. in_func_body: bool, From 849cdcf35c36f55c3dfcfc7d146041dfdcff22c9 Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Sat, 20 Jan 2024 23:24:02 -0800 Subject: [PATCH 2/8] WIP add a stub desugarer, fixing mutable borrows --- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_resolve/src/late.rs | 49 ++++++++++++++++++++++---- compiler/rustc_resolve/src/lib.rs | 2 +- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ce76c2cba939c..f70b097c26fec 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -273,7 +273,7 @@ fn configure_and_expand( // Done with macro expansion! - resolver.resolve_crate(&krate); + resolver.resolve_crate(&mut krate); krate } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d623f77d8075b..5d4f93a9c7f84 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -12,6 +12,7 @@ use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeB use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; +use rustc_ast::mut_visit::MutVisitor; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; use rustc_ast::*; @@ -4592,13 +4593,49 @@ impl<'ast> Visitor<'ast> for LifetimeCountVisitor<'_, '_, '_> { } impl<'a, 'tcx> Resolver<'a, 'tcx> { - pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { + pub(crate) fn late_resolve_crate(&mut self, krate: &mut Crate) { visit::walk_crate(&mut LifetimeCountVisitor { r: self }, krate); - let mut late_resolution_visitor = LateResolutionVisitor::new(self); - late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); - visit::walk_crate(&mut late_resolution_visitor, krate); - for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() { - self.lint_buffer.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); + { + let mut late_resolution_visitor = LateResolutionVisitor::new(self); + late_resolution_visitor + .resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); + visit::walk_crate(&mut late_resolution_visitor, krate); + for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() { + self.lint_buffer.buffer_lint( + lint::builtin::UNUSED_LABELS, + *id, + *span, + "unused label", + ); + } + } + + { + let mut late_desugar_visitor = LateDesugarVisitor::new(self); + late_desugar_visitor.visit_crate(krate); } } } + +struct LateDesugarVisitor<'a, 'b, 'tcx> { + _r: &'b mut Resolver<'a, 'tcx>, +} + +impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { + fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> Self { + LateDesugarVisitor { _r: resolver } + } +} + +impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { + fn visit_item_kind(&mut self, i: &mut ItemKind) { + if is_axel_debug() { + eprintln!("[Desugar][ItemKind] {:?}", i); + } + } +} + +fn is_axel_debug() -> bool { + use std::env; + env::var("AXEL_DEBUG").is_ok() +} diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a14f3d494fb4d..6e029fe273597 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1591,7 +1591,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } /// Entry point to crate resolution. - pub fn resolve_crate(&mut self, krate: &Crate) { + pub fn resolve_crate(&mut self, krate: &mut Crate) { self.tcx.sess.time("resolve_crate", || { self.tcx.sess.time("finalize_imports", || self.finalize_imports()); let exported_ambiguities = self.tcx.sess.time("compute_effective_visibilities", || { From 725b09f604bd5bb4123166a44a9ecce145a16ab2 Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Sun, 21 Jan 2024 00:48:02 -0800 Subject: [PATCH 3/8] WIP add check for bare traits (needs test) --- compiler/rustc_resolve/src/late.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5d4f93a9c7f84..f8af18e0483e5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4618,24 +4618,30 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } struct LateDesugarVisitor<'a, 'b, 'tcx> { - _r: &'b mut Resolver<'a, 'tcx>, + r: &'b mut Resolver<'a, 'tcx>, } impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> Self { - LateDesugarVisitor { _r: resolver } + LateDesugarVisitor { r: resolver } } } impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { - fn visit_item_kind(&mut self, i: &mut ItemKind) { - if is_axel_debug() { - eprintln!("[Desugar][ItemKind] {:?}", i); + fn visit_ty(&mut self, ty: &mut P) { + // check whether this path is a bare trait object + if let TyKind::Path(None, _path) = &ty.kind + && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) + && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + { + if _is_axel_debug() { + eprintln!("[Desugar][Ty][BareTrait] {:?}", ty); + } } } } -fn is_axel_debug() -> bool { +fn _is_axel_debug() -> bool { use std::env; env::var("AXEL_DEBUG").is_ok() } From 78e347f2e9c79565c2a477ce8fbbeec7a286741f Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Sun, 21 Jan 2024 16:27:12 -0800 Subject: [PATCH 4/8] WIP sort of get bare trait desugaring working still need to correctly construct TraitObject kind from res --- compiler/rustc_resolve/src/late.rs | 46 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f8af18e0483e5..85907ca83b0d9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4630,14 +4630,56 @@ impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &mut P) { // check whether this path is a bare trait object + // if _is_axel_debug() { + // let is_path = if let TyKind::Path(None, _path) = &ty.kind { true } else { false }; + // let is_partial_res = if let Some(_partial_res) = self.r.partial_res_map.get(&ty.id) { + // true + // } else { + // false + // }; + // let is_trait = if let Some(partial_res) = self.r.partial_res_map.get(&ty.id) + // && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = + // partial_res.full_res() + // { + // true + // } else { + // false + // }; + + // eprintln!( + // "[Desugar][Ty] {:?}:{:?} (Path: {}, PRes: {}, Trait: {})", + // ty.kind, ty.span, is_path, is_partial_res, is_trait + // ); + // } + + // if _is_axel_debug() { + // eprint!("[Desugar][Ty][{:?}]", ty.span); + // if let Some(partial_res) = self.r.partial_res_map.get(&ty.id) { + // let full_res = partial_res.full_res(); + // eprint!(" [{:?}]", full_res); + // } + // eprintln!("\n\t{:?}", ty) + // } + if let TyKind::Path(None, _path) = &ty.kind && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) - && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + && let Some(res @ Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = + partial_res.full_res() { if _is_axel_debug() { - eprintln!("[Desugar][Ty][BareTrait] {:?}", ty); + eprintln!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); + } + + // TODO(axelmagn): confirm TraitObject variables + let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None); + ty.kind = trait_obj; + + if _is_axel_debug() { + eprintln!("->\n{:#?}\n", ty); } } + + mut_visit::noop_visit_ty(ty, self); } } From 88f425e7daa2ad45ee412ec087e66d2f63f598ad Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Mon, 22 Jan 2024 11:19:12 -0800 Subject: [PATCH 5/8] WIP move to debug statements --- compiler/rustc_resolve/src/late.rs | 41 ++---------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 85907ca83b0d9..7d4ec5c89e53d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4629,54 +4629,17 @@ impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &mut P) { - // check whether this path is a bare trait object - // if _is_axel_debug() { - // let is_path = if let TyKind::Path(None, _path) = &ty.kind { true } else { false }; - // let is_partial_res = if let Some(_partial_res) = self.r.partial_res_map.get(&ty.id) { - // true - // } else { - // false - // }; - // let is_trait = if let Some(partial_res) = self.r.partial_res_map.get(&ty.id) - // && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = - // partial_res.full_res() - // { - // true - // } else { - // false - // }; - - // eprintln!( - // "[Desugar][Ty] {:?}:{:?} (Path: {}, PRes: {}, Trait: {})", - // ty.kind, ty.span, is_path, is_partial_res, is_trait - // ); - // } - - // if _is_axel_debug() { - // eprint!("[Desugar][Ty][{:?}]", ty.span); - // if let Some(partial_res) = self.r.partial_res_map.get(&ty.id) { - // let full_res = partial_res.full_res(); - // eprint!(" [{:?}]", full_res); - // } - // eprintln!("\n\t{:?}", ty) - // } - if let TyKind::Path(None, _path) = &ty.kind && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) && let Some(res @ Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() { - if _is_axel_debug() { - eprintln!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); - } + debug!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); - // TODO(axelmagn): confirm TraitObject variables let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None); ty.kind = trait_obj; - if _is_axel_debug() { - eprintln!("->\n{:#?}\n", ty); - } + debug!("->\n{:#?}\n", ty); } mut_visit::noop_visit_ty(ty, self); From cbc52bf15fc38c32916c79ff33b9cdde866106ae Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Mon, 22 Jan 2024 11:24:59 -0800 Subject: [PATCH 6/8] WIP remove debug helper --- compiler/rustc_resolve/src/late.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7d4ec5c89e53d..5f19e81417396 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4645,8 +4645,3 @@ impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { mut_visit::noop_visit_ty(ty, self); } } - -fn _is_axel_debug() -> bool { - use std::env; - env::var("AXEL_DEBUG").is_ok() -} From 95dd33b610bc675c262155e3e6f8873ab045fa88 Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Tue, 13 Feb 2024 16:28:02 -0800 Subject: [PATCH 7/8] WIP move AST desugaring to its own module --- compiler/rustc_resolve/src/desugar.rs | 37 +++++++++++++++++++++++++++ compiler/rustc_resolve/src/late.rs | 31 +--------------------- compiler/rustc_resolve/src/lib.rs | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 compiler/rustc_resolve/src/desugar.rs diff --git a/compiler/rustc_resolve/src/desugar.rs b/compiler/rustc_resolve/src/desugar.rs new file mode 100644 index 0000000000000..5845c5f6cb9eb --- /dev/null +++ b/compiler/rustc_resolve/src/desugar.rs @@ -0,0 +1,37 @@ +use rustc_ast::{ + mut_visit::{self, MutVisitor}, + ptr::P, + TraitObjectSyntax, Ty, TyKind, +}; +use rustc_hir::def::DefKind; + +use crate::{Res, Resolver}; + +struct LateDesugarVisitor<'a, 'b, 'tcx> { + r: &'b mut Resolver<'a, 'tcx>, +} + +impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { + fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> Self { + LateDesugarVisitor { r: resolver } + } +} + +impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { + fn visit_ty(&mut self, ty: &mut P) { + if let TyKind::Path(None, _path) = &ty.kind + && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) + && let Some(res @ Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = + partial_res.full_res() + { + debug!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); + + let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None); + ty.kind = trait_obj; + + debug!("->\n{:#?}\n", ty); + } + + mut_visit::noop_visit_ty(ty, self); + } +} diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5f19e81417396..38e2e0c8f930b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4615,33 +4615,4 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { late_desugar_visitor.visit_crate(krate); } } -} - -struct LateDesugarVisitor<'a, 'b, 'tcx> { - r: &'b mut Resolver<'a, 'tcx>, -} - -impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { - fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> Self { - LateDesugarVisitor { r: resolver } - } -} - -impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { - fn visit_ty(&mut self, ty: &mut P) { - if let TyKind::Path(None, _path) = &ty.kind - && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) - && let Some(res @ Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = - partial_res.full_res() - { - debug!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); - - let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None); - ty.kind = trait_obj; - - debug!("->\n{:#?}\n", ty); - } - - mut_visit::noop_visit_ty(ty, self); - } -} +} \ No newline at end of file diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6e029fe273597..ca61c0bf0b977 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -77,6 +77,7 @@ type Res = def::Res; mod build_reduced_graph; mod check_unused; mod def_collector; +mod desugar; mod diagnostics; mod effective_visibilities; mod errors; From 828616065354af892fcd48f38705aced8d18eaa2 Mon Sep 17 00:00:00 2001 From: Axel Magnuson Date: Fri, 16 Feb 2024 00:48:29 -0800 Subject: [PATCH 8/8] WIP stub out path visitor --- compiler/rustc_resolve/src/desugar.rs | 24 ++++++++++++++++++++++-- compiler/rustc_resolve/src/late.rs | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/desugar.rs b/compiler/rustc_resolve/src/desugar.rs index 5845c5f6cb9eb..902f7c7f8cd63 100644 --- a/compiler/rustc_resolve/src/desugar.rs +++ b/compiler/rustc_resolve/src/desugar.rs @@ -1,7 +1,7 @@ use rustc_ast::{ mut_visit::{self, MutVisitor}, ptr::P, - TraitObjectSyntax, Ty, TyKind, + Path, TraitObjectSyntax, Ty, TyKind, }; use rustc_hir::def::DefKind; @@ -19,6 +19,9 @@ impl<'a, 'b, 'tcx> LateDesugarVisitor<'a, 'b, 'tcx> { impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &mut P) { + // If the type is a path, and that path resolves to a trate, desugar it + // into a bare trait object. + if let TyKind::Path(None, _path) = &ty.kind && let Some(partial_res) = self.r.partial_res_map.get(&ty.id) && let Some(res @ Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = @@ -26,12 +29,29 @@ impl MutVisitor for LateDesugarVisitor<'_, '_, '_> { { debug!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty); - let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None); + // TODO(axelmagn): extract bounds from path? + let bounds = vec![]; + // TODO(axelmagn): is this the right choice? I don't think a trait + // path would ever imply Dyn, so None is the only other option. + let syntax = TraitObjectSyntax::None; + let trait_obj = TyKind::TraitObject(bounds, syntax); ty.kind = trait_obj; + // TODO(axelmagn): Do the type tokens need to be rewritten? I would + // assume so, for use in AST lowering. + debug!("->\n{:#?}\n", ty); } mut_visit::noop_visit_ty(ty, self); } + + fn visit_path(&mut self, path: &mut Path) { + // TODO(axelmagn): Desugar type-relative paths during resolution. + // Transform a::b::c::d to ::d when a::b::c can be resolved to + // a type and ::d cannot (for instance because it is a trait method). + // (check rustc_ast_lowering::path::lower_qpath for current impl) + + mut_visit::noop_visit_path(path, self); + } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 38e2e0c8f930b..8208e8ef3882b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4615,4 +4615,4 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { late_desugar_visitor.visit_crate(krate); } } -} \ No newline at end of file +}