Skip to content

Commit 0b399e5

Browse files
authored
Auto merge of #37676 - eddyb:lazy-7, r=nikomatsakis
[7/n] rustc: desugar UFCS in HIR and don't use DefMap for associated resolutions. _This is part of a series ([prev](#37412) | [next](#37688)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> Previously, a path like `T::Assoc::method`, while equivalent to `<<T>::Assoc>::method`, wasn't desugared in any way at the HIR level and everything inspecting it had to either deal with knowing only `T` (before typeck) or knowing only the definition of `method` (after typeck). Such a path also had only one `NodeId` and associated resolution during typeck modified `DefMap`, in a way that would be hard for incremental recompilation to track, and inconvenient for partial type conversions from HIR to `Ty`, which are required to break faux-cycles in on-demand type collection. The desugarings performed by this PR are as follows: * `use a::{b,c};` is flattened to `use a as _; use a::b; use a::c;` * as resolution is complete, `use a as _;` doesn't do anything, except get checked for stability * `Vec::new` (an expression) becomes `Vec<..>::new<..>`, to distinguish it from `<Vec>::new<..>` * the "infer all parameters" `<..>` form is internal and not even pretty-printed * used when there are no type parameters at all, in an expression or pattern path segment * `T::A::B` becomes `<<T>::A>::B` in a type, and `<<T<..>>::A<..>>::B<..>` in an expression/pattern * one additional `hir::Ty` node is created for each prefix, starting with the fully-resolved type (`T`) and extending it with each segment (e.g. `<T>::A`) * fully-resolved paths contain their `Def` in HIR, getting rid of the `DefMap` and absolving incremental recompilation of needing to manually look up nodes to handle that side information Not keeping the `DefMap` around meant that associated resolutions had to be stored somewhere else: * expressions and patterns use a new `NodeId -> Def` map in `ty::Tables` * compatible with the future per-body (constant / `fn` / closure) `Tables` * types are accessible via `Ty` and the usual per-item generics / predicates / type * `rustdoc` and `save-analysis` are the only situations which insist on mapping syntactical types to semantical ones, or at least understand the resolution of associated types, therefore the type conversion cache, i.e. a `NodeId -> Ty` map, is exposed by typeck for this purpose * stability had to be split into a pass that runs on HIR and checks the results of name resolution, and impromptu checks triggered by `typeck` for associated paths, methods, fields, etc. * privacy using semantic types results in accurate reachability for `impl Trait`, which fixes #35870, and thorough introspection of associated types, which may allow relaxing private-in-public checking on bounds, while keeping the intended ban on projections with private type parameters cc @petrochenkov
2 parents c7ddb89 + 372c6df commit 0b399e5

File tree

179 files changed

+4149
-3105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+4149
-3105
lines changed

src/etc/generate-deriving-span-tests.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
3838
// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
3939
40-
extern crate rand;
41-
4240
{error_deriving}
4341
struct Error;
4442
{code}
@@ -106,7 +104,6 @@ def write_file(name, string):
106104
ALL = STRUCT | ENUM
107105

108106
traits = {
109-
'Zero': (STRUCT, [], 1),
110107
'Default': (STRUCT, [], 1),
111108
'FromPrimitive': (0, [], 0), # only works for C-like enums
112109

@@ -116,7 +113,7 @@ def write_file(name, string):
116113

117114
for (trait, supers, errs) in [('Clone', [], 1),
118115
('PartialEq', [], 2),
119-
('PartialOrd', ['PartialEq'], 8),
116+
('PartialOrd', ['PartialEq'], 9),
120117
('Eq', ['PartialEq'], 1),
121118
('Ord', ['Eq', 'PartialOrd', 'PartialEq'], 1),
122119
('Debug', [], 1),

src/librustc/cfg/construct.rs

+11-20
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
use rustc_data_structures::graph;
1212
use cfg::*;
13-
use hir::def::Def;
14-
use hir::pat_util;
1513
use ty::{self, TyCtxt};
1614
use syntax::ast;
1715
use syntax::ptr::P;
@@ -100,7 +98,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
10098
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
10199
match pat.node {
102100
PatKind::Binding(.., None) |
103-
PatKind::Path(..) |
101+
PatKind::Path(_) |
104102
PatKind::Lit(..) |
105103
PatKind::Range(..) |
106104
PatKind::Wild => {
@@ -284,15 +282,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
284282

285283
hir::ExprBreak(label, ref opt_expr) => {
286284
let v = self.opt_expr(opt_expr, pred);
287-
let loop_scope = self.find_scope(expr, label.map(|l| l.node));
285+
let loop_scope = self.find_scope(expr, label);
288286
let b = self.add_ast_node(expr.id, &[v]);
289287
self.add_exiting_edge(expr, b,
290288
loop_scope, loop_scope.break_index);
291289
self.add_unreachable_node()
292290
}
293291

294292
hir::ExprAgain(label) => {
295-
let loop_scope = self.find_scope(expr, label.map(|l| l.node));
293+
let loop_scope = self.find_scope(expr, label);
296294
let a = self.add_ast_node(expr.id, &[pred]);
297295
self.add_exiting_edge(expr, a,
298296
loop_scope, loop_scope.continue_index);
@@ -361,7 +359,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
361359

362360
hir::ExprClosure(..) |
363361
hir::ExprLit(..) |
364-
hir::ExprPath(..) => {
362+
hir::ExprPath(_) => {
365363
self.straightline(expr, pred, None::<hir::Expr>.iter())
366364
}
367365
}
@@ -457,7 +455,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
457455
// Visit the guard expression
458456
let guard_exit = self.expr(&guard, guard_start);
459457

460-
let this_has_bindings = pat_util::pat_contains_bindings_or_wild(&pat);
458+
let this_has_bindings = pat.contains_bindings_or_wild();
461459

462460
// If both this pattern and the previous pattern
463461
// were free of bindings, they must consist only
@@ -570,23 +568,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
570568

571569
fn find_scope(&self,
572570
expr: &hir::Expr,
573-
label: Option<ast::Name>) -> LoopScope {
574-
if label.is_none() {
575-
return *self.loop_scopes.last().unwrap();
576-
}
577-
578-
match self.tcx.expect_def(expr.id) {
579-
Def::Label(loop_id) => {
571+
label: Option<hir::Label>) -> LoopScope {
572+
match label {
573+
None => *self.loop_scopes.last().unwrap(),
574+
Some(label) => {
580575
for l in &self.loop_scopes {
581-
if l.loop_id == loop_id {
576+
if l.loop_id == label.loop_id {
582577
return *l;
583578
}
584579
}
585-
span_bug!(expr.span, "no loop scope for id {}", loop_id);
586-
}
587-
588-
r => {
589-
span_bug!(expr.span, "bad entry `{:?}` in def_map for label", r);
580+
span_bug!(expr.span, "no loop scope for id {}", label.loop_id);
590581
}
591582
}
592583
}

src/librustc/dep_graph/dep_node.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub enum DepNode<D: Clone + Debug> {
9090
RvalueCheck(D),
9191
Reachability,
9292
DeadCheck,
93-
StabilityCheck,
93+
StabilityCheck(D),
9494
LateLintCheck,
9595
TransCrate,
9696
TransCrateItem(D),
@@ -189,7 +189,6 @@ impl<D: Clone + Debug> DepNode<D> {
189189
Privacy => Some(Privacy),
190190
Reachability => Some(Reachability),
191191
DeadCheck => Some(DeadCheck),
192-
StabilityCheck => Some(StabilityCheck),
193192
LateLintCheck => Some(LateLintCheck),
194193
TransCrate => Some(TransCrate),
195194
TransWriteMetadata => Some(TransWriteMetadata),
@@ -217,6 +216,7 @@ impl<D: Clone + Debug> DepNode<D> {
217216
Mir(ref d) => op(d).map(Mir),
218217
BorrowCheck(ref d) => op(d).map(BorrowCheck),
219218
RvalueCheck(ref d) => op(d).map(RvalueCheck),
219+
StabilityCheck(ref d) => op(d).map(StabilityCheck),
220220
TransCrateItem(ref d) => op(d).map(TransCrateItem),
221221
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
222222
AssociatedItems(ref d) => op(d).map(AssociatedItems),

src/librustc/hir/def.rs

-8
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,6 @@ impl PathResolution {
8383
PathResolution { base_def: def, depth: 0 }
8484
}
8585

86-
/// Get the definition, if fully resolved, otherwise panic.
87-
pub fn full_def(&self) -> Def {
88-
if self.depth != 0 {
89-
bug!("path not fully resolved: {:?}", self);
90-
}
91-
self.base_def
92-
}
93-
9486
pub fn kind_name(&self) -> &'static str {
9587
if self.depth != 0 {
9688
"associated item"

src/librustc/hir/intravisit.rs

+49-53
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
3838
use syntax::codemap::Spanned;
3939
use syntax_pos::Span;
4040
use hir::*;
41+
use hir::def::Def;
4142
use hir::map::Map;
4243
use super::itemlikevisit::DeepVisitor;
4344

@@ -155,6 +156,9 @@ pub trait Visitor<'v> : Sized {
155156
fn visit_id(&mut self, _node_id: NodeId) {
156157
// Nothing to do.
157158
}
159+
fn visit_def_mention(&mut self, _def: Def) {
160+
// Nothing to do.
161+
}
158162
fn visit_name(&mut self, _span: Span, _name: Name) {
159163
// Nothing to do.
160164
}
@@ -244,12 +248,12 @@ pub trait Visitor<'v> : Sized {
244248
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
245249
walk_lifetime_def(self, lifetime)
246250
}
251+
fn visit_qpath(&mut self, qpath: &'v QPath, id: NodeId, span: Span) {
252+
walk_qpath(self, qpath, id, span)
253+
}
247254
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
248255
walk_path(self, path)
249256
}
250-
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
251-
walk_path_list_item(self, prefix, item)
252-
}
253257
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
254258
walk_path_segment(self, path_span, path_segment)
255259
}
@@ -349,23 +353,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
349353
visitor.visit_id(item.id);
350354
walk_opt_name(visitor, item.span, opt_name)
351355
}
352-
ItemUse(ref vp) => {
356+
ItemUse(ref path, _) => {
353357
visitor.visit_id(item.id);
354-
match vp.node {
355-
ViewPathSimple(name, ref path) => {
356-
visitor.visit_name(vp.span, name);
357-
visitor.visit_path(path, item.id);
358-
}
359-
ViewPathGlob(ref path) => {
360-
visitor.visit_path(path, item.id);
361-
}
362-
ViewPathList(ref prefix, ref list) => {
363-
visitor.visit_path(prefix, item.id);
364-
for item in list {
365-
visitor.visit_path_list_item(prefix, item)
366-
}
367-
}
368-
}
358+
visitor.visit_path(path, item.id);
369359
}
370360
ItemStatic(ref typ, _, ref expr) |
371361
ItemConst(ref typ, ref expr) => {
@@ -481,11 +471,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
481471
walk_fn_decl(visitor, &function_declaration.decl);
482472
walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
483473
}
484-
TyPath(ref maybe_qself, ref path) => {
485-
if let Some(ref qself) = *maybe_qself {
486-
visitor.visit_ty(&qself.ty);
487-
}
488-
visitor.visit_path(path, typ.id);
474+
TyPath(ref qpath) => {
475+
visitor.visit_qpath(qpath, typ.id, typ.span);
489476
}
490477
TyObjectSum(ref ty, ref bounds) => {
491478
visitor.visit_ty(ty);
@@ -508,20 +495,28 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
508495
}
509496
}
510497

498+
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath, id: NodeId, span: Span) {
499+
match *qpath {
500+
QPath::Resolved(ref maybe_qself, ref path) => {
501+
if let Some(ref qself) = *maybe_qself {
502+
visitor.visit_ty(qself);
503+
}
504+
visitor.visit_path(path, id)
505+
}
506+
QPath::TypeRelative(ref qself, ref segment) => {
507+
visitor.visit_ty(qself);
508+
visitor.visit_path_segment(span, segment);
509+
}
510+
}
511+
}
512+
511513
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
514+
visitor.visit_def_mention(path.def);
512515
for segment in &path.segments {
513516
visitor.visit_path_segment(path.span, segment);
514517
}
515518
}
516519

517-
pub fn walk_path_list_item<'v, V>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem)
518-
where V: Visitor<'v>,
519-
{
520-
visitor.visit_id(item.node.id);
521-
visitor.visit_name(item.span, item.node.name);
522-
walk_opt_name(visitor, item.span, item.node.rename);
523-
}
524-
525520
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
526521
path_span: Span,
527522
segment: &'v PathSegment) {
@@ -555,18 +550,15 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
555550
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
556551
visitor.visit_id(pattern.id);
557552
match pattern.node {
558-
PatKind::TupleStruct(ref path, ref children, _) => {
559-
visitor.visit_path(path, pattern.id);
553+
PatKind::TupleStruct(ref qpath, ref children, _) => {
554+
visitor.visit_qpath(qpath, pattern.id, pattern.span);
560555
walk_list!(visitor, visit_pat, children);
561556
}
562-
PatKind::Path(ref opt_qself, ref path) => {
563-
if let Some(ref qself) = *opt_qself {
564-
visitor.visit_ty(&qself.ty);
565-
}
566-
visitor.visit_path(path, pattern.id)
557+
PatKind::Path(ref qpath) => {
558+
visitor.visit_qpath(qpath, pattern.id, pattern.span);
567559
}
568-
PatKind::Struct(ref path, ref fields, _) => {
569-
visitor.visit_path(path, pattern.id);
560+
PatKind::Struct(ref qpath, ref fields, _) => {
561+
visitor.visit_qpath(qpath, pattern.id, pattern.span);
570562
for field in fields {
571563
visitor.visit_name(field.span, field.node.name);
572564
visitor.visit_pat(&field.node.pat)
@@ -579,7 +571,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
579571
PatKind::Ref(ref subpattern, _) => {
580572
visitor.visit_pat(subpattern)
581573
}
582-
PatKind::Binding(_, ref pth1, ref optional_subpattern) => {
574+
PatKind::Binding(_, def_id, ref pth1, ref optional_subpattern) => {
575+
visitor.visit_def_mention(Def::Local(def_id));
583576
visitor.visit_name(pth1.span, pth1.node);
584577
walk_list!(visitor, visit_pat, optional_subpattern);
585578
}
@@ -840,8 +833,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
840833
visitor.visit_expr(element);
841834
visitor.visit_expr(count)
842835
}
843-
ExprStruct(ref path, ref fields, ref optional_base) => {
844-
visitor.visit_path(path, expression.id);
836+
ExprStruct(ref qpath, ref fields, ref optional_base) => {
837+
visitor.visit_qpath(qpath, expression.id, expression.span);
845838
for field in fields {
846839
visitor.visit_name(field.name.span, field.name.node);
847840
visitor.visit_expr(&field.expr)
@@ -917,18 +910,21 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
917910
visitor.visit_expr(main_expression);
918911
visitor.visit_expr(index_expression)
919912
}
920-
ExprPath(ref maybe_qself, ref path) => {
921-
if let Some(ref qself) = *maybe_qself {
922-
visitor.visit_ty(&qself.ty);
923-
}
924-
visitor.visit_path(path, expression.id)
913+
ExprPath(ref qpath) => {
914+
visitor.visit_qpath(qpath, expression.id, expression.span);
925915
}
926-
ExprBreak(ref opt_sp_name, ref opt_expr) => {
927-
walk_opt_sp_name(visitor, opt_sp_name);
916+
ExprBreak(None, ref opt_expr) => {
928917
walk_list!(visitor, visit_expr, opt_expr);
929918
}
930-
ExprAgain(ref opt_sp_name) => {
931-
walk_opt_sp_name(visitor, opt_sp_name);
919+
ExprBreak(Some(label), ref opt_expr) => {
920+
visitor.visit_def_mention(Def::Label(label.loop_id));
921+
visitor.visit_name(label.span, label.name);
922+
walk_list!(visitor, visit_expr, opt_expr);
923+
}
924+
ExprAgain(None) => {}
925+
ExprAgain(Some(label)) => {
926+
visitor.visit_def_mention(Def::Label(label.loop_id));
927+
visitor.visit_name(label.span, label.name);
932928
}
933929
ExprRet(ref optional_expression) => {
934930
walk_list!(visitor, visit_expr, optional_expression);

0 commit comments

Comments
 (0)