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

Refactor global paths #38232

Merged
merged 2 commits into from
Dec 23, 2016
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
})
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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)],
})));
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
28 changes: 12 additions & 16 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand All @@ -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, ">")?;
Expand Down
1 change: 0 additions & 1 deletion src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc_const_eval/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}));
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ enum SawAbiComponent<'a> {
SawStructField,
SawVariant,
SawQPath,
SawPath(bool),
SawPathSegment,
SawPathParameters,
SawBlock,
Expand Down Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/bad_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
31 changes: 18 additions & 13 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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()
Expand All @@ -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");

Expand Down Expand Up @@ -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)
Expand Down
Loading