Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6da912e2
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,发现更多精彩内容 >>
提交
6da912e2
编写于
1月 26, 2018
作者:
A
Alex Crichton
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'explain' of
https://github.com/estebank/rust
into rollup
上级
95942155
2b737334
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
231 addition
and
44 deletion
+231
-44
src/librustc/session/config.rs
src/librustc/session/config.rs
+3
-2
src/librustc/session/mod.rs
src/librustc/session/mod.rs
+4
-0
src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic.rs
+5
-1
src/librustc_errors/lib.rs
src/librustc_errors/lib.rs
+18
-0
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+6
-4
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+3
-3
src/librustc_typeck/lib.rs
src/librustc_typeck/lib.rs
+4
-3
src/librustc_typeck/structured_errors.rs
src/librustc_typeck/structured_errors.rs
+150
-0
src/test/compile-fail/E0617.rs
src/test/compile-fail/E0617.rs
+12
-6
src/test/compile-fail/issue-32201.rs
src/test/compile-fail/issue-32201.rs
+2
-1
src/test/ui/variadic-ffi-3.rs
src/test/ui/variadic-ffi-3.rs
+6
-6
src/test/ui/variadic-ffi-3.stderr
src/test/ui/variadic-ffi-3.stderr
+18
-18
未找到文件。
src/librustc/session/config.rs
浏览文件 @
6da912e2
...
...
@@ -1167,6 +1167,8 @@ fn parse_lto(slot: &mut Lto, v: Option<&str>) -> bool {
"treat all errors that occur as bugs"
),
external_macro_backtrace
:
bool
=
(
false
,
parse_bool
,
[
UNTRACKED
],
"show macro backtraces even for non-local macros"
),
teach
:
bool
=
(
false
,
parse_bool
,
[
TRACKED
],
"show extended diagnostic help"
),
continue_parse_after_error
:
bool
=
(
false
,
parse_bool
,
[
TRACKED
],
"attempt to recover from parse errors (experimental)"
),
incremental
:
Option
<
String
>
=
(
None
,
parse_opt_string
,
[
UNTRACKED
],
...
...
@@ -1664,8 +1666,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
let
mut
debugging_opts
=
build_debugging_options
(
matches
,
error_format
);
if
!
debugging_opts
.unstable_options
&&
error_format
==
ErrorOutputType
::
Json
(
true
)
{
early_error
(
ErrorOutputType
::
Json
(
false
),
"--error-format=pretty-json is unstable"
);
early_error
(
ErrorOutputType
::
Json
(
false
),
"--error-format=pretty-json is unstable"
);
}
let
mut
output_types
=
BTreeMap
::
new
();
...
...
src/librustc/session/mod.rs
浏览文件 @
6da912e2
...
...
@@ -860,6 +860,10 @@ pub fn codegen_units(&self) -> usize {
// scientific.
16
}
pub
fn
teach
(
&
self
,
code
:
&
DiagnosticId
)
->
bool
{
self
.opts.debugging_opts.teach
&&
!
self
.parse_sess.span_diagnostic
.code_emitted
(
code
)
}
}
pub
fn
build_session
(
sopts
:
config
::
Options
,
...
...
src/librustc_errors/diagnostic.rs
浏览文件 @
6da912e2
...
...
@@ -27,7 +27,7 @@ pub struct Diagnostic {
pub
suggestions
:
Vec
<
CodeSuggestion
>
,
}
#[derive(Clone,
Debug,
PartialEq,
Hash,
RustcEncodable,
RustcDecodable)]
#[derive(Clone,
Debug,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable)]
pub
enum
DiagnosticId
{
Error
(
String
),
Lint
(
String
),
...
...
@@ -281,6 +281,10 @@ pub fn code(&mut self, s: DiagnosticId) -> &mut Self {
self
}
pub
fn
get_code
(
&
self
)
->
Option
<
DiagnosticId
>
{
self
.code
.clone
()
}
pub
fn
message
(
&
self
)
->
String
{
self
.message
.iter
()
.map
(|
i
|
i
.0
.to_owned
())
.collect
::
<
String
>
()
}
...
...
src/librustc_errors/lib.rs
浏览文件 @
6da912e2
...
...
@@ -259,6 +259,11 @@ pub struct Handler {
delayed_span_bug
:
RefCell
<
Option
<
Diagnostic
>>
,
tracked_diagnostics
:
RefCell
<
Option
<
Vec
<
Diagnostic
>>>
,
// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
// emitting the same diagnostic with extended help (`--teach`) twice, which
// would be uneccessary repetition.
tracked_diagnostic_codes
:
RefCell
<
FxHashSet
<
DiagnosticId
>>
,
// This set contains a hash of every diagnostic that has been emitted by
// this handler. These hashes is used to avoid emitting the same error
// twice.
...
...
@@ -317,6 +322,7 @@ pub fn with_emitter_and_flags(e: Box<Emitter>, flags: HandlerFlags) -> Handler {
continue_after_error
:
Cell
::
new
(
true
),
delayed_span_bug
:
RefCell
::
new
(
None
),
tracked_diagnostics
:
RefCell
::
new
(
None
),
tracked_diagnostic_codes
:
RefCell
::
new
(
FxHashSet
()),
emitted_diagnostics
:
RefCell
::
new
(
FxHashSet
()),
}
}
...
...
@@ -589,6 +595,14 @@ pub fn track_diagnostics<F, R>(&self, f: F) -> (R, Vec<Diagnostic>)
(
ret
,
diagnostics
)
}
/// `true` if a diagnostic with this code has already been emitted in this handler.
///
/// Used to suppress emitting the same error multiple times with extended explanation when
/// calling `-Zteach`.
pub
fn
code_emitted
(
&
self
,
code
:
&
DiagnosticId
)
->
bool
{
self
.tracked_diagnostic_codes
.borrow
()
.contains
(
code
)
}
fn
emit_db
(
&
self
,
db
:
&
DiagnosticBuilder
)
{
let
diagnostic
=
&**
db
;
...
...
@@ -596,6 +610,10 @@ fn emit_db(&self, db: &DiagnosticBuilder) {
list
.push
(
diagnostic
.clone
());
}
if
let
Some
(
ref
code
)
=
diagnostic
.code
{
self
.tracked_diagnostic_codes
.borrow_mut
()
.insert
(
code
.clone
());
}
let
diagnostic_hash
=
{
use
std
::
hash
::
Hash
;
let
mut
hasher
=
StableHasher
::
new
();
...
...
src/librustc_typeck/check/cast.rs
浏览文件 @
6da912e2
...
...
@@ -281,10 +281,12 @@ fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
.emit
();
}
CastError
::
SizedUnsizedCast
=>
{
type_error_struct!
(
fcx
.tcx.sess
,
self
.span
,
self
.expr_ty
,
E0607
,
"cannot cast thin pointer `{}` to fat pointer `{}`"
,
self
.expr_ty
,
fcx
.ty_to_string
(
self
.cast_ty
))
.emit
();
use
structured_errors
::{
SizedUnsizedCastError
,
StructuredDiagnostic
};
SizedUnsizedCastError
::
new
(
&
fcx
.tcx.sess
,
self
.span
,
self
.expr_ty
,
fcx
.ty_to_string
(
self
.cast_ty
))
.diagnostic
()
.emit
();
}
CastError
::
UnknownCastPtrKind
|
CastError
::
UnknownExprPtrKind
=>
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
6da912e2
...
...
@@ -103,6 +103,7 @@
use
rustc
::
ty
::
util
::{
Representability
,
IntTypeExt
};
use
rustc
::
ty
::
layout
::
LayoutOf
;
use
errors
::{
DiagnosticBuilder
,
DiagnosticId
};
use
require_c_abi_if_variadic
;
use
session
::{
CompileIncomplete
,
config
,
Session
};
use
TypeAndSubsts
;
...
...
@@ -2599,9 +2600,8 @@ fn parameter_count_error<'tcx>(sess: &Session,
// arguments which we skipped above.
if
variadic
{
fn
variadic_error
<
'tcx
>
(
s
:
&
Session
,
span
:
Span
,
t
:
Ty
<
'tcx
>
,
cast_ty
:
&
str
)
{
type_error_struct!
(
s
,
span
,
t
,
E0617
,
"can't pass `{}` to variadic function, cast to `{}`"
,
t
,
cast_ty
)
.emit
();
use
structured_errors
::{
VariadicError
,
StructuredDiagnostic
};
VariadicError
::
new
(
s
,
span
,
t
,
cast_ty
)
.diagnostic
()
.emit
();
}
for
arg
in
args
.iter
()
.skip
(
expected_arg_count
)
{
...
...
src/librustc_typeck/lib.rs
浏览文件 @
6da912e2
...
...
@@ -123,16 +123,17 @@
// registered before they are used.
mod
diagnostics
;
mod
astconv
;
mod
check
;
mod
check_unused
;
mod
astconv
;
mod
coherence
;
mod
collect
;
mod
constrained_type_params
;
mod
structured_errors
;
mod
impl_wf_check
;
mod
coheren
ce
;
mod
namespa
ce
;
mod
outlives
;
mod
variance
;
mod
namespace
;
pub
struct
TypeAndSubsts
<
'tcx
>
{
substs
:
&
'tcx
Substs
<
'tcx
>
,
...
...
src/librustc_typeck/structured_errors.rs
0 → 100644
浏览文件 @
6da912e2
// Copyright 2018 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.
use
rustc
::
session
::
Session
;
use
syntax_pos
::
Span
;
use
errors
::{
DiagnosticId
,
DiagnosticBuilder
};
use
rustc
::
ty
::{
Ty
,
TypeFoldable
};
pub
trait
StructuredDiagnostic
<
'tcx
>
{
fn
session
(
&
self
)
->
&
Session
;
fn
code
(
&
self
)
->
DiagnosticId
;
fn
common
(
&
self
)
->
DiagnosticBuilder
<
'tcx
>
;
fn
diagnostic
(
&
self
)
->
DiagnosticBuilder
<
'tcx
>
{
let
err
=
self
.common
();
if
self
.session
()
.teach
(
&
self
.code
())
{
self
.extended
(
err
)
}
else
{
self
.regular
(
err
)
}
}
fn
regular
(
&
self
,
err
:
DiagnosticBuilder
<
'tcx
>
)
->
DiagnosticBuilder
<
'tcx
>
{
err
}
fn
extended
(
&
self
,
err
:
DiagnosticBuilder
<
'tcx
>
)
->
DiagnosticBuilder
<
'tcx
>
{
err
}
}
pub
struct
VariadicError
<
'tcx
>
{
sess
:
&
'tcx
Session
,
span
:
Span
,
t
:
Ty
<
'tcx
>
,
cast_ty
:
&
'tcx
str
,
}
impl
<
'tcx
>
VariadicError
<
'tcx
>
{
pub
fn
new
(
sess
:
&
'tcx
Session
,
span
:
Span
,
t
:
Ty
<
'tcx
>
,
cast_ty
:
&
'tcx
str
)
->
VariadicError
<
'tcx
>
{
VariadicError
{
sess
,
span
,
t
,
cast_ty
}
}
}
impl
<
'tcx
>
StructuredDiagnostic
<
'tcx
>
for
VariadicError
<
'tcx
>
{
fn
session
(
&
self
)
->
&
Session
{
self
.sess
}
fn
code
(
&
self
)
->
DiagnosticId
{
__
diagnostic_used!
(
E0617
);
DiagnosticId
::
Error
(
"E0617"
.to_owned
())
}
fn
common
(
&
self
)
->
DiagnosticBuilder
<
'tcx
>
{
let
mut
err
=
if
self
.t
.references_error
()
{
self
.sess
.diagnostic
()
.struct_dummy
()
}
else
{
self
.sess
.struct_span_fatal_with_code
(
self
.span
,
&
format!
(
"can't pass `{}` to variadic function"
,
self
.t
),
self
.code
(),
)
};
if
let
Ok
(
snippet
)
=
self
.sess
.codemap
()
.span_to_snippet
(
self
.span
)
{
err
.span_suggestion
(
self
.span
,
&
format!
(
"cast the value to `{}`"
,
self
.cast_ty
),
format!
(
"{} as {}"
,
snippet
,
self
.cast_ty
));
}
else
{
err
.help
(
&
format!
(
"cast the value to `{}`"
,
self
.cast_ty
));
}
err
}
fn
extended
(
&
self
,
mut
err
:
DiagnosticBuilder
<
'tcx
>
)
->
DiagnosticBuilder
<
'tcx
>
{
err
.note
(
&
format!
(
"certain types, like `{}`, must be cast before passing them to a
\
variadic function, because of arcane ABI rules dictated by the C
\
standard"
,
self
.t
));
err
}
}
pub
struct
SizedUnsizedCastError
<
'tcx
>
{
sess
:
&
'tcx
Session
,
span
:
Span
,
expr_ty
:
Ty
<
'tcx
>
,
cast_ty
:
String
,
}
impl
<
'tcx
>
SizedUnsizedCastError
<
'tcx
>
{
pub
fn
new
(
sess
:
&
'tcx
Session
,
span
:
Span
,
expr_ty
:
Ty
<
'tcx
>
,
cast_ty
:
String
)
->
SizedUnsizedCastError
<
'tcx
>
{
SizedUnsizedCastError
{
sess
,
span
,
expr_ty
,
cast_ty
}
}
}
impl
<
'tcx
>
StructuredDiagnostic
<
'tcx
>
for
SizedUnsizedCastError
<
'tcx
>
{
fn
session
(
&
self
)
->
&
Session
{
self
.sess
}
fn
code
(
&
self
)
->
DiagnosticId
{
__
diagnostic_used!
(
E0607
);
DiagnosticId
::
Error
(
"E0607"
.to_owned
())
}
fn
common
(
&
self
)
->
DiagnosticBuilder
<
'tcx
>
{
if
self
.expr_ty
.references_error
()
{
self
.sess
.diagnostic
()
.struct_dummy
()
}
else
{
self
.sess
.struct_span_fatal_with_code
(
self
.span
,
&
format!
(
"cannot cast thin pointer `{}` to fat pointer `{}`"
,
self
.expr_ty
,
self
.cast_ty
),
self
.code
(),
)
}
}
fn
extended
(
&
self
,
mut
err
:
DiagnosticBuilder
<
'tcx
>
)
->
DiagnosticBuilder
<
'tcx
>
{
err
.help
(
"Thin pointers are
\"
simple
\"
pointers: they are purely a reference to a
memory address.
Fat pointers are pointers referencing
\"
Dynamically Sized Types
\"
(also
called DST). DST don't have a statically known size, therefore they can
only exist behind some kind of pointers that contain additional
information. Slices and trait objects are DSTs. In the case of slices,
the additional information the fat pointer holds is their size.
To fix this error, don't try to cast directly between thin and fat
pointers.
For more information about casts, take a look at The Book:
https://doc.rust-lang.org/book/first-edition/casting-between-types.html"
);
err
}
}
src/test/compile-fail/E0617.rs
浏览文件 @
6da912e2
...
...
@@ -17,16 +17,22 @@
fn
main
()
{
unsafe
{
printf
(::
std
::
ptr
::
null
(),
0f32
);
//~^ ERROR can't pass `f32` to variadic function, cast to `c_double` [E0617]
//~^ ERROR can't pass `f32` to variadic function
//~| HELP cast the value to `c_double`
printf
(::
std
::
ptr
::
null
(),
0i8
);
//~^ ERROR can't pass `i8` to variadic function, cast to `c_int` [E0617]
//~^ ERROR can't pass `i8` to variadic function
//~| HELP cast the value to `c_int`
printf
(::
std
::
ptr
::
null
(),
0i16
);
//~^ ERROR can't pass `i16` to variadic function, cast to `c_int` [E0617]
//~^ ERROR can't pass `i16` to variadic function
//~| HELP cast the value to `c_int`
printf
(::
std
::
ptr
::
null
(),
0u8
);
//~^ ERROR can't pass `u8` to variadic function, cast to `c_uint` [E0617]
//~^ ERROR can't pass `u8` to variadic function
//~| HELP cast the value to `c_uint`
printf
(::
std
::
ptr
::
null
(),
0u16
);
//~^ ERROR can't pass `u16` to variadic function, cast to `c_uint` [E0617]
//~^ ERROR can't pass `u16` to variadic function
//~| HELP cast the value to `c_uint`
printf
(::
std
::
ptr
::
null
(),
printf
);
//~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function, cast to `unsafe extern "C" fn(*const i8, ...)` [E0617]
//~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function
//~| HELP cast the value to `unsafe extern "C" fn(*const i8, ...)`
}
}
src/test/compile-fail/issue-32201.rs
浏览文件 @
6da912e2
...
...
@@ -17,6 +17,7 @@ fn bar(_: *const u8) {}
fn
main
()
{
unsafe
{
foo
(
0
,
bar
);
//~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)`
//~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function
//~| HELP cast the value to `fn(*const u8)`
}
}
src/test/ui/variadic-ffi-3.rs
浏览文件 @
6da912e2
...
...
@@ -31,11 +31,11 @@ fn main() {
//~| expected type `extern "C" fn(isize, u8, ...)`
//~| found type `extern "C" fn(isize, u8) {bar}`
foo
(
1
,
2
,
3f32
);
//~ ERROR can't pass `f32` to variadic function
, cast to `c_double`
foo
(
1
,
2
,
true
);
//~ ERROR can't pass `bool` to variadic function
, cast to `c_int`
foo
(
1
,
2
,
1i8
);
//~ ERROR can't pass `i8` to variadic function
, cast to `c_int`
foo
(
1
,
2
,
1u8
);
//~ ERROR can't pass `u8` to variadic function
, cast to `c_uint`
foo
(
1
,
2
,
1i16
);
//~ ERROR can't pass `i16` to variadic function
, cast to `c_int`
foo
(
1
,
2
,
1u16
);
//~ ERROR can't pass `u16` to variadic function
, cast to `c_uint`
foo
(
1
,
2
,
3f32
);
//~ ERROR can't pass `f32` to variadic function
foo
(
1
,
2
,
true
);
//~ ERROR can't pass `bool` to variadic function
foo
(
1
,
2
,
1i8
);
//~ ERROR can't pass `i8` to variadic function
foo
(
1
,
2
,
1u8
);
//~ ERROR can't pass `u8` to variadic function
foo
(
1
,
2
,
1i16
);
//~ ERROR can't pass `i16` to variadic function
foo
(
1
,
2
,
1u16
);
//~ ERROR can't pass `u16` to variadic function
}
}
src/test/ui/variadic-ffi-3.stderr
浏览文件 @
6da912e2
...
...
@@ -34,41 +34,41 @@ error[E0308]: mismatched types
= note: expected type `extern "C" fn(isize, u8, ...)`
found type `extern "C" fn(isize, u8) {bar}`
error[E0617]: can't pass `f32` to variadic function
, cast to `c_double`
error[E0617]: can't pass `f32` to variadic function
--> $DIR/variadic-ffi-3.rs:34:19
|
34 | foo(1, 2, 3f32); //~ ERROR can't pass `f32` to variadic function
, cast to `c_double`
| ^^^^
34 | foo(1, 2, 3f32); //~ ERROR can't pass `f32` to variadic function
| ^^^^
help: cast the value to `c_double`: `3f32 as c_double`
error[E0617]: can't pass `bool` to variadic function
, cast to `c_int`
error[E0617]: can't pass `bool` to variadic function
--> $DIR/variadic-ffi-3.rs:35:19
|
35 | foo(1, 2, true); //~ ERROR can't pass `bool` to variadic function
, cast to `c_int`
| ^^^^
35 | foo(1, 2, true); //~ ERROR can't pass `bool` to variadic function
| ^^^^
help: cast the value to `c_int`: `true as c_int`
error[E0617]: can't pass `i8` to variadic function
, cast to `c_int`
error[E0617]: can't pass `i8` to variadic function
--> $DIR/variadic-ffi-3.rs:36:19
|
36 | foo(1, 2, 1i8); //~ ERROR can't pass `i8` to variadic function
, cast to `c_int`
| ^^^
36 | foo(1, 2, 1i8); //~ ERROR can't pass `i8` to variadic function
| ^^^
help: cast the value to `c_int`: `1i8 as c_int`
error[E0617]: can't pass `u8` to variadic function
, cast to `c_uint`
error[E0617]: can't pass `u8` to variadic function
--> $DIR/variadic-ffi-3.rs:37:19
|
37 | foo(1, 2, 1u8); //~ ERROR can't pass `u8` to variadic function
, cast to `c_uint`
| ^^^
37 | foo(1, 2, 1u8); //~ ERROR can't pass `u8` to variadic function
| ^^^
help: cast the value to `c_uint`: `1u8 as c_uint`
error[E0617]: can't pass `i16` to variadic function
, cast to `c_int`
error[E0617]: can't pass `i16` to variadic function
--> $DIR/variadic-ffi-3.rs:38:19
|
38 | foo(1, 2, 1i16); //~ ERROR can't pass `i16` to variadic function
, cast to `c_int`
| ^^^^
38 | foo(1, 2, 1i16); //~ ERROR can't pass `i16` to variadic function
| ^^^^
help: cast the value to `c_int`: `1i16 as c_int`
error[E0617]: can't pass `u16` to variadic function
, cast to `c_uint`
error[E0617]: can't pass `u16` to variadic function
--> $DIR/variadic-ffi-3.rs:39:19
|
39 | foo(1, 2, 1u16); //~ ERROR can't pass `u16` to variadic function
, cast to `c_uint`
| ^^^^
39 | foo(1, 2, 1u16); //~ ERROR can't pass `u16` to variadic function
| ^^^^
help: cast the value to `c_uint`: `1u16 as c_uint`
error: aborting due to 10 previous errors
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录