Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
59cb1705
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
59cb1705
编写于
9月 12, 2018
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rebasing and reviewer changes
Primarily refactoring `(Ident, Option<NodeId>)` to `Segment`
上级
8ac32726
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
157 addition
and
133 deletion
+157
-133
src/librustc/hir/lowering.rs
src/librustc/hir/lowering.rs
+0
-1
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/build_reduced_graph.rs
+34
-39
src/librustc_resolve/error_reporting.rs
src/librustc_resolve/error_reporting.rs
+17
-19
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+81
-48
src/librustc_resolve/macros.rs
src/librustc_resolve/macros.rs
+12
-14
src/librustc_resolve/resolve_imports.rs
src/librustc_resolve/resolve_imports.rs
+12
-11
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+1
-1
未找到文件。
src/librustc/hir/lowering.rs
浏览文件 @
59cb1705
...
...
@@ -1385,7 +1385,6 @@ fn lower_existential_impl_trait(
// does not actually exist in the AST.
lctx
.items
.insert
(
exist_ty_id
.node_id
,
exist_ty_item
);
let
def
=
Def
::
Existential
(
DefId
::
local
(
exist_ty_def_index
));
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`
hir
::
TyKind
::
Def
(
hir
::
ItemId
{
id
:
exist_ty_id
.node_id
},
lifetimes
)
})
...
...
src/librustc_resolve/build_reduced_graph.rs
浏览文件 @
59cb1705
...
...
@@ -16,7 +16,7 @@
use
macros
::{
InvocationData
,
ParentScope
,
LegacyScope
};
use
resolve_imports
::
ImportDirective
;
use
resolve_imports
::
ImportDirectiveSubclass
::{
self
,
GlobImport
,
SingleImport
};
use
{
Module
,
ModuleData
,
ModuleKind
,
NameBinding
,
NameBindingKind
,
ToNameBinding
};
use
{
Module
,
ModuleData
,
ModuleKind
,
NameBinding
,
NameBindingKind
,
Segment
,
ToNameBinding
};
use
{
ModuleOrUniformRoot
,
PerNS
,
Resolver
,
ResolverArenas
,
ExternPreludeEntry
};
use
Namespace
::{
self
,
TypeNS
,
ValueNS
,
MacroNS
};
use
{
resolve_error
,
resolve_struct_error
,
ResolutionError
};
...
...
@@ -122,7 +122,7 @@ fn build_reduced_graph_for_use_tree(
use_tree
:
&
ast
::
UseTree
,
id
:
NodeId
,
vis
:
ty
::
Visibility
,
parent_prefix
:
&
[
Id
ent
],
parent_prefix
:
&
[
Segm
ent
],
mut
uniform_paths_canary_emitted
:
bool
,
nested
:
bool
,
item
:
&
Item
,
...
...
@@ -139,10 +139,10 @@ fn build_reduced_graph_for_use_tree(
self
.session
.features_untracked
()
.uniform_paths
;
let
prefix_iter
=
||
parent_prefix
.iter
()
.cloned
()
.chain
(
use_tree
.prefix.segments
.iter
()
.map
(|
seg
|
seg
.i
dent
));
.chain
(
use_tree
.prefix.segments
.iter
()
.map
(|
seg
|
seg
.i
nto
()
));
let
prefix_start
=
prefix_iter
()
.next
();
let
starts_with_non_keyword
=
prefix_start
.map_or
(
false
,
|
(
ident
,
_
)
|
{
!
ident
.is_path_segment_keyword
()
let
starts_with_non_keyword
=
prefix_start
.map_or
(
false
,
|
seg
|
{
!
seg
.
ident
.is_path_segment_keyword
()
});
// Imports are resolved as global by default, prepend `CrateRoot`,
...
...
@@ -156,7 +156,7 @@ fn build_reduced_graph_for_use_tree(
};
let
root
=
if
inject_crate_root
{
let
span
=
use_tree
.prefix.span
.shrink_to_lo
();
Some
(
Ident
::
new
(
keywords
::
CrateRoot
.name
(),
span
))
Some
(
Segment
::
from_ident
(
Ident
::
new
(
keywords
::
CrateRoot
.name
(),
span
)
))
}
else
{
None
};
...
...
@@ -202,13 +202,13 @@ fn build_reduced_graph_for_use_tree(
let
source
=
prefix_start
.unwrap
();
// Helper closure to emit a canary with the given base path.
let
emit
=
|
this
:
&
mut
Self
,
base
:
Option
<
(
Ident
,
Option
<
NodeId
>
)
>
|
{
let
emit
=
|
this
:
&
mut
Self
,
base
:
Option
<
Segment
>
|
{
let
subclass
=
SingleImport
{
target
:
Ident
{
name
:
keywords
::
Underscore
.name
()
.gensymed
(),
span
:
source
.
0
.span
,
span
:
source
.
ident
.span
,
},
source
:
source
.
0
,
source
:
source
.
ident
,
result
:
PerNS
{
type_ns
:
Cell
::
new
(
Err
(
Undetermined
)),
value_ns
:
Cell
::
new
(
Err
(
Undetermined
)),
...
...
@@ -219,7 +219,7 @@ fn build_reduced_graph_for_use_tree(
this
.add_import_directive
(
base
.into_iter
()
.collect
(),
subclass
.clone
(),
source
.
0
.span
,
source
.
ident
.span
,
id
,
root_use_tree
.span
,
root_id
,
...
...
@@ -230,15 +230,18 @@ fn build_reduced_graph_for_use_tree(
};
// A single simple `self::x` canary.
emit
(
self
,
Some
((
Ident
{
name
:
keywords
::
SelfValue
.name
(),
span
:
source
.0
.span
,
},
source
.1
)));
emit
(
self
,
Some
(
Segment
{
ident
:
Ident
{
name
:
keywords
::
SelfValue
.name
(),
span
:
source
.ident.span
,
},
id
:
source
.id
}));
// One special unprefixed canary per block scope around
// the import, to detect items unreachable by `self::x`.
let
orig_current_module
=
self
.current_module
;
let
mut
span
=
source
.
0
.span
.modern
();
let
mut
span
=
source
.
ident
.span
.modern
();
loop
{
match
self
.current_module.kind
{
ModuleKind
::
Block
(
..
)
=>
emit
(
self
,
None
),
...
...
@@ -265,11 +268,11 @@ fn build_reduced_graph_for_use_tree(
if
nested
{
// Correctly handle `self`
if
source
.
0
.name
==
keywords
::
SelfValue
.name
()
{
if
source
.
ident
.name
==
keywords
::
SelfValue
.name
()
{
type_ns_only
=
true
;
let
empty_prefix
=
module_path
.last
()
.map_or
(
true
,
|
(
ident
,
_
)
|
{
ident
.name
==
keywords
::
CrateRoot
.name
()
let
empty_prefix
=
module_path
.last
()
.map_or
(
true
,
|
seg
|
{
seg
.
ident.name
==
keywords
::
CrateRoot
.name
()
});
if
empty_prefix
{
resolve_error
(
...
...
@@ -284,20 +287,20 @@ fn build_reduced_graph_for_use_tree(
// Replace `use foo::self;` with `use foo;`
source
=
module_path
.pop
()
.unwrap
();
if
rename
.is_none
()
{
ident
=
source
.
0
;
ident
=
source
.
ident
;
}
}
}
else
{
// Disallow `self`
if
source
.
0
.name
==
keywords
::
SelfValue
.name
()
{
if
source
.
ident
.name
==
keywords
::
SelfValue
.name
()
{
resolve_error
(
self
,
use_tree
.span
,
ResolutionError
::
SelfImportsOnlyAllowedWithin
);
}
// Disallow `use $crate;`
if
source
.
0
.name
==
keywords
::
DollarCrate
.name
()
&&
module_path
.is_empty
()
{
let
crate_root
=
self
.resolve_crate_root
(
source
.
0
);
if
source
.
ident
.name
==
keywords
::
DollarCrate
.name
()
&&
module_path
.is_empty
()
{
let
crate_root
=
self
.resolve_crate_root
(
source
.
ident
);
let
crate_name
=
match
crate_root
.kind
{
ModuleKind
::
Def
(
_
,
name
)
=>
name
,
ModuleKind
::
Block
(
..
)
=>
unreachable!
(),
...
...
@@ -307,11 +310,14 @@ fn build_reduced_graph_for_use_tree(
// while the current crate doesn't have a valid `crate_name`.
if
crate_name
!=
keywords
::
Invalid
.name
()
{
// `crate_name` should not be interpreted as relative.
module_path
.push
((
Ident
{
name
:
keywords
::
CrateRoot
.name
(),
span
:
source
.0
.span
,
},
Some
(
self
.session
.next_node_id
())));
source
.0
.name
=
crate_name
;
module_path
.push
(
Segment
{
ident
:
Ident
{
name
:
keywords
::
CrateRoot
.name
(),
span
:
source
.ident.span
,
},
id
:
Some
(
self
.session
.next_node_id
()),
});
source
.ident.name
=
crate_name
;
}
if
rename
.is_none
()
{
ident
.name
=
crate_name
;
...
...
@@ -332,7 +338,7 @@ fn build_reduced_graph_for_use_tree(
let
subclass
=
SingleImport
{
target
:
ident
,
source
:
source
.
0
,
source
:
source
.
ident
,
result
:
PerNS
{
type_ns
:
Cell
::
new
(
Err
(
Undetermined
)),
value_ns
:
Cell
::
new
(
Err
(
Undetermined
)),
...
...
@@ -392,17 +398,6 @@ fn build_reduced_graph_for_use_tree(
e
.emit
();
}
let
prefix
=
ast
::
Path
{
segments
:
module_path
.into_iter
()
.map
(|(
ident
,
id
)|
{
let
mut
seg
=
ast
::
PathSegment
::
from_ident
(
ident
);
seg
.id
=
id
.expect
(
"Missing node id"
);
seg
})
.collect
(),
span
:
path
.span
,
};
for
&
(
ref
tree
,
id
)
in
items
{
self
.build_reduced_graph_for_use_tree
(
root_use_tree
,
...
...
src/librustc_resolve/error_reporting.rs
浏览文件 @
59cb1705
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
{
CrateLint
,
PathResult
};
use
{
CrateLint
,
PathResult
,
Segment
};
use
std
::
collections
::
BTreeSet
;
...
...
@@ -23,8 +23,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
pub
(
crate
)
fn
make_path_suggestion
(
&
mut
self
,
span
:
Span
,
path
:
Vec
<
Id
ent
>
)
->
Option
<
Vec
<
Id
ent
>>
{
path
:
Vec
<
Segm
ent
>
)
->
Option
<
Vec
<
Segm
ent
>>
{
debug!
(
"make_path_suggestion: span={:?} path={:?}"
,
span
,
path
);
// If we don't have a path to suggest changes to, then return.
if
path
.is_empty
()
{
...
...
@@ -37,13 +37,13 @@ pub(crate) fn make_path_suggestion(
match
(
path
.get
(
0
),
path
.get
(
1
))
{
// Make suggestions that require at least two non-special path segments.
(
Some
(
fst
),
Some
(
snd
))
if
!
is_special
(
*
fst
)
&&
!
is_special
(
*
snd
)
=>
{
(
Some
(
fst
),
Some
(
snd
))
if
!
is_special
(
fst
.ident
)
&&
!
is_special
(
snd
.ident
)
=>
{
debug!
(
"make_path_suggestion: fst={:?} snd={:?}"
,
fst
,
snd
);
self
.make_missing_self_suggestion
(
span
,
path
.clone
())
.or_else
(||
self
.make_missing_crate_suggestion
(
span
,
path
.clone
()))
.or_else
(||
self
.make_missing_super_suggestion
(
span
,
path
.clone
()))
.or_else
(||
self
.make_external_crate_suggestion
(
span
,
path
.clone
()
))
.or_else
(||
self
.make_external_crate_suggestion
(
span
,
path
))
},
_
=>
None
,
}
...
...
@@ -59,10 +59,10 @@ pub(crate) fn make_path_suggestion(
fn
make_missing_self_suggestion
(
&
mut
self
,
span
:
Span
,
mut
path
:
Vec
<
Id
ent
>
)
->
Option
<
Vec
<
Id
ent
>>
{
mut
path
:
Vec
<
Segm
ent
>
)
->
Option
<
Vec
<
Segm
ent
>>
{
// Replace first ident with `self` and check if that is valid.
path
[
0
]
.name
=
keywords
::
SelfValue
.name
();
path
[
0
]
.
ident.
name
=
keywords
::
SelfValue
.name
();
let
result
=
self
.resolve_path
(
None
,
&
path
,
None
,
false
,
span
,
CrateLint
::
No
);
debug!
(
"make_missing_self_suggestion: path={:?} result={:?}"
,
path
,
result
);
if
let
PathResult
::
Module
(
..
)
=
result
{
...
...
@@ -82,10 +82,10 @@ fn make_missing_self_suggestion(
fn
make_missing_crate_suggestion
(
&
mut
self
,
span
:
Span
,
mut
path
:
Vec
<
Id
ent
>
)
->
Option
<
Vec
<
Id
ent
>>
{
mut
path
:
Vec
<
Segm
ent
>
)
->
Option
<
Vec
<
Segm
ent
>>
{
// Replace first ident with `crate` and check if that is valid.
path
[
0
]
.name
=
keywords
::
Crate
.name
();
path
[
0
]
.
ident.
name
=
keywords
::
Crate
.name
();
let
result
=
self
.resolve_path
(
None
,
&
path
,
None
,
false
,
span
,
CrateLint
::
No
);
debug!
(
"make_missing_crate_suggestion: path={:?} result={:?}"
,
path
,
result
);
if
let
PathResult
::
Module
(
..
)
=
result
{
...
...
@@ -105,10 +105,10 @@ fn make_missing_crate_suggestion(
fn
make_missing_super_suggestion
(
&
mut
self
,
span
:
Span
,
mut
path
:
Vec
<
Id
ent
>
)
->
Option
<
Vec
<
Id
ent
>>
{
mut
path
:
Vec
<
Segm
ent
>
)
->
Option
<
Vec
<
Segm
ent
>>
{
// Replace first ident with `crate` and check if that is valid.
path
[
0
]
.name
=
keywords
::
Super
.name
();
path
[
0
]
.
ident.
name
=
keywords
::
Super
.name
();
let
result
=
self
.resolve_path
(
None
,
&
path
,
None
,
false
,
span
,
CrateLint
::
No
);
debug!
(
"make_missing_super_suggestion: path={:?} result={:?}"
,
path
,
result
);
if
let
PathResult
::
Module
(
..
)
=
result
{
...
...
@@ -131,8 +131,8 @@ fn make_missing_super_suggestion(
fn
make_external_crate_suggestion
(
&
mut
self
,
span
:
Span
,
mut
path
:
Vec
<
Id
ent
>
)
->
Option
<
Vec
<
Id
ent
>>
{
mut
path
:
Vec
<
Segm
ent
>
)
->
Option
<
Vec
<
Segm
ent
>>
{
// Need to clone else we can't call `resolve_path` without a borrow error. We also store
// into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic)
// each time.
...
...
@@ -148,7 +148,7 @@ fn make_external_crate_suggestion(
for
name
in
external_crate_names
.iter
()
.rev
()
{
// Replace the first after root (a placeholder we inserted) with a crate name
// and check if that is valid.
path
[
1
]
.name
=
*
name
;
path
[
1
]
.
ident.
name
=
*
name
;
let
result
=
self
.resolve_path
(
None
,
&
path
,
None
,
false
,
span
,
CrateLint
::
No
);
debug!
(
"make_external_crate_suggestion: name={:?} path={:?} result={:?}"
,
name
,
path
,
result
);
...
...
@@ -157,8 +157,6 @@ fn make_external_crate_suggestion(
}
}
// Remove our placeholder segment.
path
.remove
(
1
);
None
}
}
src/librustc_resolve/lib.rs
浏览文件 @
59cb1705
...
...
@@ -632,6 +632,43 @@ fn error_code(self, has_unexpected_resolution: bool) -> &'static str {
}
}
// A minimal representation of a path segment. We use this in resolve because
// we synthesize 'path segments' which don't have the rest of an AST or HIR
// PathSegment.
#[derive(Clone,
Copy,
Debug)]
pub
struct
Segment
{
ident
:
Ident
,
id
:
Option
<
NodeId
>
,
}
impl
Segment
{
fn
from_path
(
path
:
&
Path
)
->
Vec
<
Segment
>
{
path
.segments
.iter
()
.map
(|
s
|
s
.into
())
.collect
()
}
fn
from_ident
(
ident
:
Ident
)
->
Segment
{
Segment
{
ident
,
id
:
None
,
}
}
fn
names_to_string
(
segments
:
&
[
Segment
])
->
String
{
names_to_string
(
&
segments
.iter
()
.map
(|
seg
|
seg
.ident
)
.collect
::
<
Vec
<
_
>>
())
}
}
impl
<
'a
>
From
<&
'a
ast
::
PathSegment
>
for
Segment
{
fn
from
(
seg
:
&
'a
ast
::
PathSegment
)
->
Segment
{
Segment
{
ident
:
seg
.ident
,
id
:
Some
(
seg
.id
),
}
}
}
struct
UsePlacementFinder
{
target_module
:
NodeId
,
span
:
Option
<
Span
>
,
...
...
@@ -1632,7 +1669,7 @@ fn resolve_hir_path_cb<F>(
let
namespace
=
if
is_value
{
ValueNS
}
else
{
TypeNS
};
let
span
=
path
.span
;
let
segments
=
&
path
.segments
;
let
path
:
Vec
<
_
>
=
segments
.iter
()
.map
(|
seg
|
(
seg
.ident
,
Some
(
seg
.id
)))
.collect
(
);
let
path
=
Segment
::
from_path
(
&
path
);
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
let
def
=
match
self
.resolve_path
(
None
,
&
path
,
Some
(
namespace
),
true
,
span
,
CrateLint
::
No
)
{
PathResult
::
Module
(
ModuleOrUniformRoot
::
Module
(
module
))
=>
...
...
@@ -2482,9 +2519,7 @@ fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f:
let
mut
new_val
=
None
;
let
mut
new_id
=
None
;
if
let
Some
(
trait_ref
)
=
opt_trait_ref
{
let
path
:
Vec
<
_
>
=
trait_ref
.path.segments
.iter
()
.map
(|
seg
|
(
seg
.ident
,
Some
(
seg
.id
)))
.collect
();
let
path
:
Vec
<
_
>
=
Segment
::
from_path
(
&
trait_ref
.path
);
let
def
=
self
.smart_resolve_path_fragment
(
trait_ref
.ref_id
,
None
,
...
...
@@ -2980,21 +3015,25 @@ fn smart_resolve_path_with_crate_lint(
source
:
PathSource
,
crate_lint
:
CrateLint
)
->
PathResolution
{
let
segments
=
&
path
.segments
.iter
()
.map
(|
seg
|
(
seg
.ident
,
Some
(
seg
.id
)))
.collect
::
<
Vec
<
_
>>
();
self
.smart_resolve_path_fragment
(
id
,
qself
,
segments
,
path
.span
,
source
,
crate_lint
)
self
.smart_resolve_path_fragment
(
id
,
qself
,
&
Segment
::
from_path
(
path
),
path
.span
,
source
,
crate_lint
,
)
}
fn
smart_resolve_path_fragment
(
&
mut
self
,
id
:
NodeId
,
qself
:
Option
<&
QSelf
>
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
span
:
Span
,
source
:
PathSource
,
crate_lint
:
CrateLint
)
->
PathResolution
{
let
ident_span
=
path
.last
()
.map_or
(
span
,
|
ident
|
ident
.
0
.span
);
let
ident_span
=
path
.last
()
.map_or
(
span
,
|
ident
|
ident
.
ident
.span
);
let
ns
=
source
.namespace
();
let
is_expected
=
&
|
def
|
source
.is_expected
(
def
);
let
is_enum_variant
=
&
|
def
|
if
let
Def
::
Variant
(
..
)
=
def
{
true
}
else
{
false
};
...
...
@@ -3004,17 +3043,17 @@ fn smart_resolve_path_fragment(&mut self,
// Make the base error.
let
expected
=
source
.descr_expected
();
let
path_str
=
names_to_string
(
path
);
let
item_str
=
path
.last
()
.unwrap
()
.
0
;
let
item_str
=
path
.last
()
.unwrap
()
.
ident
;
let
code
=
source
.error_code
(
def
.is_some
());
let
(
base_msg
,
fallback_label
,
base_span
)
=
if
let
Some
(
def
)
=
def
{
(
format!
(
"expected {}, found {} `{}`"
,
expected
,
def
.kind_name
(),
path_str
),
format!
(
"not a {}"
,
expected
),
span
)
}
else
{
let
item_span
=
path
.last
()
.unwrap
()
.
0
.span
;
let
item_span
=
path
.last
()
.unwrap
()
.
ident
.span
;
let
(
mod_prefix
,
mod_str
)
=
if
path
.len
()
==
1
{
(
String
::
new
(),
"this scope"
.to_string
())
}
else
if
path
.len
()
==
2
&&
path
[
0
]
.
0
.name
==
keywords
::
CrateRoot
.name
()
{
}
else
if
path
.len
()
==
2
&&
path
[
0
]
.
ident
.name
==
keywords
::
CrateRoot
.name
()
{
(
String
::
new
(),
"the crate root"
.to_string
())
}
else
{
let
mod_path
=
&
path
[
..
path
.len
()
-
1
];
...
...
@@ -3024,7 +3063,7 @@ fn smart_resolve_path_fragment(&mut self,
module
.def
(),
_
=>
None
,
}
.map_or
(
String
::
new
(),
|
def
|
format!
(
"{} "
,
def
.kind_name
()));
(
mod_prefix
,
format!
(
"`{}`"
,
names_and_id
s_to_string
(
mod_path
)))
(
mod_prefix
,
format!
(
"`{}`"
,
Segment
::
name
s_to_string
(
mod_path
)))
};
(
format!
(
"cannot find {} `{}` in {}{}"
,
expected
,
item_str
,
mod_prefix
,
mod_str
),
format!
(
"not found in {}"
,
mod_str
),
...
...
@@ -3035,7 +3074,7 @@ fn smart_resolve_path_fragment(&mut self,
// Emit help message for fake-self from other languages like `this`(javascript)
if
[
"this"
,
"my"
]
.contains
(
&&*
item_str
.as_str
())
&&
this
.self_value_is_available
(
path
[
0
]
.span
,
span
)
{
&&
this
.self_value_is_available
(
path
[
0
]
.
ident.
span
,
span
)
{
err
.span_suggestion_with_applicability
(
span
,
"did you mean"
,
...
...
@@ -3070,7 +3109,7 @@ fn smart_resolve_path_fragment(&mut self,
}
// Try to lookup the name in more relaxed fashion for better error reporting.
let
ident
=
path
.last
()
.unwrap
()
.
0
;
let
ident
=
path
.last
()
.unwrap
()
.
ident
;
let
candidates
=
this
.lookup_import_candidates
(
ident
.name
,
ns
,
is_expected
);
if
candidates
.is_empty
()
&&
is_expected
(
Def
::
Enum
(
DefId
::
local
(
CRATE_DEF_INDEX
)))
{
let
enum_candidates
=
...
...
@@ -3097,7 +3136,7 @@ fn smart_resolve_path_fragment(&mut self,
}
if
path
.len
()
==
1
&&
this
.self_type_is_available
(
span
)
{
if
let
Some
(
candidate
)
=
this
.lookup_assoc_candidate
(
ident
,
ns
,
is_expected
)
{
let
self_is_available
=
this
.self_value_is_available
(
path
[
0
]
.
0
.span
,
span
);
let
self_is_available
=
this
.self_value_is_available
(
path
[
0
]
.
ident
.span
,
span
);
match
candidate
{
AssocSuggestion
::
Field
=>
{
err
.span_suggestion_with_applicability
(
...
...
@@ -3332,7 +3371,7 @@ fn smart_resolve_path_fragment(&mut self,
// or `<T>::A::B`. If `B` should be resolved in value namespace then
// it needs to be added to the trait map.
if
ns
==
ValueNS
{
let
item_name
=
path
.last
()
.unwrap
()
.
0
;
let
item_name
=
path
.last
()
.unwrap
()
.
ident
;
let
traits
=
self
.get_traits_containing_item
(
item_name
,
ns
);
self
.trait_map
.insert
(
id
,
traits
);
}
...
...
@@ -3402,7 +3441,7 @@ fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool
fn
resolve_qpath_anywhere
(
&
mut
self
,
id
:
NodeId
,
qself
:
Option
<&
QSelf
>
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
primary_ns
:
Namespace
,
span
:
Span
,
defer_to_typeck
:
bool
,
...
...
@@ -3424,10 +3463,10 @@ fn resolve_qpath_anywhere(&mut self,
}
}
if
primary_ns
!=
MacroNS
&&
(
self
.macro_names
.contains
(
&
path
[
0
]
.
0
.modern
())
||
self
.builtin_macros
.get
(
&
path
[
0
]
.
0
.name
)
.cloned
()
(
self
.macro_names
.contains
(
&
path
[
0
]
.
ident
.modern
())
||
self
.builtin_macros
.get
(
&
path
[
0
]
.
ident
.name
)
.cloned
()
.and_then
(
NameBinding
::
macro_kind
)
==
Some
(
MacroKind
::
Bang
)
||
self
.macro_use_prelude
.get
(
&
path
[
0
]
.
0
.name
)
.cloned
()
self
.macro_use_prelude
.get
(
&
path
[
0
]
.
ident
.name
)
.cloned
()
.and_then
(
NameBinding
::
macro_kind
)
==
Some
(
MacroKind
::
Bang
))
{
// Return some dummy definition, it's enough for error reporting.
return
Some
(
...
...
@@ -3441,7 +3480,7 @@ fn resolve_qpath_anywhere(&mut self,
fn
resolve_qpath
(
&
mut
self
,
id
:
NodeId
,
qself
:
Option
<&
QSelf
>
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
ns
:
Namespace
,
span
:
Span
,
global_by_default
:
bool
,
...
...
@@ -3531,8 +3570,8 @@ fn resolve_qpath(&mut self,
PathResult
::
Failed
(
..
)
if
(
ns
==
TypeNS
||
path
.len
()
>
1
)
&&
self
.primitive_type_table.primitive_types
.contains_key
(
&
path
[
0
]
.
0
.name
)
=>
{
let
prim
=
self
.primitive_type_table.primitive_types
[
&
path
[
0
]
.
0
.name
];
.contains_key
(
&
path
[
0
]
.
ident
.name
)
=>
{
let
prim
=
self
.primitive_type_table.primitive_types
[
&
path
[
0
]
.
ident
.name
];
PathResolution
::
with_unresolved_segments
(
Def
::
PrimTy
(
prim
),
path
.len
()
-
1
)
}
PathResult
::
Module
(
ModuleOrUniformRoot
::
Module
(
module
))
=>
...
...
@@ -3547,8 +3586,8 @@ fn resolve_qpath(&mut self,
};
if
path
.len
()
>
1
&&
!
global_by_default
&&
result
.base_def
()
!=
Def
::
Err
&&
path
[
0
]
.
0
.name
!=
keywords
::
CrateRoot
.name
()
&&
path
[
0
]
.
0
.name
!=
keywords
::
DollarCrate
.name
()
{
path
[
0
]
.
ident
.name
!=
keywords
::
CrateRoot
.name
()
&&
path
[
0
]
.
ident
.name
!=
keywords
::
DollarCrate
.name
()
{
let
unqualified_result
=
{
match
self
.resolve_path
(
None
,
...
...
@@ -3576,7 +3615,7 @@ fn resolve_qpath(&mut self,
fn
resolve_path
(
&
mut
self
,
base_module
:
Option
<
ModuleOrUniformRoot
<
'a
>>
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
opt_ns
:
Option
<
Namespace
>
,
// `None` indicates a module path
record_used
:
bool
,
path_span
:
Span
,
...
...
@@ -3590,7 +3629,7 @@ fn resolve_path(
fn
resolve_path_with_parent_scope
(
&
mut
self
,
base_module
:
Option
<
ModuleOrUniformRoot
<
'a
>>
,
path
:
&
[
Id
ent
],
path
:
&
[
Segm
ent
],
opt_ns
:
Option
<
Namespace
>
,
// `None` indicates a module path
parent_scope
:
&
ParentScope
<
'a
>
,
record_used
:
bool
,
...
...
@@ -3612,7 +3651,7 @@ fn resolve_path_with_parent_scope(
crate_lint
,
);
for
(
i
,
&
(
ident
,
id
)
)
in
path
.iter
()
.enumerate
()
{
for
(
i
,
&
Segment
{
ident
,
id
}
)
in
path
.iter
()
.enumerate
()
{
debug!
(
"resolve_path ident {} {:?}"
,
i
,
ident
);
let
is_last
=
i
==
path
.len
()
-
1
;
...
...
@@ -3674,7 +3713,7 @@ fn resolve_path_with_parent_scope(
}
else
{
format!
(
"`{}`"
,
name
)
};
let
msg
=
if
i
==
1
&&
path
[
0
]
.
0
.name
==
keywords
::
CrateRoot
.name
()
{
let
msg
=
if
i
==
1
&&
path
[
0
]
.
ident
.name
==
keywords
::
CrateRoot
.name
()
{
format!
(
"global paths cannot start with {}"
,
name_str
)
}
else
{
format!
(
"{} in paths can only be used in start position"
,
name_str
)
...
...
@@ -3771,7 +3810,7 @@ fn resolve_path_with_parent_scope(
}
else
if
i
==
0
{
format!
(
"Use of undeclared type or module `{}`"
,
ident
)
}
else
{
format!
(
"Could not find `{}` in `{}`"
,
ident
,
path
[
i
-
1
]
.
0
)
format!
(
"Could not find `{}` in `{}`"
,
ident
,
path
[
i
-
1
]
.
ident
)
};
return
PathResult
::
Failed
(
ident
.span
,
msg
,
is_last
);
}
...
...
@@ -3789,7 +3828,7 @@ fn resolve_path_with_parent_scope(
fn
lint_if_path_starts_with_module
(
&
self
,
crate_lint
:
CrateLint
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
path_span
:
Span
,
second_binding
:
Option
<&
NameBinding
>
,
)
{
...
...
@@ -3806,7 +3845,7 @@ fn lint_if_path_starts_with_module(
};
let
first_name
=
match
path
.get
(
0
)
{
Some
(
ident
)
=>
ident
.
0
.name
,
Some
(
ident
)
=>
ident
.
ident
.name
,
None
=>
return
,
};
...
...
@@ -3818,7 +3857,7 @@ fn lint_if_path_starts_with_module(
match
path
.get
(
1
)
{
// If this import looks like `crate::...` it's already good
Some
(
(
ident
,
_
)
)
if
ident
.name
==
keywords
::
Crate
.name
()
=>
return
,
Some
(
Segment
{
ident
,
..
}
)
if
ident
.name
==
keywords
::
Crate
.name
()
=>
return
,
// Otherwise go below to see if it's an extern crate
Some
(
_
)
=>
{}
// If the path has length one (and it's `CrateRoot` most likely)
...
...
@@ -4011,7 +4050,7 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
}
fn
lookup_typo_candidate
<
FilterFn
>
(
&
mut
self
,
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
path
:
&
[
Segment
],
ns
:
Namespace
,
filter_fn
:
FilterFn
,
span
:
Span
)
...
...
@@ -4075,7 +4114,7 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
}
}
let
name
=
path
[
path
.len
()
-
1
]
.
0
.name
;
let
name
=
path
[
path
.len
()
-
1
]
.
ident
.name
;
// Make sure error reporting is deterministic.
names
.sort_by_cached_key
(|
name
|
name
.as_str
());
match
find_best_match_for_name
(
names
.iter
(),
&
name
.as_str
(),
None
)
{
...
...
@@ -4592,7 +4631,7 @@ fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
ast
::
VisibilityKind
::
Restricted
{
ref
path
,
id
,
..
}
=>
{
// Visibilities are resolved as global by default, add starting root segment.
let
segments
=
path
.make_root
()
.iter
()
.chain
(
path
.segments
.iter
())
.map
(|
seg
|
(
seg
.ident
,
Some
(
seg
.id
))
)
.map
(|
seg
|
Segment
{
ident
:
seg
.ident
,
id
:
Some
(
seg
.id
)
}
)
.collect
::
<
Vec
<
_
>>
();
let
def
=
self
.smart_resolve_path_fragment
(
id
,
...
...
@@ -4885,12 +4924,12 @@ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_g
}
}
fn
is_self_type
(
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
namespace
:
Namespace
)
->
bool
{
namespace
==
TypeNS
&&
path
.len
()
==
1
&&
path
[
0
]
.
0
.name
==
keywords
::
SelfType
.name
()
fn
is_self_type
(
path
:
&
[
Segment
],
namespace
:
Namespace
)
->
bool
{
namespace
==
TypeNS
&&
path
.len
()
==
1
&&
path
[
0
]
.
ident
.name
==
keywords
::
SelfType
.name
()
}
fn
is_self_value
(
path
:
&
[
(
Ident
,
Option
<
NodeId
>
)
],
namespace
:
Namespace
)
->
bool
{
namespace
==
ValueNS
&&
path
.len
()
==
1
&&
path
[
0
]
.
0
.name
==
keywords
::
SelfValue
.name
()
fn
is_self_value
(
path
:
&
[
Segment
],
namespace
:
Namespace
)
->
bool
{
namespace
==
ValueNS
&&
path
.len
()
==
1
&&
path
[
0
]
.
ident
.name
==
keywords
::
SelfValue
.name
()
}
fn
names_to_string
(
idents
:
&
[
Ident
])
->
String
{
...
...
@@ -4906,12 +4945,6 @@ fn names_to_string(idents: &[Ident]) -> String {
result
}
fn
names_and_ids_to_string
(
segments
:
&
[(
Ident
,
Option
<
NodeId
>
)])
->
String
{
names_to_string
(
&
segments
.iter
()
.map
(|
seg
|
seg
.0
)
.collect
::
<
Vec
<
_
>>
())
}
fn
path_names_to_string
(
path
:
&
Path
)
->
String
{
names_to_string
(
&
path
.segments
.iter
()
.map
(|
seg
|
seg
.ident
)
...
...
src/librustc_resolve/macros.rs
浏览文件 @
59cb1705
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
use
{
AmbiguityError
,
CrateLint
,
Resolver
,
ResolutionError
,
is_known_tool
,
resolve_error
};
use
{
Module
,
ModuleKind
,
NameBinding
,
NameBindingKind
,
PathResult
,
ToNameBinding
};
use
{
Module
,
ModuleKind
,
NameBinding
,
NameBindingKind
,
PathResult
,
Segment
,
ToNameBinding
};
use
ModuleOrUniformRoot
;
use
Namespace
::{
self
,
*
};
use
build_reduced_graph
::{
BuildReducedGraphVisitor
,
IsMacroExport
};
...
...
@@ -461,14 +461,15 @@ pub fn resolve_macro_to_def_inner(
parent_scope
:
&
ParentScope
<
'a
>
,
force
:
bool
,
)
->
Result
<
Def
,
Determinacy
>
{
let
ast
::
Path
{
ref
segments
,
span
}
=
*
path
;
let
mut
path
:
Vec
<
_
>
=
segments
.iter
()
.map
(|
seg
|
(
seg
.ident
,
Some
(
seg
.id
)))
.collect
(
);
let
span
=
path
.span
;
let
mut
path
=
Segment
::
from_path
(
path
);
// Possibly apply the macro helper hack
if
kind
==
MacroKind
::
Bang
&&
path
.len
()
==
1
&&
path
[
0
]
.0
.span
.ctxt
()
.outer
()
.expn_info
()
.map_or
(
false
,
|
info
|
info
.local_inner_macros
)
{
let
root
=
Ident
::
new
(
keywords
::
DollarCrate
.name
(),
path
[
0
]
.0
.span
);
path
.insert
(
0
,
(
root
,
None
));
path
[
0
]
.ident.span
.ctxt
()
.outer
()
.expn_info
()
.map_or
(
false
,
|
info
|
info
.local_inner_macros
)
{
let
root
=
Ident
::
new
(
keywords
::
DollarCrate
.name
(),
path
[
0
]
.ident.span
);
path
.insert
(
0
,
Segment
::
from_ident
(
root
));
}
if
path
.len
()
>
1
{
...
...
@@ -498,14 +499,14 @@ pub fn resolve_macro_to_def_inner(
parent_scope
.module.macro_resolutions
.borrow_mut
()
.push
((
path
.iter
()
.map
(|
(
ident
,
_
)|
*
ident
)
.map
(|
seg
|
seg
.
ident
)
.collect
::
<
Vec
<
Ident
>>
()
.into_boxed_slice
(),
span
));
def
}
else
{
let
binding
=
self
.early_resolve_ident_in_lexical_scope
(
path
[
0
]
.
0
,
MacroNS
,
Some
(
kind
),
parent_scope
,
false
,
force
,
span
path
[
0
]
.
ident
,
MacroNS
,
Some
(
kind
),
parent_scope
,
false
,
force
,
span
);
match
binding
{
Ok
(
..
)
=>
{}
...
...
@@ -514,7 +515,7 @@ pub fn resolve_macro_to_def_inner(
}
parent_scope
.module.legacy_macro_resolutions
.borrow_mut
()
.push
((
path
[
0
]
.
0
,
kind
,
parent_scope
.clone
(),
binding
.ok
()));
.push
((
path
[
0
]
.
ident
,
kind
,
parent_scope
.clone
(),
binding
.ok
()));
binding
.map
(|
binding
|
binding
.def_ignoring_ambiguity
())
}
...
...
@@ -850,10 +851,7 @@ struct Flags: u8 {
pub
fn
finalize_current_module_macro_resolutions
(
&
mut
self
)
{
let
module
=
self
.current_module
;
for
&
(
ref
path
,
span
)
in
module
.macro_resolutions
.borrow
()
.iter
()
{
let
path
=
path
.iter
()
.map
(|
ident
|
(
*
ident
,
None
))
.collect
::
<
Vec
<
(
Ident
,
Option
<
ast
::
NodeId
>
)
>>
();
let
path
:
Vec
<
_
>
=
path
.iter
()
.map
(|
&
ident
|
Segment
::
from_ident
(
ident
))
.collect
();
match
self
.resolve_path
(
None
,
&
path
,
Some
(
MacroNS
),
true
,
span
,
CrateLint
::
No
)
{
PathResult
::
NonModule
(
_
)
=>
{},
PathResult
::
Failed
(
span
,
msg
,
_
)
=>
{
...
...
@@ -946,7 +944,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
}
};
let
ident
=
Ident
::
new
(
Symbol
::
intern
(
name
),
span
);
self
.lookup_typo_candidate
(
&
[
(
ident
,
None
)],
MacroNS
,
is_macro
,
span
)
self
.lookup_typo_candidate
(
&
[
Segment
::
from_ident
(
ident
)],
MacroNS
,
is_macro
,
span
)
});
if
let
Some
(
suggestion
)
=
suggestion
{
...
...
src/librustc_resolve/resolve_imports.rs
浏览文件 @
59cb1705
...
...
@@ -13,8 +13,8 @@
use
{
AmbiguityError
,
CrateLint
,
Module
,
ModuleOrUniformRoot
,
PerNS
};
use
Namespace
::{
self
,
TypeNS
,
MacroNS
};
use
{
NameBinding
,
NameBindingKind
,
ToNameBinding
,
PathResult
,
PrivacyError
};
use
Resolver
;
use
{
names_to_string
,
names_and_ids_to_string
,
module_to_string
};
use
{
Resolver
,
Segment
}
;
use
{
names_to_string
,
module_to_string
};
use
{
resolve_error
,
ResolutionError
};
use
rustc_data_structures
::
ptr_key
::
PtrKey
;
...
...
@@ -89,7 +89,7 @@ pub struct ImportDirective<'a> {
pub
root_span
:
Span
,
pub
parent
:
Module
<
'a
>
,
pub
module_path
:
Vec
<
(
Ident
,
Option
<
NodeId
>
)
>
,
pub
module_path
:
Vec
<
Segment
>
,
/// The resolution of `module_path`.
pub
imported_module
:
Cell
<
Option
<
ModuleOrUniformRoot
<
'a
>>>
,
pub
subclass
:
ImportDirectiveSubclass
<
'a
>
,
...
...
@@ -393,7 +393,7 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
// Add an import directive to the current module.
pub
fn
add_import_directive
(
&
mut
self
,
module_path
:
Vec
<
(
Ident
,
Option
<
NodeId
>
)
>
,
module_path
:
Vec
<
Segment
>
,
subclass
:
ImportDirectiveSubclass
<
'a
>
,
span
:
Span
,
id
:
NodeId
,
...
...
@@ -679,7 +679,7 @@ struct UniformPathsCanaryResults<'a> {
let
has_explicit_self
=
!
import
.module_path
.is_empty
()
&&
import
.module_path
[
0
]
.
0
.name
==
keywords
::
SelfValue
.name
();
import
.module_path
[
0
]
.
ident
.name
==
keywords
::
SelfValue
.name
();
self
.per_ns
(|
_
,
ns
|
{
if
let
Some
(
result
)
=
result
[
ns
]
.get
()
.ok
()
{
...
...
@@ -729,7 +729,7 @@ struct UniformPathsCanaryResults<'a> {
}
if
!
seen_spans
.contains
(
&
span
)
{
let
path
=
import_path_to_string
(
&
import
.module_path
.iter
()
.map
(|
(
ident
,
_
)|
*
ident
)
.collect
::
<
Vec
<
_
>>
(),
&
import
.module_path
.iter
()
.map
(|
seg
|
seg
.
ident
)
.collect
::
<
Vec
<
_
>>
(),
&
import
.subclass
,
span
,
);
...
...
@@ -853,9 +853,10 @@ fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>,
/// If successful, the resolved bindings are written into the module.
fn
resolve_import
(
&
mut
self
,
directive
:
&
'b
ImportDirective
<
'b
>
)
->
bool
{
debug!
(
"(resolving import for module) resolving import `{}::...` in `{}`"
,
names_and_id
s_to_string
(
&
directive
.module_path
[
..
]),
Segment
::
name
s_to_string
(
&
directive
.module_path
[
..
]),
module_to_string
(
self
.current_module
)
.unwrap_or_else
(||
"???"
.to_string
()));
self
.current_module
=
directive
.parent
;
let
module
=
if
let
Some
(
module
)
=
directive
.imported_module
.get
()
{
...
...
@@ -968,7 +969,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
)
{
Some
((
span
,
format!
(
"Did you mean `{}`?"
,
names_to_string
(
&
suggested_path
[
..
]
))
format!
(
"Did you mean `{}`?"
,
Segment
::
names_to_string
(
&
suggested_path
))
))
}
else
{
Some
((
span
,
msg
))
...
...
@@ -984,7 +985,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
let
mut
full_path
=
module_path
.clone
();
full_path
.push
(
(
keywords
::
Invalid
.ident
(),
None
));
full_path
.push
(
Segment
::
from_ident
(
keywords
::
Invalid
.ident
()
));
self
.lint_if_path_starts_with_module
(
directive
.crate_lint
(),
&
full_path
,
...
...
@@ -1148,7 +1149,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
let
mut
full_path
=
module_path
.clone
();
full_path
.push
(
(
ident
,
None
));
full_path
.push
(
Segment
::
from_ident
(
ident
));
self
.per_ns
(|
this
,
ns
|
{
if
let
Ok
(
binding
)
=
result
[
ns
]
.get
()
{
this
.lint_if_path_starts_with_module
(
...
...
@@ -1290,7 +1291,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
let
resolutions
=
imported_module
.parent
.expect
(
"parent should exist"
)
.resolutions
.borrow
();
let
enum_path_segment_index
=
directive
.module_path
.len
()
-
1
;
let
enum_ident
=
directive
.module_path
[
enum_path_segment_index
]
.
0
;
let
enum_ident
=
directive
.module_path
[
enum_path_segment_index
]
.
ident
;
let
enum_resolution
=
resolutions
.get
(
&
(
enum_ident
,
TypeNS
))
.expect
(
"resolution should exist"
);
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
59cb1705
...
...
@@ -2137,7 +2137,7 @@ fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
PathSegment
{
ident
,
args
,
id
:
ast
::
DUMMY_NODE_ID
}
}
else
{
// Generic arguments are not found.
PathSegment
::
from_ident
(
ident
,
)
PathSegment
::
from_ident
(
ident
)
})
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录