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

WIP Add late desugaring to rustc_resolve #120247

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
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: 1 addition & 1 deletion compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fn configure_and_expand(

// Done with macro expansion!

resolver.resolve_crate(&krate);
resolver.resolve_crate(&mut krate);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the new pass is supposed to run right after this function finishes, at least for the step 1 in #99669 (comment).
Also makes sense to put this pass into a separate file.
(I'm still not sure it's a good idea, all in all, maybe it will become more visible once the step 1 is finished.)


krate
}
Expand Down
57 changes: 50 additions & 7 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -669,7 +670,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,

Expand Down Expand Up @@ -4592,13 +4593,55 @@ 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_ty(&mut self, ty: &mut P<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()
{
debug!("[Desugar][Ty][BareTrait][{:?}] {:?}\n{:#?}", ty.span, res, ty);

let trait_obj = TyKind::TraitObject(vec![], TraitObjectSyntax::None);
Copy link
Contributor

Choose a reason for hiding this comment

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

You are creating a trait object with a single generic bound, which is a trait with no bound generics (for<'a>) and no modifiers (?Foo, const Bar). The trait's path is _path from the type.

ty.kind = trait_obj;

debug!("->\n{:#?}\n", ty);
}

mut_visit::noop_visit_ty(ty, self);
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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", || {
Expand Down