Hygienize librustc_typeck
.
This commit is contained in:
parent
1f175fa35d
commit
bfa2ef62a1
@ -47,7 +47,7 @@
|
||||
use hir::def::{Def, PathResolution};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use session::Session;
|
||||
use util::nodemap::{DefIdMap, NodeMap};
|
||||
use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt::Debug;
|
||||
@ -77,6 +77,7 @@ pub struct LoweringContext<'a> {
|
||||
// a definition, then we can properly create the def id.
|
||||
parent_def: Option<DefIndex>,
|
||||
resolver: &'a mut Resolver,
|
||||
name_map: FxHashMap<Ident, Name>,
|
||||
|
||||
/// The items being lowered are collected here.
|
||||
items: BTreeMap<NodeId, hir::Item>,
|
||||
@ -126,6 +127,7 @@ pub fn lower_crate(sess: &Session,
|
||||
sess: sess,
|
||||
parent_def: None,
|
||||
resolver: resolver,
|
||||
name_map: FxHashMap(),
|
||||
items: BTreeMap::new(),
|
||||
trait_items: BTreeMap::new(),
|
||||
impl_items: BTreeMap::new(),
|
||||
@ -495,6 +497,14 @@ fn def_key(&mut self, id: DefId) -> DefKey {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_ident(&mut self, ident: Ident) -> Name {
|
||||
let ident = ident.modern();
|
||||
if ident.ctxt == SyntaxContext::empty() {
|
||||
return ident.name;
|
||||
}
|
||||
*self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
|
||||
}
|
||||
|
||||
fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
|
||||
o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
|
||||
}
|
||||
@ -546,7 +556,7 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
|
||||
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
|
||||
hir::TypeBinding {
|
||||
id: self.lower_node_id(b.id),
|
||||
name: b.ident.name,
|
||||
name: self.lower_ident(b.ident),
|
||||
ty: self.lower_ty(&b.ty),
|
||||
span: b.span,
|
||||
}
|
||||
@ -844,7 +854,7 @@ fn lower_path_segment(&mut self,
|
||||
}
|
||||
|
||||
hir::PathSegment {
|
||||
name: segment.identifier.name,
|
||||
name: self.lower_ident(segment.identifier),
|
||||
parameters: parameters,
|
||||
}
|
||||
}
|
||||
@ -941,7 +951,7 @@ fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound {
|
||||
}
|
||||
|
||||
fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::TyParam {
|
||||
let mut name = tp.ident.name;
|
||||
let mut name = self.lower_ident(tp.ident);
|
||||
|
||||
// Don't expose `Self` (recovered "keyword used as ident" parse error).
|
||||
// `rustc::ty` expects `Self` to be only used for a trait's `Self`.
|
||||
@ -1137,7 +1147,11 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
|
||||
hir::StructField {
|
||||
span: f.span,
|
||||
id: self.lower_node_id(f.id),
|
||||
name: f.ident.map(|ident| ident.name).unwrap_or(Symbol::intern(&index.to_string())),
|
||||
name: self.lower_ident(match f.ident {
|
||||
Some(ident) => ident,
|
||||
// FIXME(jseyfried) positional field hygiene
|
||||
None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt },
|
||||
}),
|
||||
vis: self.lower_visibility(&f.vis, None),
|
||||
ty: self.lower_ty(&f.ty),
|
||||
attrs: self.lower_attrs(&f.attrs),
|
||||
@ -1146,7 +1160,7 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
|
||||
|
||||
fn lower_field(&mut self, f: &Field) -> hir::Field {
|
||||
hir::Field {
|
||||
name: respan(f.ident.span, f.ident.node.name),
|
||||
name: respan(f.ident.span, self.lower_ident(f.ident.node)),
|
||||
expr: P(self.lower_expr(&f.expr)),
|
||||
span: f.span,
|
||||
is_shorthand: f.is_shorthand,
|
||||
@ -1371,7 +1385,7 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
|
||||
self.with_parent_def(i.id, |this| {
|
||||
hir::TraitItem {
|
||||
id: this.lower_node_id(i.id),
|
||||
name: i.ident.name,
|
||||
name: this.lower_ident(i.ident),
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
node: match i.node {
|
||||
TraitItemKind::Const(ref ty, ref default) => {
|
||||
@ -1421,7 +1435,7 @@ fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
|
||||
};
|
||||
hir::TraitItemRef {
|
||||
id: hir::TraitItemId { node_id: i.id },
|
||||
name: i.ident.name,
|
||||
name: self.lower_ident(i.ident),
|
||||
span: i.span,
|
||||
defaultness: self.lower_defaultness(Defaultness::Default, has_default),
|
||||
kind: kind,
|
||||
@ -1432,7 +1446,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
|
||||
self.with_parent_def(i.id, |this| {
|
||||
hir::ImplItem {
|
||||
id: this.lower_node_id(i.id),
|
||||
name: i.ident.name,
|
||||
name: this.lower_ident(i.ident),
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
vis: this.lower_visibility(&i.vis, None),
|
||||
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
@ -1461,7 +1475,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
|
||||
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
||||
hir::ImplItemRef {
|
||||
id: hir::ImplItemId { node_id: i.id },
|
||||
name: i.ident.name,
|
||||
name: self.lower_ident(i.ident),
|
||||
span: i.span,
|
||||
vis: self.lower_visibility(&i.vis, Some(i.id)),
|
||||
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
@ -1655,7 +1669,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
|
||||
Spanned {
|
||||
span: f.span,
|
||||
node: hir::FieldPat {
|
||||
name: f.node.ident.name,
|
||||
name: self.lower_ident(f.node.ident),
|
||||
pat: self.lower_pat(&f.node.pat),
|
||||
is_shorthand: f.node.is_shorthand,
|
||||
},
|
||||
@ -1825,7 +1839,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
|
||||
ExprKind::MethodCall(i, ref tps, ref args) => {
|
||||
let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
|
||||
let args = args.iter().map(|x| self.lower_expr(x)).collect();
|
||||
hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
|
||||
hir::ExprMethodCall(respan(i.span, self.lower_ident(i.node)), tps, args)
|
||||
}
|
||||
ExprKind::Binary(binop, ref lhs, ref rhs) => {
|
||||
let binop = self.lower_binop(binop);
|
||||
@ -1924,7 +1938,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
|
||||
P(self.lower_expr(er)))
|
||||
}
|
||||
ExprKind::Field(ref el, ident) => {
|
||||
hir::ExprField(P(self.lower_expr(el)), respan(ident.span, ident.node.name))
|
||||
hir::ExprField(P(self.lower_expr(el)),
|
||||
respan(ident.span, self.lower_ident(ident.node)))
|
||||
}
|
||||
ExprKind::TupField(ref el, ident) => {
|
||||
hir::ExprTupField(P(self.lower_expr(el)), ident)
|
||||
@ -2643,10 +2658,8 @@ fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMod
|
||||
let def_id = {
|
||||
let defs = self.resolver.definitions();
|
||||
let def_path_data = DefPathData::Binding(name.as_str());
|
||||
let def_index = defs.create_def_with_parent(parent_def,
|
||||
id,
|
||||
def_path_data,
|
||||
REGULAR_SPACE);
|
||||
let def_index = defs
|
||||
.create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root());
|
||||
DefId::local(def_index)
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
pub struct DefCollector<'a> {
|
||||
definitions: &'a mut Definitions,
|
||||
parent_def: Option<DefIndex>,
|
||||
expansion: Mark,
|
||||
pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
|
||||
}
|
||||
|
||||
@ -32,9 +33,10 @@ pub struct MacroInvocationData {
|
||||
}
|
||||
|
||||
impl<'a> DefCollector<'a> {
|
||||
pub fn new(definitions: &'a mut Definitions) -> Self {
|
||||
pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
|
||||
DefCollector {
|
||||
definitions: definitions,
|
||||
expansion: expansion,
|
||||
parent_def: None,
|
||||
visit_macro_invoc: None,
|
||||
}
|
||||
@ -54,7 +56,8 @@ fn create_def(&mut self,
|
||||
-> DefIndex {
|
||||
let parent_def = self.parent_def.unwrap();
|
||||
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
|
||||
self.definitions.create_def_with_parent(parent_def, node_id, data, address_space)
|
||||
self.definitions
|
||||
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion)
|
||||
}
|
||||
|
||||
pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
use std::fmt::Write;
|
||||
use std::hash::Hash;
|
||||
use syntax::ast;
|
||||
use syntax::ext::hygiene::Mark;
|
||||
use syntax::symbol::{Symbol, InternedString};
|
||||
use ty::TyCtxt;
|
||||
use util::nodemap::NodeMap;
|
||||
@ -180,6 +181,8 @@ pub struct Definitions {
|
||||
node_to_def_index: NodeMap<DefIndex>,
|
||||
def_index_to_node: [Vec<ast::NodeId>; 2],
|
||||
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
|
||||
macro_def_scopes: FxHashMap<Mark, DefId>,
|
||||
expansions: FxHashMap<DefIndex, Mark>,
|
||||
}
|
||||
|
||||
// Unfortunately we have to provide a manual impl of Clone because of the
|
||||
@ -194,6 +197,8 @@ fn clone(&self) -> Self {
|
||||
self.def_index_to_node[1].clone(),
|
||||
],
|
||||
node_to_hir_id: self.node_to_hir_id.clone(),
|
||||
macro_def_scopes: self.macro_def_scopes.clone(),
|
||||
expansions: self.expansions.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -379,6 +384,8 @@ pub fn new() -> Definitions {
|
||||
node_to_def_index: NodeMap(),
|
||||
def_index_to_node: [vec![], vec![]],
|
||||
node_to_hir_id: IndexVec::new(),
|
||||
macro_def_scopes: FxHashMap(),
|
||||
expansions: FxHashMap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,7 +479,8 @@ pub fn create_def_with_parent(&mut self,
|
||||
parent: DefIndex,
|
||||
node_id: ast::NodeId,
|
||||
data: DefPathData,
|
||||
address_space: DefIndexAddressSpace)
|
||||
address_space: DefIndexAddressSpace,
|
||||
expansion: Mark)
|
||||
-> DefIndex {
|
||||
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
|
||||
parent, node_id, data);
|
||||
@ -510,6 +518,7 @@ pub fn create_def_with_parent(&mut self,
|
||||
assert_eq!(index.as_array_index(),
|
||||
self.def_index_to_node[address_space.index()].len());
|
||||
self.def_index_to_node[address_space.index()].push(node_id);
|
||||
self.expansions.insert(index, expansion);
|
||||
|
||||
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
|
||||
self.node_to_def_index.insert(node_id, index);
|
||||
@ -525,6 +534,18 @@ pub fn init_node_id_to_hir_id_mapping(&mut self,
|
||||
"Trying initialize NodeId -> HirId mapping twice");
|
||||
self.node_to_hir_id = mapping;
|
||||
}
|
||||
|
||||
pub fn expansion(&self, index: DefIndex) -> Mark {
|
||||
self.expansions[&index]
|
||||
}
|
||||
|
||||
pub fn macro_def_scope(&self, mark: Mark) -> DefId {
|
||||
self.macro_def_scopes[&mark]
|
||||
}
|
||||
|
||||
pub fn add_macro_def_scope(&mut self, mark: Mark, scope: DefId) {
|
||||
self.macro_def_scopes.insert(mark, scope);
|
||||
}
|
||||
}
|
||||
|
||||
impl DefPathData {
|
||||
|
@ -637,14 +637,15 @@ pub fn get_parent(&self, id: NodeId) -> NodeId {
|
||||
|
||||
/// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no
|
||||
/// module parent is in this map.
|
||||
pub fn get_module_parent(&self, id: NodeId) -> NodeId {
|
||||
match self.walk_parent_nodes(id, |node| match *node {
|
||||
pub fn get_module_parent(&self, id: NodeId) -> DefId {
|
||||
let id = match self.walk_parent_nodes(id, |node| match *node {
|
||||
NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true,
|
||||
_ => false,
|
||||
}) {
|
||||
Ok(id) => id,
|
||||
Err(id) => id,
|
||||
}
|
||||
};
|
||||
self.local_def_id(id)
|
||||
}
|
||||
|
||||
/// Returns the nearest enclosing scope. A scope is an item or block.
|
||||
|
@ -45,8 +45,9 @@
|
||||
use std::slice;
|
||||
use std::vec::IntoIter;
|
||||
use std::mem;
|
||||
use syntax::ast::{self, DUMMY_NODE_ID, Name, NodeId};
|
||||
use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax::ext::hygiene::{Mark, SyntaxContext};
|
||||
use syntax::symbol::{Symbol, InternedString};
|
||||
use syntax_pos::{DUMMY_SP, Span};
|
||||
use rustc_const_math::ConstInt;
|
||||
@ -268,7 +269,7 @@ pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
|
||||
def => Visibility::Restricted(def.def_id()),
|
||||
},
|
||||
hir::Inherited => {
|
||||
Visibility::Restricted(tcx.hir.local_def_id(tcx.hir.get_module_parent(id)))
|
||||
Visibility::Restricted(tcx.hir.get_module_parent(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1823,17 +1824,22 @@ fn sized_constraint_for_ty(&self,
|
||||
|
||||
impl<'a, 'gcx, 'tcx> VariantDef {
|
||||
#[inline]
|
||||
pub fn find_field_named(&self,
|
||||
name: ast::Name)
|
||||
-> Option<&FieldDef> {
|
||||
self.fields.iter().find(|f| f.name == name)
|
||||
pub fn find_field_named(&self, name: ast::Name) -> Option<&FieldDef> {
|
||||
self.index_of_field_named(name).map(|index| &self.fields[index])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn index_of_field_named(&self,
|
||||
name: ast::Name)
|
||||
-> Option<usize> {
|
||||
self.fields.iter().position(|f| f.name == name)
|
||||
pub fn index_of_field_named(&self, name: ast::Name) -> Option<usize> {
|
||||
if let Some(index) = self.fields.iter().position(|f| f.name == name) {
|
||||
return Some(index);
|
||||
}
|
||||
let mut ident = name.to_ident();
|
||||
while ident.ctxt != SyntaxContext::empty() {
|
||||
ident.ctxt.remove_mark();
|
||||
if let Some(field) = self.fields.iter().position(|f| f.name.to_ident() == ident) {
|
||||
return Some(field);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -2257,10 +2263,6 @@ pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vis_is_accessible_from(self, vis: Visibility, block: NodeId) -> bool {
|
||||
vis.is_accessible_from(self.hir.local_def_id(self.hir.get_module_parent(block)), self)
|
||||
}
|
||||
|
||||
pub fn item_name(self, id: DefId) -> ast::Name {
|
||||
if let Some(id) = self.hir.as_local_node_id(id) {
|
||||
self.hir.name(id)
|
||||
@ -2372,6 +2374,22 @@ pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
|
||||
Err(self.sess.cstore.crate_name(impl_did.krate))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn adjust(self, name: Name, scope: DefId, block: NodeId) -> (Ident, DefId) {
|
||||
self.adjust_ident(name.to_ident(), scope, block)
|
||||
}
|
||||
|
||||
pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
|
||||
let expansion = match scope.krate {
|
||||
LOCAL_CRATE => self.hir.definitions().expansion(scope.index),
|
||||
_ => Mark::root(),
|
||||
};
|
||||
let scope = match ident.ctxt.adjust(expansion) {
|
||||
Some(macro_def) => self.hir.definitions().macro_def_scope(macro_def),
|
||||
None => self.hir.get_module_parent(block),
|
||||
};
|
||||
(ident, scope)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
@ -154,7 +154,7 @@ fn check_match(
|
||||
}
|
||||
}
|
||||
|
||||
let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
|
||||
let module = self.tcx.hir.get_module_parent(scrut.id);
|
||||
MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
|
||||
let mut have_errors = false;
|
||||
|
||||
@ -182,7 +182,7 @@ fn check_match(
|
||||
// Then, if the match has no arms, check whether the scrutinee
|
||||
// is uninhabited.
|
||||
let pat_ty = self.tables.node_id_to_type(scrut.id);
|
||||
let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
|
||||
let module = self.tcx.hir.get_module_parent(scrut.id);
|
||||
if inlined_arms.is_empty() {
|
||||
let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type {
|
||||
pat_ty.is_uninhabited_from(module, self.tcx)
|
||||
@ -231,7 +231,7 @@ fn check_irrefutable(&self, pat: &Pat, is_fn_arg: bool) {
|
||||
"local binding"
|
||||
};
|
||||
|
||||
let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(pat.id));
|
||||
let module = self.tcx.hir.get_module_parent(pat.id);
|
||||
MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
|
||||
let mut patcx = PatternContext::new(self.tcx, self.tables);
|
||||
let pattern = patcx.lower_pattern(pat);
|
||||
|
@ -1320,7 +1320,7 @@ pub fn new(session: &'a Session,
|
||||
module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
|
||||
|
||||
let mut definitions = Definitions::new();
|
||||
DefCollector::new(&mut definitions)
|
||||
DefCollector::new(&mut definitions, Mark::root())
|
||||
.collect_root(crate_name, &session.local_crate_disambiguator().as_str());
|
||||
|
||||
let mut invocations = FxHashMap();
|
||||
|
@ -158,7 +158,7 @@ fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool {
|
||||
|
||||
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark]) {
|
||||
let invocation = self.invocations[&mark];
|
||||
self.collect_def_ids(invocation, expansion);
|
||||
self.collect_def_ids(mark, invocation, expansion);
|
||||
|
||||
self.current_module = invocation.module.get();
|
||||
self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
|
||||
@ -290,7 +290,12 @@ fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
|
||||
Err(determinacy) => return Err(determinacy),
|
||||
},
|
||||
};
|
||||
|
||||
self.macro_defs.insert(invoc.expansion_data.mark, def.def_id());
|
||||
let normal_module_def_id =
|
||||
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
|
||||
self.definitions.add_macro_def_scope(invoc.expansion_data.mark, normal_module_def_id);
|
||||
|
||||
self.unused_macros.remove(&def.def_id());
|
||||
let ext = self.get_macro(def);
|
||||
if ext.is_modern() {
|
||||
@ -665,7 +670,10 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Expansion) {
|
||||
fn collect_def_ids(&mut self,
|
||||
mark: Mark,
|
||||
invocation: &'a InvocationData<'a>,
|
||||
expansion: &Expansion) {
|
||||
let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
|
||||
let InvocationData { def_index, const_expr, .. } = *invocation;
|
||||
|
||||
@ -681,7 +689,7 @@ fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Ex
|
||||
});
|
||||
};
|
||||
|
||||
let mut def_collector = DefCollector::new(&mut self.definitions);
|
||||
let mut def_collector = DefCollector::new(&mut self.definitions, mark);
|
||||
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
|
||||
def_collector.with_parent(def_index, |def_collector| {
|
||||
if const_expr {
|
||||
|
@ -891,7 +891,8 @@ pub fn associated_path_def_to_ty(&self,
|
||||
let item = tcx.associated_items(trait_did).find(|i| i.name == assoc_name)
|
||||
.expect("missing associated type");
|
||||
let def = Def::AssociatedTy(item.def_id);
|
||||
if !tcx.vis_is_accessible_from(item.vis, ref_id) {
|
||||
let def_scope = tcx.adjust(assoc_name, item.container.id(), ref_id).1;
|
||||
if !item.vis.is_accessible_from(def_scope, tcx) {
|
||||
let msg = format!("{} `{}` is private", def.kind_name(), assoc_name);
|
||||
tcx.sess.span_err(span, &msg);
|
||||
}
|
||||
|
@ -338,6 +338,7 @@ pub fn resolve_ufcs(&self,
|
||||
/// and return it, or `None`, if no such item was defined there.
|
||||
pub fn associated_item(&self, def_id: DefId, item_name: ast::Name)
|
||||
-> Option<ty::AssociatedItem> {
|
||||
self.tcx.associated_items(def_id).find(|item| item.name == item_name)
|
||||
let ident = self.tcx.adjust(item_name, def_id, self.body_id).0;
|
||||
self.tcx.associated_items(def_id).find(|item| item.name.to_ident() == ident)
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +371,13 @@ fn reset(&mut self) {
|
||||
|
||||
fn push_inherent_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::AssociatedItem,
|
||||
kind: CandidateKind<'tcx>, import_id: Option<ast::NodeId>) {
|
||||
if self.tcx.vis_is_accessible_from(item.vis, self.body_id) {
|
||||
let is_accessible = if let LookingFor::MethodName(name) = self.looking_for {
|
||||
let def_scope = self.tcx.adjust(name, item.container.id(), self.body_id).1;
|
||||
item.vis.is_accessible_from(def_scope, self.tcx)
|
||||
} else {
|
||||
true
|
||||
};
|
||||
if is_accessible {
|
||||
self.inherent_candidates.push(Candidate { xform_self_ty, item, kind, import_id });
|
||||
} else if self.private_candidate.is_none() {
|
||||
self.private_candidate = Some(item.def());
|
||||
@ -380,7 +386,13 @@ fn push_inherent_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::Associa
|
||||
|
||||
fn push_extension_candidate(&mut self, xform_self_ty: Ty<'tcx>, item: ty::AssociatedItem,
|
||||
kind: CandidateKind<'tcx>, import_id: Option<ast::NodeId>) {
|
||||
if self.tcx.vis_is_accessible_from(item.vis, self.body_id) {
|
||||
let is_accessible = if let LookingFor::MethodName(name) = self.looking_for {
|
||||
let def_scope = self.tcx.adjust(name, item.container.id(), self.body_id).1;
|
||||
item.vis.is_accessible_from(def_scope, self.tcx)
|
||||
} else {
|
||||
true
|
||||
};
|
||||
if is_accessible {
|
||||
self.extension_candidates.push(Candidate { xform_self_ty, item, kind, import_id });
|
||||
} else if self.private_candidate.is_none() {
|
||||
self.private_candidate = Some(item.def());
|
||||
|
@ -195,8 +195,8 @@ pub fn report_method_error(&self,
|
||||
};
|
||||
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
|
||||
if tcx.vis_is_accessible_from(field.vis, self.body_id) {
|
||||
let scope = self.tcx.hir.get_module_parent(self.body_id);
|
||||
if field.vis.is_accessible_from(scope, self.tcx) {
|
||||
if self.is_fn_ty(&field_ty, span) {
|
||||
err.help(&format!("use `({0}.{1})(...)` if you \
|
||||
meant to call the function \
|
||||
|
@ -2916,9 +2916,12 @@ fn check_field(&self,
|
||||
match base_t.sty {
|
||||
ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
|
||||
debug!("struct named {:?}", base_t);
|
||||
if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
|
||||
let (ident, def_scope) =
|
||||
self.tcx.adjust(field.node, base_def.did, self.body_id);
|
||||
let fields = &base_def.struct_variant().fields;
|
||||
if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
|
||||
let field_ty = self.field_ty(expr.span, field, substs);
|
||||
if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
|
||||
if field.vis.is_accessible_from(def_scope, self.tcx) {
|
||||
autoderef.finalize(lvalue_pref, base);
|
||||
self.apply_autoderef_adjustment(base.id, autoderefs, base_t);
|
||||
|
||||
@ -3024,16 +3027,25 @@ fn check_tup_field(&self,
|
||||
if !tuple_like { continue }
|
||||
|
||||
debug!("tuple struct named {:?}", base_t);
|
||||
base_def.struct_variant().fields.get(idx.node).and_then(|field| {
|
||||
let ident = ast::Ident {
|
||||
name: Symbol::intern(&idx.node.to_string()),
|
||||
ctxt: idx.span.ctxt.modern(),
|
||||
};
|
||||
let (ident, def_scope) =
|
||||
self.tcx.adjust_ident(ident, base_def.did, self.body_id);
|
||||
let fields = &base_def.struct_variant().fields;
|
||||
if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
|
||||
let field_ty = self.field_ty(expr.span, field, substs);
|
||||
private_candidate = Some((base_def.did, field_ty));
|
||||
if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
|
||||
if field.vis.is_accessible_from(def_scope, self.tcx) {
|
||||
self.tcx.check_stability(field.did, expr.id, expr.span);
|
||||
Some(field_ty)
|
||||
} else {
|
||||
private_candidate = Some((base_def.did, field_ty));
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ty::TyTuple(ref v, _) => {
|
||||
tuple_like = true;
|
||||
@ -3142,7 +3154,7 @@ fn check_expr_struct_fields(&self,
|
||||
|
||||
let mut remaining_fields = FxHashMap();
|
||||
for field in &variant.fields {
|
||||
remaining_fields.insert(field.name, field);
|
||||
remaining_fields.insert(field.name.to_ident(), field);
|
||||
}
|
||||
|
||||
let mut seen_fields = FxHashMap();
|
||||
@ -3154,7 +3166,8 @@ fn check_expr_struct_fields(&self,
|
||||
let final_field_type;
|
||||
let field_type_hint;
|
||||
|
||||
if let Some(v_field) = remaining_fields.remove(&field.name.node) {
|
||||
let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
|
||||
if let Some(v_field) = remaining_fields.remove(&ident) {
|
||||
final_field_type = self.field_ty(field.span, v_field, substs);
|
||||
field_type_hint = self.field_ty(field.span, v_field, hint_substs);
|
||||
|
||||
@ -3205,7 +3218,7 @@ fn check_expr_struct_fields(&self,
|
||||
|
||||
let mut displayable_field_names = remaining_fields
|
||||
.keys()
|
||||
.map(|x| x.as_str())
|
||||
.map(|ident| ident.name.as_str())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
displayable_field_names.sort();
|
||||
|
@ -16,7 +16,7 @@
|
||||
//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
|
||||
|
||||
use Span;
|
||||
use symbol::Symbol;
|
||||
use symbol::{Ident, Symbol};
|
||||
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use std::cell::RefCell;
|
||||
@ -106,6 +106,7 @@ struct HygieneData {
|
||||
marks: Vec<MarkData>,
|
||||
syntax_contexts: Vec<SyntaxContextData>,
|
||||
markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
|
||||
idents: HashMap<Symbol, Ident>,
|
||||
}
|
||||
|
||||
impl HygieneData {
|
||||
@ -114,6 +115,7 @@ fn new() -> Self {
|
||||
marks: vec![MarkData::default()],
|
||||
syntax_contexts: vec![SyntaxContextData::default()],
|
||||
markings: HashMap::new(),
|
||||
idents: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,3 +350,19 @@ fn decode<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
|
||||
Ok(SyntaxContext::empty()) // FIXME(jseyfried) intercrate hygiene
|
||||
}
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn from_ident(ident: Ident) -> Symbol {
|
||||
HygieneData::with(|data| {
|
||||
let symbol = Symbol::gensym(&ident.name.as_str());
|
||||
data.idents.insert(symbol, ident);
|
||||
symbol
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_ident(self) -> Ident {
|
||||
HygieneData::with(|data| {
|
||||
data.idents.get(&self).cloned().unwrap_or(Ident::with_empty_ctxt(self))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user