提交 5d8fd98d 编写于 作者: B bors

Auto merge of #60544 - petrochenkov:parder, r=eddyb

Rename `PathResolution` to `PartialRes`

Don't use `PartialRes` when `Res` is enough.
Rename `Res::kind_name` to `Res::descr` for consistency.
Remove `Res::Label`, paths can never resolve to labels.

Some further cleanup after https://github.com/rust-lang/rust/pull/60462
r? @EddyB
use crate::hir::def_id::DefId;
use crate::util::nodemap::{NodeMap, DefIdMap};
use crate::util::nodemap::DefIdMap;
use syntax::ast;
use syntax::ext::base::MacroKind;
use syntax::ast::NodeId;
......@@ -142,7 +142,6 @@ pub enum Res<Id = hir::HirId> {
Upvar(Id, // `HirId` of closed over local
usize, // index in the `freevars` list of the closure
ast::NodeId), // expr node that creates the closure
Label(ast::NodeId),
// Macro namespace
NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
......@@ -151,7 +150,9 @@ pub enum Res<Id = hir::HirId> {
Err,
}
/// The result of resolving a path before lowering to HIR.
/// The result of resolving a path before lowering to HIR,
/// with "module" segments resolved and associated item
/// segments deferred to type checking.
/// `base_res` is the resolution of the resolved part of the
/// path, `unresolved_segments` is the number of unresolved
/// segments.
......@@ -166,19 +167,21 @@ pub enum Res<Id = hir::HirId> {
/// base_res unresolved_segments = 2
/// ```
#[derive(Copy, Clone, Debug)]
pub struct PathResolution {
pub struct PartialRes {
base_res: Res<NodeId>,
unresolved_segments: usize,
}
impl PathResolution {
pub fn new(res: Res<NodeId>) -> Self {
PathResolution { base_res: res, unresolved_segments: 0 }
impl PartialRes {
#[inline]
pub fn new(base_res: Res<NodeId>) -> Self {
PartialRes { base_res, unresolved_segments: 0 }
}
pub fn with_unresolved_segments(res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
if res == Res::Err { unresolved_segments = 0 }
PathResolution { base_res: res, unresolved_segments: unresolved_segments }
#[inline]
pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
if base_res == Res::Err { unresolved_segments = 0 }
PartialRes { base_res, unresolved_segments }
}
#[inline]
......@@ -269,17 +272,10 @@ pub fn present_items(self) -> impl Iterator<Item=T> {
}
}
/// Definition mapping
pub type ResMap = NodeMap<PathResolution>;
/// This is the replacement export map. It maps a module to all of the exports
/// within.
pub type ExportMap<Id> = DefIdMap<Vec<Export<Id>>>;
/// Map used to track the `use` statements within a scope, matching it with all the items in every
/// namespace.
pub type ImportMap = NodeMap<PerNS<Option<PathResolution>>>;
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct Export<Id> {
/// The name of the target.
......@@ -352,7 +348,6 @@ pub fn opt_def_id(&self) -> Option<DefId> {
Res::Local(..) |
Res::Upvar(..) |
Res::Label(..) |
Res::PrimTy(..) |
Res::SelfTy(..) |
Res::SelfCtor(..) |
......@@ -373,14 +368,13 @@ pub fn mod_def_id(&self) -> Option<DefId> {
}
/// A human readable name for the res kind ("function", "module", etc.).
pub fn kind_name(&self) -> &'static str {
pub fn descr(&self) -> &'static str {
match *self {
Res::Def(kind, _) => kind.descr(),
Res::SelfCtor(..) => "self constructor",
Res::PrimTy(..) => "builtin type",
Res::Local(..) => "local variable",
Res::Upvar(..) => "closure capture",
Res::Label(..) => "label",
Res::SelfTy(..) => "self type",
Res::ToolMod => "tool module",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
......@@ -408,7 +402,6 @@ pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
index,
closure
),
Res::Label(id) => Res::Label(id),
Res::SelfTy(a, b) => Res::SelfTy(a, b),
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
......
......@@ -37,7 +37,7 @@
use crate::hir::HirVec;
use crate::hir::map::{DefKey, DefPathData, Definitions};
use crate::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
use crate::hir::def::{Res, DefKind, PathResolution, PerNS};
use crate::hir::def::{Res, DefKind, PartialRes, PerNS};
use crate::hir::{GenericArg, ConstArg};
use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
ELIDED_LIFETIMES_IN_PATHS};
......@@ -145,11 +145,14 @@ fn resolve_hir_path(
is_value: bool,
) -> hir::Path;
/// Obtain the resolution for a `NodeId`.
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
/// Obtain resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
/// Obtain the possible resolutions for the given `use` statement.
fn get_import(&mut self, id: NodeId) -> PerNS<Option<PathResolution>>;
/// Obtain per-namespace resolutions for `use` statement with the given `NoedId`.
fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
/// Obtain resolution for a label with the given `NodeId`.
fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
/// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
/// This should only return `None` during testing.
......@@ -821,7 +824,7 @@ fn lower_res(&mut self, res: Res<NodeId>) -> Res {
}
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
self.resolver.get_resolution(id).map_or(Res::Err, |pr| {
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
if pr.unresolved_segments() != 0 {
bug!("path not fully resolved: {:?}", pr);
}
......@@ -830,12 +833,7 @@ fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
}
fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
self.resolver.get_import(id).present_items().map(|pr| {
if pr.unresolved_segments() != 0 {
bug!("path not fully resolved: {:?}", pr);
}
pr.base_res()
})
self.resolver.get_import_res(id).present_items()
}
fn diagnostic(&self) -> &errors::Handler {
......@@ -1251,7 +1249,7 @@ fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
let target_id = match destination {
Some((id, _)) => {
if let Res::Label(loop_id) = self.expect_full_res(id) {
if let Some(loop_id) = self.resolver.get_label_res(id) {
Ok(self.lower_node_id(loop_id))
} else {
Err(hir::LoopIdError::UnresolvedLabel)
......@@ -1842,13 +1840,13 @@ fn lower_qpath(
let qself_position = qself.as_ref().map(|q| q.position);
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
let resolution = self.resolver
.get_resolution(id)
.unwrap_or_else(|| PathResolution::new(Res::Err));
let partial_res = self.resolver
.get_partial_res(id)
.unwrap_or_else(|| PartialRes::new(Res::Err));
let proj_start = p.segments.len() - resolution.unresolved_segments();
let proj_start = p.segments.len() - partial_res.unresolved_segments();
let path = P(hir::Path {
res: self.lower_res(resolution.base_res()),
res: self.lower_res(partial_res.base_res()),
segments: p.segments[..proj_start]
.iter()
.enumerate()
......@@ -1869,7 +1867,7 @@ fn lower_qpath(
krate: def_id.krate,
index: this.def_key(def_id).parent.expect("missing parent"),
};
let type_def_id = match resolution.base_res() {
let type_def_id = match partial_res.base_res() {
Res::Def(DefKind::AssociatedTy, def_id) if i + 2 == proj_start => {
Some(parent_def_id(self, def_id))
}
......@@ -1886,7 +1884,7 @@ fn lower_qpath(
}
_ => None,
};
let parenthesized_generic_args = match resolution.base_res() {
let parenthesized_generic_args = match partial_res.base_res() {
// `a::b::Trait(Args)`
Res::Def(DefKind::Trait, _)
if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
......@@ -1940,7 +1938,7 @@ fn lower_qpath(
// Simple case, either no projections, or only fully-qualified.
// E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
if resolution.unresolved_segments() == 0 {
if partial_res.unresolved_segments() == 0 {
return hir::QPath::Resolved(qself, path);
}
......@@ -2792,7 +2790,7 @@ fn lower_generics(
&& bound_pred.bound_generic_params.is_empty() =>
{
if let Some(Res::Def(DefKind::TyParam, def_id)) = self.resolver
.get_resolution(bound_pred.bounded_ty.id)
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| d.base_res())
{
if let Some(node_id) =
......@@ -3946,7 +3944,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
let node = match p.node {
PatKind::Wild => hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, ident, ref sub) => {
match self.resolver.get_resolution(p.id).map(|d| d.base_res()) {
match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
// `None` can occur in body-less function signatures
res @ None | res @ Some(Res::Local(_)) => {
let canonical_id = match res {
......
......@@ -2143,7 +2143,7 @@ pub enum UseKind {
/// resolve maps each TraitRef's ref_id to its defining trait; that's all
/// that the ref_id is for. Note that ref_id's value is not the NodeId of the
/// trait being referred to but just a unique NodeId that serves as a key
/// within the ResMap.
/// within the resolution map.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TraitRef {
pub path: Path,
......
......@@ -286,7 +286,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
PatKind::Path(hir::QPath::Resolved(None, ref path))
if path.segments.len() == 1 && path.segments[0].args.is_none() => {
format!("interpreted as {} {} pattern, not new variable",
path.res.article(), path.res.kind_name())
path.res.article(), path.res.descr())
}
_ => format!("pattern `{}` not covered", pattern_string),
};
......
......@@ -41,7 +41,7 @@ pub(crate) fn smart_resolve_report_errors(
let item_str = path.last().unwrap().ident;
let code = source.error_code(res.is_some());
let (base_msg, fallback_label, base_span) = if let Some(res) = res {
(format!("expected {}, found {} `{}`", expected, res.kind_name(), path_str),
(format!("expected {}, found {} `{}`", expected, res.descr(), path_str),
format!("not a {}", expected),
span)
} else {
......
此差异已折叠。
......@@ -333,7 +333,7 @@ fn resolve_macro_to_res(
// Not only attributes, but anything in macro namespace can result in
// `Res::NonMacroAttr` definition (e.g., `inline!()`), so we must report
// an error for those cases.
let msg = format!("expected a macro, found {}", res.kind_name());
let msg = format!("expected a macro, found {}", res.descr());
self.session.span_err(path.span, &msg);
return Err(Determinacy::Determined);
}
......@@ -913,7 +913,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
// (which is a best effort error recovery tool, basically), so we can't
// promise their resolution won't change later.
let msg = format!("inconsistent resolution for a macro: first {}, then {}",
initial_res.kind_name(), res.kind_name());
initial_res.descr(), res.descr());
this.session.span_err(span, &msg);
} else {
span_bug!(span, "inconsistent resolution for a macro");
......
......@@ -21,7 +21,7 @@
UNUSED_IMPORTS,
};
use rustc::hir::def_id::{CrateNum, DefId};
use rustc::hir::def::{self, DefKind, PathResolution, Export};
use rustc::hir::def::{self, DefKind, PartialRes, Export};
use rustc::session::DiagnosticMessageId;
use rustc::util::nodemap::FxHashSet;
use rustc::{bug, span_bug};
......@@ -1233,8 +1233,7 @@ fn finalize_import(
res = Res::Err;
}
}
let import = this.import_map.entry(directive.id).or_default();
import[ns] = Some(PathResolution::new(res));
this.import_res_map.entry(directive.id).or_default()[ns] = Some(res);
});
self.check_for_redundant_imports(
......@@ -1371,7 +1370,7 @@ fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
}
// Record the destination of this import
self.record_res(directive.id, PathResolution::new(module.res().unwrap()));
self.record_partial_res(directive.id, PartialRes::new(module.res().unwrap()));
}
// Miscellaneous post-processing, including recording re-exports,
......
......@@ -796,7 +796,6 @@ fn fn_type(seg: &ast::PathSegment) -> bool {
}
Res::PrimTy(..) |
Res::SelfTy(..) |
Res::Label(..) |
Res::Def(HirDefKind::Macro(..), _) |
Res::ToolMod |
Res::NonMacroAttr(..) |
......
......@@ -579,7 +579,7 @@ fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext<'_, '_>) ->
let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
let (name, start, end) = match res {
Res::Label(..) | Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
return Ok(Signature {
text: pprust::path_to_string(self),
defs: vec![],
......
......@@ -884,7 +884,7 @@ fn check_pat_tuple_struct(
};
let report_unexpected_res = |res: Res| {
let msg = format!("expected tuple struct/variant, found {} `{}`",
res.kind_name(),
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
.span_label(pat.span, "not a tuple variant or struct").emit();
......@@ -947,7 +947,7 @@ fn check_pat_tuple_struct(
let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
struct_span_err!(tcx.sess, pat.span, E0023,
"this pattern has {} field{}, but the corresponding {} has {} field{}",
subpats.len(), subpats_ending, res.kind_name(),
subpats.len(), subpats_ending, res.descr(),
variant.fields.len(), fields_ending)
.span_label(pat.span, format!("expected {} field{}, found {}",
variant.fields.len(), fields_ending, subpats.len()))
......
......@@ -1902,7 +1902,7 @@ fn report_unexpected_variant_res<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
qpath: &QPath) {
span_err!(tcx.sess, span, E0533,
"expected unit struct/variant or constant, found {} `{}`",
res.kind_name(),
res.descr(),
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
}
......
......@@ -513,18 +513,18 @@ fn ambiguity_error(
msg += &format!(
"both {} {} and {} {}",
first_def.article(),
first_def.kind_name(),
first_def.descr(),
second_def.article(),
second_def.kind_name(),
second_def.descr(),
);
}
_ => {
let mut candidates = candidates.iter().peekable();
while let Some((res, _)) = candidates.next() {
if candidates.peek().is_some() {
msg += &format!("{} {}, ", res.article(), res.kind_name());
msg += &format!("{} {}, ", res.article(), res.descr());
} else {
msg += &format!("and {} {}", res.article(), res.kind_name());
msg += &format!("and {} {}", res.article(), res.descr());
}
}
}
......@@ -575,7 +575,7 @@ fn ambiguity_error(
diag.span_suggestion(
sp,
&format!("to link to the {}, {}", res.kind_name(), action),
&format!("to link to the {}, {}", res.descr(), action),
suggestion,
Applicability::MaybeIncorrect,
);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册