Skip to content

Refactor global paths #38232

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

Merged
merged 2 commits into from
Dec 23, 2016
Merged
Changes from all 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
46 changes: 22 additions & 24 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ pub struct LoweringContext<'a> {
}

pub trait Resolver {
// Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);

// Obtain the resolution for a node id
@@ -337,7 +337,6 @@ impl<'a> LoweringContext<'a> {

let proj_start = p.segments.len() - resolution.depth;
let path = P(hir::Path {
global: p.global,
def: resolution.base_def,
segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
let param_mode = match (qself_position, param_mode) {
@@ -404,12 +403,17 @@ impl<'a> LoweringContext<'a> {
id: NodeId,
p: &Path,
name: Option<Name>,
param_mode: ParamMode)
param_mode: ParamMode,
defaults_to_global: bool)
-> hir::Path {
let mut segments = p.segments.iter();
if defaults_to_global && p.is_global() {
segments.next();
}

hir::Path {
global: p.global,
def: self.expect_full_def(id),
segments: p.segments.iter().map(|segment| {
segments: segments.map(|segment| {
self.lower_path_segment(segment, param_mode)
}).chain(name.map(|name| {
hir::PathSegment {
@@ -424,9 +428,10 @@ impl<'a> LoweringContext<'a> {
fn lower_path(&mut self,
id: NodeId,
p: &Path,
param_mode: ParamMode)
param_mode: ParamMode,
defaults_to_global: bool)
-> hir::Path {
self.lower_path_extra(id, p, None, param_mode)
self.lower_path_extra(id, p, None, param_mode, defaults_to_global)
}

fn lower_path_segment(&mut self,
@@ -602,8 +607,8 @@ impl<'a> LoweringContext<'a> {
// Check if the where clause type is a plain type parameter.
match bound_pred.bounded_ty.node {
TyKind::Path(None, ref path)
if !path.global && path.segments.len() == 1 &&
bound_pred.bound_lifetimes.is_empty() => {
if path.segments.len() == 1 &&
bound_pred.bound_lifetimes.is_empty() => {
if let Some(Def::TyParam(def_id)) =
self.resolver.get_resolution(bound_pred.bounded_ty.id)
.map(|d| d.base_def) {
@@ -677,7 +682,7 @@ impl<'a> LoweringContext<'a> {
span}) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
id: id,
path: self.lower_path(id, path, ParamMode::Explicit),
path: self.lower_path(id, path, ParamMode::Explicit, false),
ty: self.lower_ty(ty),
span: span,
})
@@ -707,7 +712,7 @@ impl<'a> LoweringContext<'a> {

fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
hir::TraitRef {
path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit),
path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit, false),
ref_id: p.ref_id,
}
}
@@ -800,7 +805,7 @@ impl<'a> LoweringContext<'a> {
};

let mut path = self.lower_path_extra(import.id, path, suffix,
ParamMode::Explicit);
ParamMode::Explicit, true);
path.span = span;
self.items.insert(import.id, hir::Item {
id: import.id,
@@ -814,7 +819,7 @@ impl<'a> LoweringContext<'a> {
path
}
};
let path = P(self.lower_path(id, path, ParamMode::Explicit));
let path = P(self.lower_path(id, path, ParamMode::Explicit, true));
let kind = match view_path.node {
ViewPathSimple(ident, _) => {
*name = ident.name;
@@ -1135,7 +1140,6 @@ impl<'a> LoweringContext<'a> {
Some(def) => {
hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
span: pth1.span,
global: false,
def: def,
segments: hir_vec![
hir::PathSegment::from_name(pth1.node.name)
@@ -1878,7 +1882,7 @@ impl<'a> LoweringContext<'a> {
Visibility::Crate(_) => hir::Visibility::Crate,
Visibility::Restricted { ref path, id } => {
hir::Visibility::Restricted {
path: P(self.lower_path(id, path, ParamMode::Explicit)),
path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
id: id
}
}
@@ -1971,7 +1975,6 @@ impl<'a> LoweringContext<'a> {

let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
span: span,
global: false,
def: def,
segments: hir_vec![hir::PathSegment::from_name(id)],
})));
@@ -2139,17 +2142,12 @@ impl<'a> LoweringContext<'a> {
/// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
/// The path is also resolved according to `is_value`.
fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
let idents = self.crate_root.iter().chain(components);

let segments: Vec<_> = idents.map(|name| {
hir::PathSegment::from_name(Symbol::intern(name))
}).collect();

let mut path = hir::Path {
span: span,
global: true,
def: Def::Err,
segments: segments.into(),
segments: iter::once(keywords::CrateRoot.name()).chain({
self.crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern)
}).map(hir::PathSegment::from_name).collect(),
};

self.resolver.resolve_hir_path(&mut path, is_value);
9 changes: 6 additions & 3 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -105,15 +105,18 @@ pub struct LifetimeDef {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
pub span: Span,
/// A `::foo` path, is relative to the crate root rather than current
/// module (like paths in an import).
pub global: bool,
/// The definition that the path resolved to.
pub def: Def,
/// The segments in the path: the things separated by `::`.
pub segments: HirVec<PathSegment>,
}

impl Path {
pub fn is_global(&self) -> bool {
!self.segments.is_empty() && self.segments[0].name == keywords::CrateRoot.name()
}
}

impl fmt::Debug for Path {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "path({})", print::path_to_string(self))
28 changes: 12 additions & 16 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
@@ -1643,17 +1643,14 @@ impl<'a> State<'a> {
-> io::Result<()> {
self.maybe_print_comment(path.span.lo)?;

let mut first = !path.global;
for segment in &path.segments {
if first {
first = false
} else {
for (i, segment) in path.segments.iter().enumerate() {
if i > 0 {
word(&mut self.s, "::")?
}

self.print_name(segment.name)?;

self.print_path_parameters(&segment.parameters, colons_before_params)?;
if segment.name != keywords::CrateRoot.name() && segment.name != "$crate" {
self.print_name(segment.name)?;
self.print_path_parameters(&segment.parameters, colons_before_params)?;
}
}

Ok(())
@@ -1673,15 +1670,14 @@ impl<'a> State<'a> {
space(&mut self.s)?;
self.word_space("as")?;

let mut first = !path.global;
for segment in &path.segments[..path.segments.len() - 1] {
if first {
first = false
} else {
for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() {
if i > 0 {
word(&mut self.s, "::")?
}
self.print_name(segment.name)?;
self.print_path_parameters(&segment.parameters, colons_before_params)?;
if segment.name != keywords::CrateRoot.name() && segment.name != "$crate" {
self.print_name(segment.name)?;
self.print_path_parameters(&segment.parameters, colons_before_params)?;
}
}

word(&mut self.s, ">")?;
1 change: 0 additions & 1 deletion src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1620,7 +1620,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
new_segs.push(new_seg);
hir::Path {
span: path.span,
global: path.global,
def: path.def,
segments: new_segs.into()
}
1 change: 0 additions & 1 deletion src/librustc_const_eval/_match.rs
Original file line number Diff line number Diff line change
@@ -324,7 +324,6 @@ impl Witness {
let v = ctor.variant_for_adt(adt);
let qpath = hir::QPath::Resolved(None, P(hir::Path {
span: DUMMY_SP,
global: false,
def: Def::Err,
segments: vec![hir::PathSegment::from_name(v.name)].into(),
}));
2 changes: 0 additions & 2 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
@@ -189,7 +189,6 @@ enum SawAbiComponent<'a> {
SawStructField,
SawVariant,
SawQPath,
SawPath(bool),
SawPathSegment,
SawPathParameters,
SawBlock,
@@ -678,7 +677,6 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has

fn visit_path(&mut self, path: &'tcx Path, _: ast::NodeId) {
debug!("visit_path: st={:?}", self.st);
SawPath(path.global).hash(self.st);
hash_span!(self, path.span);
visit::walk_path(self, path)
}
2 changes: 1 addition & 1 deletion src/librustc_lint/bad_style.rs
Original file line number Diff line number Diff line change
@@ -382,7 +382,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
// Lint for constants that look like binding identifiers (#7526)
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
if path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
if let Def::Const(..) = path.def {
NonUpperCaseGlobals::check_upper_case(cx,
"constant in pattern",
4 changes: 2 additions & 2 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
@@ -154,8 +154,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_path(&mut self, path: &'a Path, id: NodeId) {
if path.global && path.segments.len() > 0 {
let ident = path.segments[0].identifier;
if path.segments.len() >= 2 && path.is_global() {
let ident = path.segments[1].identifier;
if token::Ident(ident).is_path_segment_keyword() {
self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
id,
31 changes: 18 additions & 13 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ use syntax::ext::base::Determinacy::Undetermined;
use syntax::ext::expand::mark_tts;
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::parse::token;
use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};

@@ -112,7 +113,7 @@ impl<'a> Resolver<'a> {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path: Vec<_> = match view_path.node {
let mut module_path: Vec<_> = match view_path.node {
ViewPathSimple(_, ref full_path) => {
full_path.segments
.split_last()
@@ -132,6 +133,12 @@ impl<'a> Resolver<'a> {
}
};

// This can be removed once warning cycle #36888 is complete.
if module_path.len() >= 2 && module_path[0].name == keywords::CrateRoot.name() &&
token::Ident(module_path[1]).is_path_segment_keyword() {
module_path.remove(0);
}

// Build up the import directives.
let is_prelude = attr::contains_name(&item.attrs, "prelude_import");

@@ -193,18 +200,16 @@ impl<'a> Resolver<'a> {
let rename = node.rename.unwrap_or(node.name);
(module_path.clone(), node.name, rename)
} else {
let ident = match module_path.last() {
Some(&ident) => ident,
None => {
resolve_error(
self,
source_item.span,
ResolutionError::
SelfImportOnlyInImportListWithNonEmptyPrefix
);
continue;
}
};
let ident = *module_path.last().unwrap();
if ident.name == keywords::CrateRoot.name() {
resolve_error(
self,
source_item.span,
ResolutionError::
SelfImportOnlyInImportListWithNonEmptyPrefix
);
continue;
}
let module_path = module_path.split_last().unwrap().1;
let rename = node.rename.unwrap_or(ident);
(module_path.to_vec(), ident, rename)
Loading