Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
99925fb5
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
99925fb5
编写于
11月 21, 2015
作者:
M
Manish Goregaokar
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Look up macro names as well when suggesting replacements for function resolve errors
fixes #5780
上级
ef5ee7d8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
76 addition
and
30 deletion
+76
-30
src/librustc/session/mod.rs
src/librustc/session/mod.rs
+7
-1
src/librustc_driver/driver.rs
src/librustc_driver/driver.rs
+7
-6
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+21
-5
src/libsyntax/ext/base.rs
src/libsyntax/ext/base.rs
+9
-3
src/libsyntax/ext/expand.rs
src/libsyntax/ext/expand.rs
+19
-15
src/test/compile-fail/resolve-hint-macro.rs
src/test/compile-fail/resolve-hint-macro.rs
+13
-0
未找到文件。
src/librustc/session/mod.rs
浏览文件 @
99925fb5
...
...
@@ -15,7 +15,7 @@
use
session
::
search_paths
::
PathKind
;
use
util
::
nodemap
::{
NodeMap
,
FnvHashMap
};
use
syntax
::
ast
::{
NodeId
,
NodeIdAssigner
};
use
syntax
::
ast
::{
NodeId
,
NodeIdAssigner
,
Name
};
use
syntax
::
codemap
::
Span
;
use
syntax
::
diagnostic
::{
self
,
Emitter
};
use
syntax
::
diagnostics
;
...
...
@@ -30,6 +30,7 @@
use
std
::
path
::{
Path
,
PathBuf
};
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
collections
::
HashSet
;
use
std
::
env
;
pub
mod
config
;
...
...
@@ -74,6 +75,10 @@ pub struct Session {
/// didn't already find one, and this tracks what was injected.
pub
injected_allocator
:
Cell
<
Option
<
ast
::
CrateNum
>>
,
/// Names of all bang-style macros and syntax extensions
/// available in this crate
pub
available_macros
:
RefCell
<
HashSet
<
Name
>>
,
next_node_id
:
Cell
<
ast
::
NodeId
>
,
}
...
...
@@ -468,6 +473,7 @@ pub fn build_session_(sopts: config::Options,
can_print_warnings
:
can_print_warnings
,
next_node_id
:
Cell
::
new
(
1
),
injected_allocator
:
Cell
::
new
(
None
),
available_macros
:
RefCell
::
new
(
HashSet
::
new
()),
};
sess
...
...
src/librustc_driver/driver.rs
浏览文件 @
99925fb5
...
...
@@ -553,15 +553,16 @@ pub fn phase_2_configure_and_expand(sess: &Session,
recursion_limit
:
sess
.recursion_limit
.get
(),
trace_mac
:
sess
.opts.debugging_opts.trace_macros
,
};
let
ret
=
syntax
::
ext
::
expand
::
expand_crate
(
&
sess
.parse_sess
,
cfg
,
macros
,
syntax_exts
,
&
mut
feature_gated_cfgs
,
krate
);
let
(
ret
,
macro_names
)
=
syntax
::
ext
::
expand
::
expand_crate
(
&
sess
.parse_sess
,
cfg
,
macros
,
syntax_exts
,
&
mut
feature_gated_cfgs
,
krate
);
if
cfg!
(
windows
)
{
env
::
set_var
(
"PATH"
,
&
_
old_path
);
}
*
sess
.available_macros
.borrow_mut
()
=
macro_names
;
ret
});
...
...
src/librustc_resolve/lib.rs
浏览文件 @
99925fb5
...
...
@@ -124,6 +124,12 @@
)
}
enum
SuggestionType
{
Macro
(
String
),
Function
(
String
),
NotFound
,
}
pub
enum
ResolutionError
<
'a
>
{
/// error E0401: can't use type parameters from outer function
TypeParametersFromOuterFunction
,
...
...
@@ -3616,10 +3622,15 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
NoSuggestion
}
fn
find_best_match_for_name
(
&
mut
self
,
name
:
&
str
)
->
Option
<
String
>
{
fn
find_best_match_for_name
(
&
mut
self
,
name
:
&
str
)
->
SuggestionType
{
let
mut
maybes
:
Vec
<
token
::
InternedString
>
=
Vec
::
new
();
let
mut
values
:
Vec
<
usize
>
=
Vec
::
new
();
if
let
Some
(
macro_name
)
=
self
.session.available_macros
.borrow
()
.iter
()
.find
(|
n
|
n
.as_str
()
==
name
)
{
return
SuggestionType
::
Macro
(
format!
(
"{}!"
,
macro_name
));
}
for
rib
in
self
.value_ribs
.iter
()
.rev
()
{
for
(
&
k
,
_
)
in
&
rib
.bindings
{
maybes
.push
(
k
.as_str
());
...
...
@@ -3643,10 +3654,10 @@ fn find_best_match_for_name(&mut self, name: &str) -> Option<String> {
if
!
values
.is_empty
()
&&
values
[
smallest
]
<=
max_distance
&&
name
!=
&
maybes
[
smallest
][
..
]
{
S
ome
(
maybes
[
smallest
]
.to_string
())
S
uggestionType
::
Function
(
maybes
[
smallest
]
.to_string
())
}
else
{
None
SuggestionType
::
NotFound
}
}
...
...
@@ -3758,8 +3769,13 @@ fn resolve_expr(&mut self, expr: &Expr) {
NoSuggestion
=>
{
// limit search to 5 to reduce the number
// of stupid suggestions
self
.find_best_match_for_name
(
&
path_name
)
.map_or
(
""
.to_string
(),
|
x
|
format!
(
"`{}`"
,
x
))
match
self
.find_best_match_for_name
(
&
path_name
)
{
SuggestionType
::
Macro
(
s
)
=>
{
format!
(
"the macro `{}`"
,
s
)
}
SuggestionType
::
Function
(
s
)
=>
format!
(
"`{}`"
,
s
),
SuggestionType
::
NotFound
=>
""
.to_string
(),
}
}
Field
=>
format!
(
"`self.{}`"
,
path_name
),
Method
|
...
...
src/libsyntax/ext/base.rs
浏览文件 @
99925fb5
...
...
@@ -27,7 +27,7 @@
use
ext
::
mtwt
;
use
fold
::
Folder
;
use
std
::
collections
::
HashMap
;
use
std
::
collections
::
{
HashMap
,
HashSet
}
;
use
std
::
rc
::
Rc
;
use
std
::
default
::
Default
;
...
...
@@ -856,7 +856,10 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
///
/// This environment maps Names to SyntaxExtensions.
pub
struct
SyntaxEnv
{
chain
:
Vec
<
MapChainFrame
>
,
chain
:
Vec
<
MapChainFrame
>
,
/// All bang-style macro/extension names
/// encountered so far; to be used for diagnostics in resolve
pub
names
:
HashSet
<
Name
>
,
}
// impl question: how to implement it? Initially, the
...
...
@@ -876,7 +879,7 @@ struct MapChainFrame {
impl
SyntaxEnv
{
fn
new
()
->
SyntaxEnv
{
let
mut
map
=
SyntaxEnv
{
chain
:
Vec
::
new
()
};
let
mut
map
=
SyntaxEnv
{
chain
:
Vec
::
new
()
,
names
:
HashSet
::
new
()
};
map
.push_frame
();
map
}
...
...
@@ -913,6 +916,9 @@ pub fn find(&self, k: Name) -> Option<Rc<SyntaxExtension>> {
}
pub
fn
insert
(
&
mut
self
,
k
:
Name
,
v
:
SyntaxExtension
)
{
if
let
NormalTT
(
..
)
=
v
{
self
.names
.insert
(
k
);
}
self
.find_escape_frame
()
.map
.insert
(
k
,
Rc
::
new
(
v
));
}
...
...
src/libsyntax/ext/expand.rs
浏览文件 @
99925fb5
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
use
ast
::{
Block
,
Crate
,
DeclLocal
,
ExprMac
,
PatMac
};
use
ast
::{
Local
,
Ident
,
Mac_
};
use
ast
::{
Local
,
Ident
,
Mac_
,
Name
};
use
ast
::{
ItemMac
,
MacStmtWithSemicolon
,
Mrk
,
Stmt
,
StmtDecl
,
StmtMac
};
use
ast
::{
StmtExpr
,
StmtSemi
};
use
ast
::
TokenTree
;
...
...
@@ -32,6 +32,8 @@
use
visit
::
Visitor
;
use
std_inject
;
use
std
::
collections
::
HashSet
;
pub
fn
expand_expr
(
e
:
P
<
ast
::
Expr
>
,
fld
:
&
mut
MacroExpander
)
->
P
<
ast
::
Expr
>
{
let
expr_span
=
e
.span
;
...
...
@@ -1261,7 +1263,7 @@ pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
imported_macros
:
Vec
<
ast
::
MacroDef
>
,
user_exts
:
Vec
<
NamedSyntaxExtension
>
,
feature_gated_cfgs
:
&
mut
Vec
<
GatedCfg
>
,
c
:
Crate
)
->
Crate
{
c
:
Crate
)
->
(
Crate
,
HashSet
<
Name
>
)
{
let
mut
cx
=
ExtCtxt
::
new
(
parse_sess
,
c
.config
.clone
(),
cfg
,
feature_gated_cfgs
);
if
std_inject
::
no_core
(
&
c
)
{
...
...
@@ -1271,21 +1273,23 @@ pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
}
else
{
cx
.crate_root
=
Some
(
"std"
);
}
let
ret
=
{
let
mut
expander
=
MacroExpander
::
new
(
&
mut
cx
);
let
mut
expander
=
MacroExpander
::
new
(
&
mut
cx
);
for
def
in
imported_macros
{
expander
.cx
.insert_macro
(
def
);
}
for
def
in
imported_macros
{
expander
.cx
.insert_macro
(
def
);
}
for
(
name
,
extension
)
in
user_exts
{
expander
.cx.syntax_env
.insert
(
name
,
extension
);
}
for
(
name
,
extension
)
in
user_exts
{
expander
.cx.syntax_env
.insert
(
name
,
extension
);
}
let
mut
ret
=
expander
.fold_crate
(
c
);
ret
.exported_macros
=
expander
.cx.exported_macros
.clone
();
parse_sess
.span_diagnostic
.handler
()
.abort_if_errors
();
return
ret
;
let
mut
ret
=
expander
.fold_crate
(
c
);
ret
.exported_macros
=
expander
.cx.exported_macros
.clone
();
parse_sess
.span_diagnostic
.handler
()
.abort_if_errors
();
ret
};
return
(
ret
,
cx
.syntax_env.names
);
}
// HYGIENIC CONTEXT EXTENSION:
...
...
@@ -1480,7 +1484,7 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
let
ps
=
parse
::
ParseSess
::
new
();
let
crate_ast
=
panictry!
(
string_to_parser
(
&
ps
,
crate_str
)
.parse_crate_mod
());
// the cfg argument actually does matter, here...
expand_crate
(
&
ps
,
test_ecfg
(),
vec!
(),
vec!
(),
&
mut
vec!
[],
crate_ast
)
expand_crate
(
&
ps
,
test_ecfg
(),
vec!
(),
vec!
(),
&
mut
vec!
[],
crate_ast
)
.0
}
// find the pat_ident paths in a crate
...
...
src/test/compile-fail/resolve-hint-macro.rs
0 → 100644
浏览文件 @
99925fb5
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn
main
()
{
assert
(
true
);
//~ERROR unresolved name `assert`. Did you mean the macro `assert!`?
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录